检测图像中的正方形

Detecting squares in an image

本文关键字:正方形 图像 检测      更新时间:2023-10-16

我在网上找到了这个正方形检测代码,我正在努力理解它,有人理解结尾的行是什么吗?它表示:"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;
        }

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

无论如何,您所询问的代码行基本上是一个阈值过滤器,它基于根据级别应用于数组gray0的阈值来生成二进制gray-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
}

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

关于这种情况:

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

根据l+1(加1使范围从1到256开始,而不是从0到255)乘以255和整数除以N小于或等于阈值gray0的值,灰色设置为0或1(纯黑或纯白)

gray = gray0 >= (l+1)*255/N;