public void TestStereoSGBMCorrespondence() { Image<Gray, Byte> left = EmguAssert.LoadImage<Gray, byte>("aloeL.jpg"); Image<Gray, Byte> right = EmguAssert.LoadImage<Gray, byte>("aloeR.jpg"); Size size = left.Size; Image<Gray, Int16> disparity = new Image<Gray, Int16>(size); StereoSGBM bm = new StereoSGBM(10, 64, 0, 0, 0, 0, 0, 0, 0, 0, StereoSGBM.Mode.SGBM); Stopwatch watch = Stopwatch.StartNew(); bm.Compute(left, right, disparity); watch.Stop(); EmguAssert.WriteLine(String.Format("Time used: {0} milliseconds", watch.ElapsedMilliseconds)); Matrix<double> q = new Matrix<double>(4, 4); q.SetIdentity(); Image<Gray, Int16> disparityScaled = disparity * (-16); MCvPoint3D32f[] points = PointCollection.ReprojectImageTo3D(disparityScaled.Mat, q); float min = (float) 1.0e10, max = 0; foreach (MCvPoint3D32f p in points) { if (p.Z < min) min = p.Z; else if (p.Z > max) max = p.Z; } EmguAssert.WriteLine(String.Format("Min : {0}\r\nMax : {1}", min, max)); }
private void GetDisparityMap() { minDisparity = TBminDisparity.Value; //Minimum possible disparity value. Normally, it is zero but sometimes rectification algorithms can shift images, so this parameter needs to be adjusted accordingly. //Default is zero, should be set to a negative value, if negative disparities are possible (depends on the angle between the cameras views and the distance of the measured object to the cameras). numDisparities = TBnumDisparities.Value; //Maximum disparity minus minimum disparity. The value is always greater than zero. In the current implementation, this parameter must be divisible by 16. SADWindowSize = TBSADWindowSize.Value; //(= blockSize) Matched block size. It must be an odd number >=1 . Normally, it should be somewhere in the 3..11 range. Use 0 for default. P1 = TBp1.Value; //The first parameter controlling the disparity smoothness. It is the penalty on the disparity change by plus or minus 1 between neighbor pixels. //Reasonably good value is 8*number_of_image_channels*SADWindowSize*SADWindowSize. Use 0 for default P2 = TBp2.Value; //The second parameter controlling the disparity smoothness. It is the penalty on the disparity change by more than 1 between neighbor pixels. //The algorithm requires p2 > p1. Reasonably good value is 32*number_of_image_channels*SADWindowSize*SADWindowSize. Use 0 for default disp12MaxDiff = TBdisp12MaxDiff.Value; //Maximum allowed difference (in integer pixel units) in the left-right disparity check. Set it to a non-positive value to disable the check. preFilterCap = TBpreFilterCap.Value; //Truncation value for the prefiltered image pixels. The algorithm first computes x-derivative at each pixel and clips its value by [-preFilterCap, preFilterCap] interval. //The result values are passed to the Birchfield-Tomasi pixel cost function. uniquenessRatio = TBuniquenessRatio.Value; //Margin in percentage by which the best (minimum) computed cost function value should “win” the second best value to consider the found match correct. //Normally, a value within the 5-15 range is good enough. speckleWindowSize = TBspeckleWindowSize.Value; //Maximum size of smooth disparity regions to consider their noise speckles and invalidate. Set it to 0 to disable speckle filtering. Otherwise, set it somewhere in the 50-200 range speckleRange = TBspeckleRange.Value; //Maximum disparity variation within each connected component. If you do speckle filtering, set the parameter to a positive value, //it will be implicitly multiplied by 16. Normally, 1 or 2 is good enough. StereoSGBM.Mode mode = StereoSGBM.Mode.SGBM; //mode (Optional) : Set it to HH to run the full-scale two-pass dynamic programming algorithm. It will consume O(W*H*numDisparities) bytes, //which is large for 640x480 stereo and huge for HD-size pictures. By default, it is set to false. StereoSGBM sgbm = new StereoSGBM(minDisparity, numDisparities, SADWindowSize, P1, P2, disp12MaxDiff, preFilterCap, uniquenessRatio, speckleWindowSize, speckleRange, mode); //Computes disparity map for the specified stereo pair sgbm.Compute(imageLeft, imageRight, disparity); //Since Disparity will be either CV_16S or CV_32F, it needs to be compressed and normalized to CV_8U CvInvoke.Normalize(disparity, disp8, 0, 255, Emgu.CV.CvEnum.NormType.MinMax, Emgu.CV.CvEnum.DepthType.Cv8U); }