OpenCV3.4两种立体匹配算法效果对比

转自https://www.cnblogs.com/riddick/p/8318997.html

OpenCV3.4两种立体匹配算法效果对比

 以OpenCV自带的Aloe图像对为例:

   

1.BM算法(Block Matching)

参数设置如下:

复制代码
    int numberOfDisparities = ((imgSize.width / 8) + 15) & -16;
    cv::Ptr<cv::StereoBM> bm = cv::StereoBM::create(16, 9);
    cv::Rect roi1, roi2;
    bm->setROI1(roi1);
    bm->setROI2(roi2);
    bm->setPreFilterCap(31);
    bm->setBlockSize(9);
    bm->setMinDisparity(0);
    bm->setNumDisparities(numberOfDisparities);
    bm->setTextureThreshold(10);
    bm->setUniquenessRatio(15);
    bm->setSpeckleWindowSize(100);
    bm->setSpeckleRange(32);
    bm->setDisp12MaxDiff(1);
    bm->compute(imgL, imgR, disp);
复制代码

效果如下:

BM算法得到的视差图(左),空洞填充后得到的视差图(右)

  

2.SGBM(Semi-Global Block matching)算法:

参数设置如下:

复制代码
enum { STEREO_BM = 0, STEREO_SGBM = 1, STEREO_HH = 2, STEREO_VAR = 3, STEREO_3WAY = 4 };
    int numberOfDisparities = ((imgSize.width / 8) + 15) & -16;
    cv::Ptr<cv::StereoSGBM> sgbm = cv::StereoSGBM::create(0, 16, 3);
    sgbm->setPreFilterCap(63);
    int SADWindowSize = 9;
    int sgbmWinSize = SADWindowSize > 0 ? SADWindowSize : 3;
    sgbm->setBlockSize(sgbmWinSize);
    int cn = imgL.channels();
    sgbm->setP1(8 * cn*sgbmWinSize*sgbmWinSize);
    sgbm->setP2(32 * cn*sgbmWinSize*sgbmWinSize);
    sgbm->setMinDisparity(0);
    sgbm->setNumDisparities(numberOfDisparities);
    sgbm->setUniquenessRatio(10);
    sgbm->setSpeckleWindowSize(100);
    sgbm->setSpeckleRange(32);
    sgbm->setDisp12MaxDiff(1);
</span><span style="color: #0000ff">int</span> alg =<span style="color: #000000"> STEREO_SGBM;
</span><span style="color: #0000ff">if</span> (alg ==<span style="color: #000000"> STEREO_HH)
    sgbm</span>-&gt;<span style="color: #000000">setMode(cv::StereoSGBM::MODE_HH);
</span><span style="color: #0000ff">else</span> <span style="color: #0000ff">if</span> (alg ==<span style="color: #000000"> STEREO_SGBM)
    sgbm</span>-&gt;<span style="color: #000000">setMode(cv::StereoSGBM::MODE_SGBM);
</span><span style="color: #0000ff">else</span> <span style="color: #0000ff">if</span> (alg ==<span style="color: #000000"> STEREO_3WAY)
    sgbm</span>-&gt;<span style="color: #000000">setMode(cv::StereoSGBM::MODE_SGBM_3WAY);
sgbm</span>-&gt;compute(imgL, imgR, disp);</pre>
复制代码

 效果如图:

SGBM算法得到的视差图(左),空洞填充后得到的视差图(右)

   

可见SGBM算法得到的视差图相比于BM算法来说,减少了很多不准确的匹配点,尤其是在深度不连续区域,速度上SGBM要慢于BM算法。OpenCV3.0以后没有实现GC算法,可能是出于速度考虑,以后找时间补上对比图,以及各个算法的详细原理分析。

后面我填充空洞的效果不是很好,如果有更好的方法,望不吝赐教。

 


preFilterCap()匹配图像预处理

  •  两种立体匹配算法都要先对输入图像做预处理,OpenCV源码中中调用函数 static void prefilterXSobel(const cv::Mat& src, cv::Mat& dst, int preFilterCap),参数设置中preFilterCap在此函数中用到。函数步骤如下,作用主要有两点:对于无纹理区域,能够排除噪声干扰;对于边界区域,能够提高边界的区分性,利于后续的匹配代价计算:
  1. 先利用水平Sobel算子求输入图像x方向的微分值Value;
  2. 如果Value<-preFilterCap, 则Value=0;
    如果Value>preFilterCap,则Value=2*preFilterCap;
    如果Value>=-preFilterCap &&Value<=preFilterCap,则Value=Value+preFilterCap;
  3. 输出处理后的图像作为下一步计算匹配代价的输入图像。
