检测图像中的方块

时间:2014-04-14 12:18:38

标签: c++ opencv

我在网上发现了这个方形检测代码而我正在试图理解它,有人知道最后的那行是什么吗?它声明:“gray = gray0> =(l + 1)* 255 / N;”

Mat pyr,timg,gray0(image.size(),CV_8U),灰色;

// down-scale and upscale the image to filter out the noise
pyrDown(image, pyr, Size(image.cols/2, image.rows/2));
pyrUp(pyr, timg, image.size());
vector<vector<Point> > contours;

// find squares in every color plane of the image
for( int c = 0; c < 3; c++ )
{
    int ch[] = {c, 0};
    mixChannels(&timg, 1, &gray0, 1, ch, 1);

    // try several threshold levels
    for( int l = 0; l < N; l++ )
    {
        // hack: use Canny instead of zero threshold level.
        // Canny helps to catch squares with gradient shading
        if( l == 0 )
        {
            // apply Canny. Take the upper threshold from slider
            // and set the lower to 0 (which forces edges merging)
            Canny(gray0, gray, 0, thresh, 5);
            // dilate canny output to remove potential
            // holes between edge segments
            dilate(gray, gray, Mat(), Point(-1,-1));
        }
        else
        {
            // apply threshold if l!=0:
            // tgray(x,y) = gray(x,y) < (l+1)*255/N ? 255 : 0
            gray = gray0 >= (l+1)*255/N;
        }

3 个答案:

答案 0 :(得分:3)

此代码剪切是git存储库CVSquares的一部分。根据经验,我知道这个库在真实图像上效果不佳,但在计算机生成的图像中表现良好。此外,这种在RGB上检测而不转换为灰度的方法在计算上非常昂贵。

无论如何,您要问的代码行基本上是一个阈值过滤器,它根据级别根据应用于数组gray的阈值生成二进制gray0 Mat数组。如果条件为真,则数组在该位置包含白色像素,否则为黑色像素

基于灰度图像的更通用的检测代码可以更好地工作:

Mat binary_img(color_img.size(),CV_8UC1);
vector<Vec4i> hierarchy;
vector<vector<Point> > contours;
vector<cv::Point> approx;
cv::GaussianBlur(color_img, color_img, cv::Size(9,9), 3);
cv::medianBlur(color_img, color_img, 9);
cv::medianBlur(color_img, color_img, 9);
cvtColor(color_img,binary_img,CV_BGR2GRAY);
IplImage tempBinary=IplImage(binary_img);
cvInRangeS(&tempBinary, Scalar(20), Scalar(100), &tempBinary);
Mat imgMat=Mat(&tempBinary);
findContours( imgMat, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );

for(int i = 0; i < contours.size(); i++ )
{
    approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.0005, true);
    if(approx.size()==4)
       //draw approx
}

答案 1 :(得分:1)

该行的后半部分gray0 >= (l+1)*255/N是一个条件。 gray是一个变量,它将包含这个条件的真实性,因此它将是一个布尔值。但它是c / c ++代码,而布尔值在这里是整数。

关于这个条件:

(l + 1)* 255 / N将间隔(1,1)移动到(0,255)。因此,对于l = 0,它将是255 / N.对于l = N,它将正好是255。

答案 2 :(得分:1)

取决于l+1的值(添加1以使范围从1到256开始,而不是0到255)乘以255并且整数除以N小于或等于阈值{{ 1}},灰色设置为0或1(纯黑色或纯白色)

gray0