}
-void cv::filterSpeckles( InputOutputArray _img, double _newval, int maxSpeckleSize,
- double _maxDiff, InputOutputArray __buf )
+namespace
{
- Mat img = _img.getMat();
- Mat temp, &_buf = __buf.needed() ? __buf.getMatRef() : temp;
- CV_Assert( img.type() == CV_16SC1 );
-
- int newVal = cvRound(_newval);
- int maxDiff = cvRound(_maxDiff);
- int width = img.cols, height = img.rows, npixels = width*height;
- size_t bufSize = npixels*(int)(sizeof(Point2s) + sizeof(int) + sizeof(uchar));
- if( !_buf.isContinuous() || !_buf.data || _buf.cols*_buf.rows*_buf.elemSize() < bufSize )
- _buf.create(1, (int)bufSize, CV_8U);
-
- uchar* buf = _buf.data;
- int i, j, dstep = (int)(img.step/sizeof(short));
- int* labels = (int*)buf;
- buf += npixels*sizeof(labels[0]);
- Point2s* wbuf = (Point2s*)buf;
- buf += npixels*sizeof(wbuf[0]);
- uchar* rtype = (uchar*)buf;
- int curlabel = 0;
-
- // clear out label assignments
- memset(labels, 0, npixels*sizeof(labels[0]));
-
- for( i = 0; i < height; i++ )
+ template <typename T>
+ void filterSpecklesImpl(cv::Mat& img, int newVal, int maxSpeckleSize, int maxDiff, cv::Mat& _buf)
{
- short* ds = img.ptr<short>(i);
- int* ls = labels + width*i;
-
- for( j = 0; j < width; j++ )
+ using namespace cv;
+
+ int width = img.cols, height = img.rows, npixels = width*height;
+ size_t bufSize = npixels*(int)(sizeof(Point2s) + sizeof(int) + sizeof(uchar));
+ if( !_buf.isContinuous() || !_buf.data || _buf.cols*_buf.rows*_buf.elemSize() < bufSize )
+ _buf.create(1, (int)bufSize, CV_8U);
+
+ uchar* buf = _buf.data;
+ int i, j, dstep = (int)(img.step/sizeof(T));
+ int* labels = (int*)buf;
+ buf += npixels*sizeof(labels[0]);
+ Point2s* wbuf = (Point2s*)buf;
+ buf += npixels*sizeof(wbuf[0]);
+ uchar* rtype = (uchar*)buf;
+ int curlabel = 0;
+
+ // clear out label assignments
+ memset(labels, 0, npixels*sizeof(labels[0]));
+
+ for( i = 0; i < height; i++ )
{
- if( ds[j] != newVal ) // not a bad disparity
+ T* ds = img.ptr<T>(i);
+ int* ls = labels + width*i;
+
+ for( j = 0; j < width; j++ )
{
- if( ls[j] ) // has a label, check for bad label
- {
- if( rtype[ls[j]] ) // small region, zero out disparity
- ds[j] = (short)newVal;
- }
- // no label, assign and propagate
- else
+ if( ds[j] != newVal ) // not a bad disparity
{
- Point2s* ws = wbuf; // initialize wavefront
- Point2s p((short)j, (short)i); // current pixel
- curlabel++; // next label
- int count = 0; // current region size
- ls[j] = curlabel;
-
- // wavefront propagation
- while( ws >= wbuf ) // wavefront not empty
+ if( ls[j] ) // has a label, check for bad label
{
- count++;
- // put neighbors onto wavefront
- short* dpp = &img.at<short>(p.y, p.x);
- short dp = *dpp;
- int* lpp = labels + width*p.y + p.x;
-
- if( p.x < width-1 && !lpp[+1] && dpp[+1] != newVal && std::abs(dp - dpp[+1]) <= maxDiff )
+ if( rtype[ls[j]] ) // small region, zero out disparity
+ ds[j] = (T)newVal;
+ }
+ // no label, assign and propagate
+ else
+ {
+ Point2s* ws = wbuf; // initialize wavefront
+ Point2s p((short)j, (short)i); // current pixel
+ curlabel++; // next label
+ int count = 0; // current region size
+ ls[j] = curlabel;
+
+ // wavefront propagation
+ while( ws >= wbuf ) // wavefront not empty
{
- lpp[+1] = curlabel;
- *ws++ = Point2s(p.x+1, p.y);
- }
+ count++;
+ // put neighbors onto wavefront
+ T* dpp = &img.at<T>(p.y, p.x);
+ T dp = *dpp;
+ int* lpp = labels + width*p.y + p.x;
- if( p.x > 0 && !lpp[-1] && dpp[-1] != newVal && std::abs(dp - dpp[-1]) <= maxDiff )
- {
- lpp[-1] = curlabel;
- *ws++ = Point2s(p.x-1, p.y);
- }
+ if( p.x < width-1 && !lpp[+1] && dpp[+1] != newVal && std::abs(dp - dpp[+1]) <= maxDiff )
+ {
+ lpp[+1] = curlabel;
+ *ws++ = Point2s(p.x+1, p.y);
+ }
- if( p.y < height-1 && !lpp[+width] && dpp[+dstep] != newVal && std::abs(dp - dpp[+dstep]) <= maxDiff )
- {
- lpp[+width] = curlabel;
- *ws++ = Point2s(p.x, p.y+1);
+ if( p.x > 0 && !lpp[-1] && dpp[-1] != newVal && std::abs(dp - dpp[-1]) <= maxDiff )
+ {
+ lpp[-1] = curlabel;
+ *ws++ = Point2s(p.x-1, p.y);
+ }
+
+ if( p.y < height-1 && !lpp[+width] && dpp[+dstep] != newVal && std::abs(dp - dpp[+dstep]) <= maxDiff )
+ {
+ lpp[+width] = curlabel;
+ *ws++ = Point2s(p.x, p.y+1);
+ }
+
+ if( p.y > 0 && !lpp[-width] && dpp[-dstep] != newVal && std::abs(dp - dpp[-dstep]) <= maxDiff )
+ {
+ lpp[-width] = curlabel;
+ *ws++ = Point2s(p.x, p.y-1);
+ }
+
+ // pop most recent and propagate
+ // NB: could try least recent, maybe better convergence
+ p = *--ws;
}
- if( p.y > 0 && !lpp[-width] && dpp[-dstep] != newVal && std::abs(dp - dpp[-dstep]) <= maxDiff )
+ // assign label type
+ if( count <= maxSpeckleSize ) // speckle region
{
- lpp[-width] = curlabel;
- *ws++ = Point2s(p.x, p.y-1);
+ rtype[ls[j]] = 1; // small region label
+ ds[j] = (T)newVal;
}
-
- // pop most recent and propagate
- // NB: could try least recent, maybe better convergence
- p = *--ws;
- }
-
- // assign label type
- if( count <= maxSpeckleSize ) // speckle region
- {
- rtype[ls[j]] = 1; // small region label
- ds[j] = (short)newVal;
+ else
+ rtype[ls[j]] = 0; // large region label
}
- else
- rtype[ls[j]] = 0; // large region label
}
}
}
}
}
+void cv::filterSpeckles( InputOutputArray _img, double _newval, int maxSpeckleSize,
+ double _maxDiff, InputOutputArray __buf )
+{
+ Mat img = _img.getMat();
+ Mat temp, &_buf = __buf.needed() ? __buf.getMatRef() : temp;
+ CV_Assert( img.type() == CV_8UC1 || img.type() == CV_16SC1 );
+
+ int newVal = cvRound(_newval);
+ int maxDiff = cvRound(_maxDiff);
+
+ if (img.type() == CV_8UC1)
+ filterSpecklesImpl<uchar>(img, newVal, maxSpeckleSize, maxDiff, _buf);
+ else
+ filterSpecklesImpl<short>(img, newVal, maxSpeckleSize, maxDiff, _buf);
+}
+
void cv::validateDisparity( InputOutputArray _disp, InputArray _cost, int minDisparity,
int numberOfDisparities, int disp12MaxDiff )
{