static void prefilterXSobel(const cv::Mat& src, cv::Mat& dst, int ftzero)
{
    int x, y;
    const int OFS = 256 * 4, TABSZ = OFS * 2 + 256;
    uchar tab[TABSZ];
    cv::Size size = src.size();
</span><span style="color: #0000ff">for</span> (x = <span style="color: #800080">0</span>; x &lt; TABSZ; x++<span style="color: #000000">)
    tab[x] </span>= (uchar)(x - OFS &lt; -ftzero ? <span style="color: #800080">0</span> : x - OFS &gt; ftzero ? ftzero * <span style="color: #800080">2</span> : x - OFS +<span style="color: #000000"> ftzero);
uchar val0 </span>= tab[<span style="color: #800080">0</span> +<span style="color: #000000"> OFS];

</span><span style="color: #0000ff">for</span> (y = <span style="color: #800080">0</span>; y &lt; size.height - <span style="color: #800080">1</span>; y += <span style="color: #800080">2</span><span style="color: #000000">)
{
    </span><span style="color: #0000ff">const</span> uchar* srow1 = src.ptr&lt;uchar&gt;<span style="color: #000000">(y);
    </span><span style="color: #0000ff">const</span> uchar* srow0 = y &gt; <span style="color: #800080">0</span> ? srow1 - src.step : size.height &gt; <span style="color: #800080">1</span> ? srow1 +<span style="color: #000000"> src.step : srow1;
    </span><span style="color: #0000ff">const</span> uchar* srow2 = y &lt; size.height - <span style="color: #800080">1</span> ? srow1 + src.step : size.height &gt; <span style="color: #800080">1</span> ? srow1 -<span style="color: #000000"> src.step : srow1;
    </span><span style="color: #0000ff">const</span> uchar* srow3 = y &lt; size.height - <span style="color: #800080">2</span> ? srow1 + src.step * <span style="color: #800080">2</span><span style="color: #000000"> : srow1;
    uchar</span>* dptr0 = dst.ptr&lt;uchar&gt;<span style="color: #000000">(y);
    uchar</span>* dptr1 = dptr0 +<span style="color: #000000"> dst.step;

    dptr0[</span><span style="color: #800080">0</span>] = dptr0[size.width - <span style="color: #800080">1</span>] = dptr1[<span style="color: #800080">0</span>] = dptr1[size.width - <span style="color: #800080">1</span>] =<span style="color: #000000"> val0;
    x </span>= <span style="color: #800080">1</span><span style="color: #000000">;
    </span><span style="color: #0000ff">for</span> (; x &lt; size.width - <span style="color: #800080">1</span>; x++<span style="color: #000000">)
    {
        </span><span style="color: #0000ff">int</span> d0 = srow0[x + <span style="color: #800080">1</span>] - srow0[x - <span style="color: #800080">1</span>], d1 = srow1[x + <span style="color: #800080">1</span>] - srow1[x - <span style="color: #800080">1</span><span style="color: #000000">],
            d2 </span>= srow2[x + <span style="color: #800080">1</span>] - srow2[x - <span style="color: #800080">1</span>], d3 = srow3[x + <span style="color: #800080">1</span>] - srow3[x - <span style="color: #800080">1</span><span style="color: #000000">];
        </span><span style="color: #0000ff">int</span> v0 = tab[d0 + d1 * <span style="color: #800080">2</span> + d2 +<span style="color: #000000"> OFS];
        </span><span style="color: #0000ff">int</span> v1 = tab[d1 + d2 * <span style="color: #800080">2</span> + d3 +<span style="color: #000000"> OFS];
        dptr0[x] </span>=<span style="color: #000000"> (uchar)v0;
        dptr1[x] </span>=<span style="color: #000000"> (uchar)v1;
    }
}

</span><span style="color: #0000ff">for</span> (; y &lt; size.height; y++<span style="color: #000000">)
{
    uchar</span>* dptr = dst.ptr&lt;uchar&gt;<span style="color: #000000">(y);
    x </span>= <span style="color: #800080">0</span><span style="color: #000000">;
    </span><span style="color: #0000ff">for</span> (; x &lt; size.width; x++<span style="color: #000000">)
        dptr[x] </span>=<span style="color: #000000"> val0;
}

}

View Code

自己实现的函数如下:

