Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
159 views
in Technique[技术] by (71.8m points)

ios - Find corner of papers

I am new in openCV so struggling from last 3 to 4 days, I already detect paper sheet boundary, Now I wants to draw 4 circles on the corners.

I draw boundary from this code

const cv::Point* p = &squares[i][0];

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

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

I am new in openCV, So In my opinion I have upper left corner points p->x and p->y, But how I get the others corners, I am also confused in parameter &n in this polylines method, how this polylines method draw complete rectangle?

When I use bounding rect, It's not perfect it give's little space on side of paper sheet.

Any help is really appreciated

code is :

- (cv::Mat)finshWork:(cv::Mat &)image
{
// read in the apple (change path to the file)
Mat img0 =image;// imread("/home/philipp/img/apple.jpg", 1);

Mat img1;
cvtColor(img0, img1, CV_RGB2GRAY);

// apply your filter
Canny(img1, img1, 100, 200);

// find the contours
vector< vector<cv::Point> > contours;
findContours(img1, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);

/////for SQUARE CODE
std::vector<std::vector<cv::Point> > squares;
std::vector<cv::Point> approx;
for( size_t i = 0; i < contours.size(); i++ )
{
    cv::approxPolyDP(cv::Mat(contours[i]), approx, arcLength(cv::Mat(contours[i]), true)*0.02, true);
    if( approx.size() == 4 && fabs(contourArea(cv::Mat(approx))) > 1000 && cv::isContourConvex(cv::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);
            cv::Point newPoint = approx[0]; 

            NSLog(@"x is %d and  y is %d",newPoint.x,newPoint.y);
        }
    }
}

const cv::Point* p = &squares[0][0];


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

NSLog(@"%d",n);


//THIS IS WORKING CODE              

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

Thanks

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Take for reference my original code, which simply detects squares on an image.

That means that in the main method of the application you would write something like the following pseudo-code to call find_squares():

Mat image = imread("test.jpg", 1);

// Detect all regions in the image that are similar to a rectangle
vector<vector<Point> > squares;
find_squares(image, squares);

// The largest of them probably represents the paper
vector<Point> largest_square;
find_largest_square(squares, largest_square);

// Print the x,y coordinates of the square
cout << "Point 1: " << largest_square[0] << endl;
cout << "Point 2: " << largest_square[1] << endl;
cout << "Point 3: " << largest_square[2] << endl;
cout << "Point 4: " << largest_square[3] << endl;

The trick relies on find_largest_square() presented below:

void find_largest_square(const vector<vector<Point> >& squares, vector<Point>& biggest_square)
{
    if (!squares.size())
    {
            // no squares detected
            return;
    }

    int max_width = 0;
    int max_height = 0;
    int max_square_idx = 0;
    const int n_points = 4;

    for (size_t i = 0; i < squares.size(); i++)
    {
            // Convert a set of 4 unordered Points into a meaningful cv::Rect structure.
            Rect rectangle = boundingRect(Mat(squares[i]));

    //        cout << "find_largest_square: #" << i << " rectangle x:" << rectangle.x << " y:" << rectangle.y << " " << rectangle.width << "x" << rectangle.height << endl;

            // Store the index position of the biggest square found
            if ((rectangle.width >= max_width) && (rectangle.height >= max_height))
            {
                    max_width = rectangle.width;
                    max_height = rectangle.height;
                    max_square_idx = i;
            }
    }

    biggest_square = squares[max_square_idx];
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...