如何在opencv中获得轮廓角

时间:2014-05-04 18:58:13

标签: c++ opencv image-processing

我在C ++和opencv

工作

我正在检测图像中的大轮廓,因为我有一个黑色区域。My image

在这种情况下,该区域只是水平的,但它可以在任何地方。

Mat resultGray;
 cvtColor(result,resultGray, COLOR_BGR2GRAY);
 medianBlur(resultGray,resultGray,3);
 Mat resultTh;
 Mat canny_output;
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
 Canny( resultGray, canny_output, 100, 100*2, 3 );

    findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
    Vector<Point> best= contours[0];
    int max_area = -1;
    for( int i = 0; i < contours.size(); i++ ) {
            Scalar color = Scalar( 0, 0, 0 );

            if(contourArea(contours[i])> max_area)
            {
                max_area=contourArea(contours[i]);
                best=contours[i];
            }
    }
    Mat approxCurve;
    approxPolyDP(Mat(best),approxCurve,0.01*arcLength(Mat(best),true),true);

这个,我有大的轮廓和它的近似值(在大约中)。现在,我想获得这个近似的角点并将图像放在这个轮廓内,但我不知道我该怎么做。

我正在使用此How to remove black part from the image? 但最后一部分我不太清楚。

任何人都知道如何获得角落?这是另一种更简单的方法吗?

感谢您的时间,

2 个答案:

答案 0 :(得分:4)

一种更简单的方法是检查图像像素并找到非黑色像素的最小/最大坐标。

这样的事情:

int maxx,maxy,minx,miny;
maxx=maxy=-std::numeric_limits<int>::max();
minx=miny=std::numeric_limits<int>::min();
for(int y=0; y<img.rows; ++y)
{
    for(int x=0; x<img.cols; ++x)
    {
        const cv::Vec3b &px = img.at<cv::Vec3b>(y,x);
        if(px(0)==0 && px(1)==0 && px(2)==0)
            continue;
        if(x<minx) minx=x;
        if(x>maxx) maxx=x;
        if(y<miny) miny=y;
        if(y>maxy) maxy=y;
    }
}
cv::Mat subimg;
img(cv::Rect(cv::Point(minx,miny),cv::Point(maxx,maxy))).copyTo(subimg);

在我看来,这种方法更可靠,因为您不必检测任何轮廓,这可能会导致根据输入图像进行错误检测。

答案 1 :(得分:1)

以非常有效的方式,您可以对原始图像进行采样,直到找到一个像素,并从那里沿着一行和一列移动以找到第一个(0,0,0)像素。它会工作,除非在图像的好部分你可以有(0,0,0)像素。如果是这种情况(例如:死像素),你可以添加一个双重检查来检查这个(0,0,0)像素的邻域(它应该包含其他(0,0,0)像素。