void mySobelX(cv::Mat srcImg, cv::Mat dstImg, int preFilterCap)
{
    assert(srcImg.channels() == 1);
    int radius = 1;
    int width = srcImg.cols;
    int height = srcImg.rows;
    uchar *pSrcData = srcImg.data;
    uchar *pDstData = dstImg.data;
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            int idx = i*width + j;
            if (i >= radius && i < height - radius && j >= radius && j < width - radius)
            {
                int diff0 = pSrcData[(i - 1)*width + j + 1] - pSrcData[(i - 1)*width + j - 1];
                int diff1 = pSrcData[i*width + j + 1] - pSrcData[i*width + j - 1];
                int diff2 = pSrcData[(i + 1)*width + j + 1] - pSrcData[(i + 1)*width + j - 1];
            </span><span style="color: #0000ff">int</span> value = diff0 + <span style="color: #800080">2</span> * diff1 +<span style="color: #000000"> diff2;
            </span><span style="color: #0000ff">if</span> (value &lt; -<span style="color: #000000">preFilterCap)
            {
                pDstData[idx] </span>= <span style="color: #800080">0</span><span style="color: #000000">;
            }
            </span><span style="color: #0000ff">else</span> <span style="color: #0000ff">if</span> (value &gt;= -preFilterCap &amp;&amp; value &lt;=<span style="color: #000000"> preFilterCap)
            {
                pDstData[idx] </span>= uchar(value +<span style="color: #000000"> preFilterCap);
            }
            </span><span style="color: #0000ff">else</span><span style="color: #000000">
            {
                pDstData[idx] </span>= uchar(<span style="color: #800080">2</span> *<span style="color: #000000"> preFilterCap);
            }

        }
        </span><span style="color: #0000ff">else</span><span style="color: #000000">
        {
            pDstData[idx] </span>= <span style="color: #800080">0</span><span style="color: #000000">;
        }
    }
}

}

View Code

 函数输入,输出结果如图:

    

 


 filterSpeckles()视差图后处理

  •  两种立体匹配算法在算出初始视差图后会进行视差图后处理,包括中值滤波,连通域检测等。其中中值滤波能够有效去除视差图中孤立的噪点,而连通域检测能够检测出视差图中因噪声引起小团块(blob)。在BM和SGBM中都有speckleWindowSize和speckleRange这两个参数,speckleWindowSize是指设置检测出的连通域中像素点个数,也就是连通域的大小。speckleRange是指设置判断两个点是否属于同一个连通域的阈值条件。大概流程如下:
  1. 判断当前像素点四邻域的邻域点与当前像素点的差值diff,如果diff<speckRange,则表示该邻域点与当前像素点是一个连通域,设置一个标记。然后再以该邻域点为中心判断其四邻域点,步骤同上。直至某一像素点四邻域的点均不满足条件,则停止。
  2. 步骤1完成后,判断被标记的像素点个数count,如果像素点个数count<=speckleWindowSize,则说明该连通域是一个小团块(blob),则将当前像素点值设置为newValue(表示错误的视差值,newValue一般设置为负数或者0值)。否则,表示该连通域是个大团块,不做处理。同时建立标记值与是否为小团块的关系表rtype[label],rtype[label]为0,表示label值对应的像素点属于小团块,为1则不属于小团块。
  3. 处理下一个像素点时,先判断其是否已经被标记:
    如果已经被标记,则根据关系表rtype[label]判断是否为小团块(blob),如果是,则直接将该像素值设置为newValue;如果不是,则不做处理。继续处理下一个像素。
    如果没有被标记,则按照步骤1处理。
  4. 所有像素点处理后,满足条件的区域会被设置为newValue值,后续可以用空洞填充等方法重新估计其视差值。

OpenCV中有对应的API函数,void filterSpeckles(InputOutputArray img, double newVal, int maxSpeckleSize, double maxDiff, InputOutputArray buf=noArray() ) 

函数源码如下,使用时根据视差图或者深度图数据类型设置模板中的数据类型:

