OpenCV 在BM匹配方法中提供了一个非常有用的函数:filterSpeckles(),用于从视差图中直接去除一些小的(甚至粘连在一起的)斑块。但也许这个函数在设计之初只是为了在BM算法中使用,所以遗憾的是这个函数的接口在设计上只能接收CV_8UC和CV_16SC两种数据类型的视差图像,这一点在OpenCV的手册中已经明确了。
而在很多基于立体视觉原理的高精度测量中,我们所使用的视差图都是CV_32F类型的数据,倘若每次为了滤除斑块而重新做遍历一次图像转换数据,多少有点让人觉得多此一举却又无能为力。
所以笔者找到这个接口方法的内部实现,欣喜的发现在底层实现中其实并未限制数据的类型,因此,兴致来了,就把底层的代码搬了出来,重新自己定义了一个接口,使这个方法可以适用于更多数据类型的视差图,因此为实现代码,仅供参考。
typedef cv::Point_<short> Point2s;
template <typename T>
void FilterSpeckles(Mat& img, int maxSpeckleSize, float maxDiff)
{
using namespace cv;
int newVal = img.cols;
cv::Mat _buf;
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