【问题标题】:OpenCV flood fill card edgeOpenCV泛洪补卡边
【发布时间】:2014-03-20 05:54:57
【问题描述】:

我正在使用此代码尝试在图像中查找卡片的边缘。当我运行它时,它只勾勒出卡片边缘的一半。

这是我返回的图像示例。

cvtColor(Img, bw, CV_RGB2GRAY);
Mat outerBox = Mat(bw.size(), CV_8UC1);
GaussianBlur(bw, bw, cv::Size(11,11), 0);
adaptiveThreshold(bw, outerBox, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 5, 2);
bitwise_not(outerBox, outerBox);
Mat kernel = (Mat_<uchar>(3,3) << 0,1,0,1,1,1,0,1,0);
dilate(outerBox, outerBox, kernel);

int count=0;
int max=-1;
cv::Point maxPt;

for(int y=0;y<outerBox.size().height;y++)
{
    uchar *row = outerBox.ptr(y);
    for(int x=0;x<outerBox.size().width;x++)
    {
        if(row[x]>=128)
        {
            int area = floodFill(outerBox, cv::Point(x,y), CV_RGB(0,0,64));

            if(area>max)
            {
                maxPt = cv::Point(x,y);
                max = area;
            }
        }
    }
}
floodFill(outerBox, maxPt, CV_RGB(255,255,255));

特别是有问题的代码行是floodFill(outerBox, maxPt, CV_RGB(255,255,255));

谁能告诉我如何修改我的代码以填充卡片边缘的其余部分?突出显示的边缘并不总是一致的,具体取决于图像,但至少 1/2 的边缘总是从左侧开始填充。

【问题讨论】:

    标签: c++ opencv


    【解决方案1】:

    你是发这个帖子的人吗? Automatic perspective correction OpenCV 你做的一切都很好,但方式很复杂。你的结果应该是。看到不同?不是线条,而是模糊。我猜你只是没有正确显示你的输出。顺便说一句,您忘记提及输入图像的链接并显示如何在代码中显示结果。

    查看算法的中间输出非常有益。您只需一行代码即可完成此操作,例如:

    imshow("blur", bw);
    

    也不要使用 CV_RGB(0,0,64) 等颜色值填充单通道灰度图像。在循环中动态执行此操作可能会导致意外结果。

    【讨论】:

    • 感谢我为 iOS 开发的响应。我通过将图像转换为UIImage 然后将它们放在我的设备屏幕上来输出我的图像。 _endImage = [self UIImageFromMat:outerBox]; 当我显示 bw 时,我只得到一张灰度图像。上面的结果是怎么得到的?
    • 我运行了你的代码,就是这样。我在 Eclipse 中的 Mac 上执行了此操作,并使用 imshow("win", mat) 完成了所有中间阶段以检查发生了什么。 Everythig 工作正常,但正如我提到的,你有一个潜在的错误代码,在灰色图像中写入彩色像素,你在每次循环迭代时修改和检查。只需使用 64 而不是 CV_RGB(0,0,64),如果您的系统仍然存在问题,则可能会在每次发现最大面积连接组件时输出。
    • 另外,如果您不知何故无法解决问题,请尝试使用 opencCV findContours() 函数(希望它会更快,并且可以在没有循环的情况下运行)。 docs.opencv.org/modules/imgproc/doc/… 您可以计算每个轮廓的长度,而不是连接组件的面积,以找到外围,甚至更好地为每个轮廓创建一个边界框,然后选择靠近图像边界的最大 bbox 的那个。
    • 谢谢我替换了那个代码,仍然给了我类似的结果,我想我会在 eclipse 中尝试我的 OpenCV 代码而不是 Xcode。在 Xcode 中,它不允许我使用 imshow imwrite。这可能会给我带来一些问题。
    • Eclipse 是个好主意。此外,由于您在代码中隐含地假设背景没有渐变(对比度),您可以从扩张的图像开始,沿着每一行和每一列从边界向中心移动,直到碰到卡片的外围为了发现卡片边框上的一组像素。换句话说,从顶部向下遍历,从底部向上遍历,从右边界向左遍历,从左边界向右遍历。它比使用 Connected Components 干净得多(如果卡片内部有一个长螺旋 CC 怎么办?)。祝你好运。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-06
    • 2019-12-10
    • 1970-01-01
    • 2013-09-13
    • 1970-01-01
    • 2017-02-20
    相关资源
    最近更新 更多