user1959079
user1959079

Reputation: 91

opencv/c++ how do i only detect key points inside a square area which had been detected before

I am working on my project and I got a problem is that I have no idea how to only detect the key points from a square area which had been detector before. Below is my demo and as so far, my code would detect key points both outside and inside square: https://www.youtube.com/watch?feature=player_embedded&v=3U8V6PhMnZ8

This is my code to find the square:

       const int threshold_level = 2;
    for (int l = 0; l < threshold_level; l++)
    {

        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<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))) > 3000 &&
                        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);
                }
        }
    }

This is my code to draw the square and the corner points:

 const Point* p = &squares[i][0];
        int n = (int)squares[i].size();       
        Point p1 = squares[i][0];
        Point p2 = squares[i][1];
        Point p3 = squares[i][2];
        Point p4 = squares[i][3];
        cout<<"p1 is "<<p1<<" p2 is "<<p2<<" p3 is "<<p3<<" p4 is "<<p4<<endl;
        circle(image, squares[i][0], 3, Scalar(0,0,255), 5, 8, 0);
        circle(image, squares[i][1], 3, Scalar(0,255,255), 5, 8, 0);
        circle(image, squares[i][2], 3, Scalar(255,0,255), 5, 8, 0);
        circle(image, squares[i][3], 3, Scalar(255,255,0), 5, 8, 0);

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

This is my code to detect key points:

    Mat gray_image;
    vector<KeyPoint> keyPoints; 
    cvtColor(image, gray_image, CV_BGR2GRAY); 
    FastFeatureDetector fast(60); 
    fast.detect(gray_image,keyPoints);  
    drawKeypoints(image, keyPoints,image, Scalar::all(255), DrawMatchesFlags::DRAW_OVER_OUTIMG); 

Upvotes: 1

Views: 1419

Answers (2)

You can crop the image using

Rect r(left,top,width,height); // Part of the image we are interested in

Mat roi(fullImage, r); // will create a reference to the rectangle r of the original image. Note that it is not a copy.

Upvotes: 1

Didac Perez Parera
Didac Perez Parera

Reputation: 3834

You have two possible solutions:

  1. Detect all the keypoints and then check if they are inside the square.
  2. Crop the square from the image to generate a new image and then detect keypoints there.

Cheers,

Upvotes: 1

Related Questions