typedef cv::Point_<short> Point2s;
template <typename T> void filterSpecklesImpl(cv::Mat& img, int newVal, int maxSpeckleSize, int maxDiff, cv::Mat& _buf)
{
    using namespace cv;
</span><span style="color: #0000ff">int</span> width = img.cols, height = img.rows, npixels = width*<span style="color: #000000">height;
size_t bufSize </span>= npixels*(<span style="color: #0000ff">int</span>)(<span style="color: #0000ff">sizeof</span>(Point2s) + <span style="color: #0000ff">sizeof</span>(<span style="color: #0000ff">int</span>) + <span style="color: #0000ff">sizeof</span><span style="color: #000000">(uchar));
</span><span style="color: #0000ff">if</span> (!_buf.isContinuous() || _buf.empty() || _buf.cols*_buf.rows*_buf.elemSize() &lt;<span style="color: #000000"> bufSize)
    _buf.create(</span><span style="color: #800080">1</span>, (<span style="color: #0000ff">int</span><span style="color: #000000">)bufSize, CV_8U);

uchar</span>* buf =<span style="color: #000000"> _buf.ptr();
</span><span style="color: #0000ff">int</span> i, j, dstep = (<span style="color: #0000ff">int</span>)(img.step / <span style="color: #0000ff">sizeof</span><span style="color: #000000">(T));
</span><span style="color: #0000ff">int</span>* labels = (<span style="color: #0000ff">int</span>*<span style="color: #000000">)buf;
buf </span>+= npixels * <span style="color: #0000ff">sizeof</span>(labels[<span style="color: #800080">0</span><span style="color: #000000">]);
Point2s</span>* wbuf = (Point2s*<span style="color: #000000">)buf;
buf </span>+= npixels * <span style="color: #0000ff">sizeof</span>(wbuf[<span style="color: #800080">0</span><span style="color: #000000">]);
uchar</span>* rtype = (uchar*<span style="color: #000000">)buf;
</span><span style="color: #0000ff">int</span> curlabel = <span style="color: #800080">0</span><span style="color: #000000">;

</span><span style="color: #008000">//</span><span style="color: #008000"> clear out label assignments</span>
memset(labels, <span style="color: #800080">0</span>, npixels * <span style="color: #0000ff">sizeof</span>(labels[<span style="color: #800080">0</span><span style="color: #000000">]));

</span><span style="color: #0000ff">for</span> (i = <span style="color: #800080">0</span>; i &lt; height; i++<span style="color: #000000">)
{
    T</span>* ds = img.ptr&lt;T&gt;<span style="color: #000000">(i);
    </span><span style="color: #0000ff">int</span>* ls = labels + width*<span style="color: #000000">i;

    </span><span style="color: #0000ff">for</span> (j = <span style="color: #800080">0</span>; j &lt; width; j++<span style="color: #000000">)
    {
        </span><span style="color: #0000ff">if</span> (ds[j] != newVal)   <span style="color: #008000">//</span><span style="color: #008000"> not a bad disparity</span>

{
if (ls[j]) // has a label, check for bad label
{
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;

                </span><span style="color: #008000">//</span><span style="color: #008000"> wavefront propagation</span>
                <span style="color: #0000ff">while</span> (ws &gt;= wbuf) <span style="color: #008000">//</span><span style="color: #008000"> wavefront not empty</span>

{
count++;
// put neighbors onto wavefront
T* dpp = &img.at<T>(p.y, p.x); //current pixel value
T dp = dpp;
int
lpp = labels + width*p.y + p.x; //current label value

                    </span><span style="color: #008000">//</span><span style="color: #008000">bot</span>
                    <span style="color: #0000ff">if</span> (p.y &lt; height - <span style="color: #800080">1</span> &amp;&amp; !lpp[+width] &amp;&amp; dpp[+dstep] != newVal &amp;&amp; std::abs(dp - dpp[+dstep]) &lt;=<span style="color: #000000"> maxDiff)
                    {
                        lpp[</span>+width] =<span style="color: #000000"> curlabel;
                        </span>*ws++ = Point2s(p.x, p.y + <span style="color: #800080">1</span><span style="color: #000000">);
                    }
                    </span><span style="color: #008000">//</span><span style="color: #008000">top</span>
                    <span style="color: #0000ff">if</span> (p.y &gt; <span style="color: #800080">0</span> &amp;&amp; !lpp[-width] &amp;&amp; dpp[-dstep] != newVal &amp;&amp; std::abs(dp - dpp[-dstep]) &lt;=<span style="color: #000000"> maxDiff)
                    {
                        lpp[</span>-width] =<span style="color: #000000"> curlabel;
                        </span>*ws++ = Point2s(p.x, p.y - <span style="color: #800080">1</span><span style="color: #000000">);
                    }
                    </span><span style="color: #008000">//</span><span style="color: #008000">right</span>
                    <span style="color: #0000ff">if</span> (p.x &lt; width - <span style="color: #800080">1</span> &amp;&amp; !lpp[+<span style="color: #800080">1</span>] &amp;&amp; dpp[+<span style="color: #800080">1</span>] != newVal &amp;&amp; std::abs(dp - dpp[+<span style="color: #800080">1</span>]) &lt;=<span style="color: #000000"> maxDiff)
                    {
                        lpp[</span>+<span style="color: #800080">1</span>] =<span style="color: #000000"> curlabel;
                        </span>*ws++ = Point2s(p.x + <span style="color: #800080">1</span><span style="color: #000000">, p.y);
                    }
                    </span><span style="color: #008000">//</span><span style="color: #008000">left</span>
                    <span style="color: #0000ff">if</span> (p.x &gt; <span style="color: #800080">0</span> &amp;&amp; !lpp[-<span style="color: #800080">1</span>] &amp;&amp; dpp[-<span style="color: #800080">1</span>] != newVal &amp;&amp; std::abs(dp - dpp[-<span style="color: #800080">1</span>]) &lt;=<span style="color: #000000"> maxDiff)
                    {
                        lpp[</span>-<span style="color: #800080">1</span>] =<span style="color: #000000"> curlabel;
                        </span>*ws++ = Point2s(p.x - <span style="color: #800080">1</span><span style="color: #000000">, p.y);
                    }
                    

                    </span><span style="color: #008000">//</span><span style="color: #008000"> pop most recent and propagate
                    </span><span style="color: #008000">//</span><span style="color: #008000"> NB: could try least recent, maybe better convergence</span>
                    p = *--<span style="color: #000000">ws;
                }

                </span><span style="color: #008000">//</span><span style="color: #008000"> assign label type</span>
                <span style="color: #0000ff">if</span> (count &lt;= maxSpeckleSize)   <span style="color: #008000">//</span><span style="color: #008000"> speckle region</span>

{
rtype[ls[j]] = 1; // small region label
ds[j] = (T)newVal;
}
else
rtype[ls[j]] = 0; // large region label
}
}
}
}
}

