【问题标题】:OpenCV2 findContours(), contours size not equals to hierarchy sizeOpenCV2 findContours(),轮廓大小不等于层次大小
【发布时间】:2016-03-24 23:17:07
【问题描述】:

我尝试使用 findContour() 从下图中获取轮廓

代码是这样的:

Mat mat = imread("123.jpg");
    cv::imshow("123.jpg",mat);

    Mat hsv;
    cvtColor(mat,hsv,COLOR_BGR2HSV);

    Mat dst;
    inRange(hsv,Scalar(0,0,49),Scalar(47,165,111),dst);
    cout<<"dst channels:"<<dst.channels()<<endl;

    int c0=0,c255=0,other=0;
    for(int i=0;i<dst.rows;i++){
        for(int j=0;j<dst.cols;j++){
            int v = dst.at<uchar>(i,j);
            if(v == 0){
                c0++;
            }else if(v == 255){
                c255++;
            }else{
                other++;
            }
        }
    }

    cout<<"0 count:"<<c0<<",255 count:"<<c255<<",other value count:"<<other<<endl;

    cv::erode(dst,dst,cv::Mat(),cv::Point(1,1),6);
    cv::dilate(dst,dst,cv::Mat(),cv::Point(1,1),6);

    cv::medianBlur(dst,dst,15);
    cv::imshow("inRange",dst);

    vector< vector<Point> > contours;
    vector<Vec4i> hierarchy;
    Mat temp;
    dst.copyTo(temp);

    findContours(temp,contours,hierarchy,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE );

    cout<<"contours size:"<<contours.size()<<endl;
    cout<<"hierarchy size:"<<hierarchy.size()<<endl;

    for (int index = 0; index >= 0; index = hierarchy[index][0]) {
        cout<<"hierarchy at:"<<index<<","<<hierarchy[index]<<endl;
        cv::drawContours(mat,contours,index,Scalar(120,255,0));
    }

    cv::imshow("contours",mat);

    waitKey(0);
    return 0;

二值图像是这样的:

最终的轮廓图是这样的:

控制台窗口打印的日志是这样的:

我不知道为什么轮廓尺寸小于层次结构尺寸。实际上,应该有三个“EXTERNAL”形状。似乎错过了输出轮廓中的一种形状。这个问题困扰了我一天,我现在要发疯了...有人知道为什么轮廓中只有两个元素吗?我做错了什么吗?

【问题讨论】:

  • AFAIK 当你用 CV_RETR_EXTERNAL 参数层次调用 findContours() 时没有意义

标签: c++ opencv


【解决方案1】:

这对我来说按预期工作:

contours size:3
hierarchy size:3 
hierarchy at:0,[1, -1, -1, -1]
hierarchy at:1,[2, 0, -1, -1]
hierarchy at:2,[-1, 1, -1, -1]

您的代码中可能存在的问题是:

  • dst 可能初始化不正确
  • dst 可能不是二进制的,即可以具有不同于 0255 的值

代码:

#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;

int main()
{
    // Load image
    Mat3b img = imread("path_to_image");

    // Convert to grayscale
    Mat1b bin;
    cvtColor(img, bin, COLOR_BGR2GRAY);

    // Binarize (remove jpeg artifacts)
    bin = bin > 100;

    vector< vector<Point> > contours;
    vector<Vec4i> hierarchy;

    findContours(bin.clone(), contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);

    cout << "contours size:" << contours.size() << endl;
    cout << "hierarchy size:" << hierarchy.size() << endl;

    for (int index = 0; index >= 0; index = hierarchy[index][0]) {
        cout << "hierarchy at:" << index << "," << hierarchy[index] << endl;
        cv::drawContours(img, contours, index, Scalar(120, 255, 0), 2);
    }

    imshow("Result", img);
    waitKey();

    return 0;
}

【讨论】:

  • 嗨,三木,感谢您的帮助。这就是我初始化 dst 的方式: Mat mat = imread("123.jpg");垫 hsv; cvtColor(mat,hsv,COLOR_BGR2HSV);垫 dst; inRange(hsv,Scalar(0,0,49),Scalar(47,165,111),dst); cout(i,j); if(v !=0 && v != 255){ cout
  • 抱歉,我不知道如何在注释中格式化代码。因此它看起来有点乱,无论如何,似乎是因为这个原因“dst 可能不是二进制的,即可以具有不同于 0 和 255 的值”。我试图在 dst 中打印所有“像素”。有很多“-1”。不知道为什么,你能帮忙检查一下吗?
  • 当然,您没有正确检查:int v = dst.at&lt;uchar&gt;(i,j);。这是uchar,不是char
  • 另外,请将所有相关代码发布到问题中,格式正确@Chailie
  • 好的,我已经重新格式化了代码,还上传了所有相关图片。请查看它。非常感谢!
【解决方案2】:

我的 VS 工具已链接到 ..\opencv\build\x64\vc12\lib,我遇到了类似的问题。

我通过将链接更改为..\opencv\build\x86\vc12\lib解决了这个问题

我在 Windows 7 上使用 Visual Studio 2010。

【讨论】:

  • 如果您有新问题,请点击 按钮提出问题。如果有助于提供上下文,请包含指向此问题的链接。 - From Review
  • 这不是一个新问题。我的意思是我之前用过 64 位的 lib 遇到了这个问题,在我改成 32 位的 lib 之后,它就没有这种问题了
猜你喜欢
  • 2016-09-21
  • 1970-01-01
  • 1970-01-01
  • 2018-07-05
  • 2018-06-16
  • 1970-01-01
  • 1970-01-01
  • 2018-02-21
  • 1970-01-01
相关资源
最近更新 更多