边界检测纸张opencv [英] Boundry detect paper sheet opencv

查看:241
本文介绍了边界检测纸张opencv的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是openCV的新手,我已经检测到纸张边缘,但是在边缘画线后我的结果图像模糊了,如何在纸张边缘画线,这样我的图像质量不会受到影响。

I am new in openCV, I already detect edge of paper sheet but my result image is blurred after draw lines on edge, How I can draw lines on edges of paper sheet so my image quality remain unaffected.

我错过了什么..

我的代码如下。

非常感谢。

-(void)forOpenCV
{
   if( imageView.image != nil )
   {

      cv::Mat greyMat=[self cvMatFromUIImage:imageView.image];
      vector<vector<cv::Point> > squares;

      cv::Mat img= [self debugSquares: squares: greyMat ];


      imageView.image =[self UIImageFromCVMat: img];

   }

}


- (cv::Mat) debugSquares: (std::vector<std::vector<cv::Point> >) squares : (cv::Mat &)image
{
NSLog(@"%lu",squares.size());

// blur will enhance edge detection

Mat blurred(image);
medianBlur(image, blurred, 9);

Mat gray0(image.size(), CV_8U), gray;
vector<vector<cv::Point> > contours;

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

    // try several threshold levels
    const int threshold_level = 2;
    for (int l = 0; l < threshold_level; l++)
    {
        // Use Canny instead of zero threshold level!
        // Canny helps to catch squares with gradient shading
        if (l == 0)
        {
            Canny(gray0, gray, 10, 20, 3); //

            // Dilate helps to remove potential holes between edge segments
            dilate(gray, gray, Mat(), cv::Point(-1,-1));
        }
        else
        {
            gray = gray0 >= (l+1) * 255 / threshold_level;
        }

        // Find contours and store them in a list
        findContours(gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);

        // Test contours
        vector<cv::Point> approx;
        for (size_t i = 0; i < contours.size(); i++)
        {
            // approximate contour with accuracy proportional
            // to the contour perimeter
            approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true);

            // Note: absolute value of an area is used because
            // area may be positive or negative - in accordance with the
            // contour orientation
            if (approx.size() == 4 &&
                fabs(contourArea(Mat(approx))) > 1000 &&
                isContourConvex(Mat(approx)))
            {
                double maxCosine = 0;

                for (int j = 2; j < 5; j++)
                {
                    double cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1]));
                    maxCosine = MAX(maxCosine, cosine);
                }

                if (maxCosine < 0.3)
                    squares.push_back(approx);
            }
        }
    }
}

NSLog(@"%lu",squares.size());


for( size_t i = 0; i < squares.size(); i++ )
{


    cv:: Rect rectangle = boundingRect(Mat(squares[i]));
    if(i==squares.size()-1)////Detecting Rectangle here
    {
        const cv::Point* p = &squares[i][0];


        int n = (int)squares[i].size();

         NSLog(@"%d",n);



        line(image, cv::Point(507,418), cv::Point(507+1776,418+1372), Scalar(255,0,0),2,8);

        polylines(image, &p, &n, 1, true, Scalar(255,255,0), 5, CV_AA);



        fx1=rectangle.x;
        fy1=rectangle.y;
        fx2=rectangle.x+rectangle.width;
        fy2=rectangle.y+rectangle.height;


        line(image, cv::Point(fx1,fy1), cv::Point(fx2,fy2), Scalar(0,0,255),2,8);


    }



}


return image;
}


推荐答案

第一个问题是通过对原始图像的副本进行整个处理,轻松解决。这样,在你得到广场的所有点后,你可以在原始图像上画线,它就不会模糊。

The first problem is easily solved by doing the entire processing on a copy of the original image. That way, after you get all the points of the square you can draw the lines on the original image and it will not be blurred.

第二个问题是裁剪,可以通过在原始图像中定义ROI(感兴趣的区域)然后将其复制到新Mat来解决。我在这个答案中证明了这一点:

The second problem, which is cropping, can be solved by defining a ROI (region of interested) in the original image and then copying it to a new Mat. I've demonstrated that in this answer:

// Setup a Region Of Interest
cv::Rect roi;
roi.x = 50
roi.y = 10
roi.width = 400;
roi.height = 450;

// Crop the original image to the area defined by ROI
cv::Mat crop = original_image(roi);

cv::imwrite("cropped.png", crop);

这篇关于边界检测纸张opencv的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