View Code

 或者下面博主自己整理一遍的代码:

typedef cv::Point_<short> Point2s;
template <typename T> void myFilterSpeckles(cv::Mat &img, int newVal, int maxSpeckleSize, int maxDiff)
{
    int width = img.cols;
    int height = img.rows;
    int imgSize = width*height;
    int *pLabelBuf = (int*)malloc(sizeof(int)*imgSize);//标记值buffer
    Point2s *pPointBuf = (Point2s*)malloc(sizeof(short)*imgSize);//点坐标buffer
    uchar *pTypeBuf = (uchar*)malloc(sizeof(uchar)*imgSize);//blob判断标记buffer
    //初始化Labelbuffer
    int currentLabel = 0;
    memset(pLabelBuf, 0, sizeof(int)*imgSize);
</span><span style="color: #0000ff">for</span> (<span style="color: #0000ff">int</span> i = <span style="color: #800080">0</span>; i &lt; height; i++<span style="color: #000000">)
{
    T </span>*pData = img.ptr&lt;T&gt;<span style="color: #000000">(i);
    </span><span style="color: #0000ff">int</span> *pLabel = pLabelBuf + width*<span style="color: #000000">i;
    </span><span style="color: #0000ff">for</span> (<span style="color: #0000ff">int</span> j = <span style="color: #800080">0</span>; j &lt; width; j++<span style="color: #000000">)
    {
        </span><span style="color: #0000ff">if</span> (pData[j] !=<span style="color: #000000"> newVal)
        {
            </span><span style="color: #0000ff">if</span><span style="color: #000000"> (pLabel[j])
            {
                </span><span style="color: #0000ff">if</span><span style="color: #000000"> (pTypeBuf[pLabel[j]])
                {
                    pData[j] </span>=<span style="color: #000000"> (T)newVal;
                }
            }
            </span><span style="color: #0000ff">else</span><span style="color: #000000">
            {
                Point2s </span>*pWave =<span style="color: #000000"> pPointBuf;
                Point2s curPoint((T)j, (T)i);
                currentLabel</span>++<span style="color: #000000">;
                </span><span style="color: #0000ff">int</span> count = <span style="color: #800080">0</span><span style="color: #000000">;
                pLabel[j] </span>=<span style="color: #000000"> currentLabel;
                </span><span style="color: #0000ff">while</span> (pWave &gt;=<span style="color: #000000"> pPointBuf)
                {
                    count</span>++<span style="color: #000000">;
                    T </span>*pCurPos = &amp;img.at&lt;T&gt;<span style="color: #000000">(curPoint.y, curPoint.x);
                    T curValue </span>= *<span style="color: #000000">pCurPos;
                    </span><span style="color: #0000ff">int</span> *pCurLabel = pLabelBuf + width*curPoint.y +<span style="color: #000000"> curPoint.x;
                    </span><span style="color: #008000">//</span><span style="color: #008000">bot</span>
                    <span style="color: #0000ff">if</span> (curPoint.y &lt; height - <span style="color: #800080">1</span> &amp;&amp; !pCurLabel[+width] &amp;&amp; pCurPos[+width] != newVal  &amp;&amp; abs(curValue - pCurPos[+width]) &lt;=<span style="color: #000000"> maxDiff)
                    {
                        pCurLabel[</span>+width] =<span style="color: #000000"> currentLabel;
                        </span>*pWave++ = Point2s(curPoint.x, curPoint.y + <span style="color: #800080">1</span><span style="color: #000000">);
                    }
                    </span><span style="color: #008000">//</span><span style="color: #008000">top</span>
                    <span style="color: #0000ff">if</span> (curPoint.y &gt; <span style="color: #800080">0</span> &amp;&amp; !pCurLabel[-width] &amp;&amp; pCurPos[-width] != newVal &amp;&amp; abs(curValue - pCurPos[-width]) &lt;=<span style="color: #000000"> maxDiff)
                    {
                        pCurLabel[</span>-width] =<span style="color: #000000"> currentLabel;
                        </span>*pWave++ = Point2s(curPoint.x, curPoint.y - <span style="color: #800080">1</span><span style="color: #000000">);
                    }
                    </span><span style="color: #008000">//</span><span style="color: #008000">right</span>
                    <span style="color: #0000ff">if</span> (curPoint.x &lt; width-<span style="color: #800080">1</span> &amp;&amp; !pCurLabel[+<span style="color: #800080">1</span>] &amp;&amp; pCurPos[+<span style="color: #800080">1</span>] != newVal  &amp;&amp; abs(curValue - pCurPos[+<span style="color: #800080">1</span>]) &lt;=<span style="color: #000000"> maxDiff)
                    {
                        pCurLabel[</span>+<span style="color: #800080">1</span>] =<span style="color: #000000"> currentLabel;
                        </span>*pWave++ = Point2s(curPoint.x + <span style="color: #800080">1</span><span style="color: #000000">, curPoint.y);
                    }
                    </span><span style="color: #008000">//</span><span style="color: #008000">left</span>
                    <span style="color: #0000ff">if</span> (curPoint.x &gt; <span style="color: #800080">0</span> &amp;&amp; !pCurLabel[-<span style="color: #800080">1</span>] &amp;&amp; pCurPos[-<span style="color: #800080">1</span>] != newVal &amp;&amp; abs(curValue - pCurPos[-<span style="color: #800080">1</span>]) &lt;=<span style="color: #000000"> maxDiff)
                    {
                        pCurLabel[</span>-<span style="color: #800080">1</span>] =<span style="color: #000000"> currentLabel;
                        </span>*pWave++ = Point2s(curPoint.x - <span style="color: #800080">1</span><span style="color: #000000">, curPoint.y);
                    }

                    </span>--<span style="color: #000000">pWave;
                    curPoint </span>= *<span style="color: #000000">pWave;
                }

                </span><span style="color: #0000ff">if</span> (count &lt;=<span style="color: #000000"> maxSpeckleSize)
                {
                    pTypeBuf[pLabel[j]] </span>= <span style="color: #800080">1</span><span style="color: #000000">;
                    pData[j] </span>=<span style="color: #000000"> (T)newVal;
                }
                </span><span style="color: #0000ff">else</span><span style="color: #000000">
                {
                    pTypeBuf[pLabel[j]] </span>= <span style="color: #800080">0</span><span style="color: #000000">;
                }
            }
        }
    }
}

</span><span style="color: #0000ff">free</span><span style="color: #000000">(pLabelBuf);
</span><span style="color: #0000ff">free</span><span style="color: #000000">(pPointBuf);
</span><span style="color: #0000ff">free</span><span style="color: #000000">(pTypeBuf);

}

View Code

 

如下视差图中左上角部分有7个小团块,设置speckleWindowSize和speckleRange分别为50和32,连通域检测后结果为如下图右,小团块能够全部检测出来,方便后续用周围视差填充。当然还有一个缺点就是,图像中其他地方尤其是边界区域也会被检测为小团块,后续填充可能会对边界造成平滑。

    

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值