Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

the most important part here is to simplify it. no connectedComponentsWithStats nonsense needed here ! also you probably should not iterate over small rois, becaus orb kp work on 32 pixel patches, thus you have to spare a 16 pixel border per rectangle, which will derease the already sparse kp significantly.

just draw your mask properly, and apply to the detection.

(if you want to retain only 10 kp per square, better filter for that later, but again, there cannot be any guaratee, that it will find at least 10)

// Mat ocv = ... // the input (bgr)
Mat gray; cvtColor(ocv,gray,COLOR_BGR2GRAY);
Mat mask(ocv.size(), CV_8U, Scalar(0));

int w = ocv.cols/5;
int h = ocv.cols/5;
int x=0, y=0;
for (int i=0; i<5; i++) {
    for (int j=0; j<5; j++) {
         int col = (i+j)%2==0 ? 255:0;
        rectangle(mask,Rect(x,y,w,h),Scalar(col),-1);
        x+=w;
    }
    y += h; x=0;
}


Ptr<ORB> detector = ORB::create();
vector<KeyPoint> keypoints;
detector->detect(gray, keypoints, mask);

Mat chan[3] = {mask, gray,gray};
merge(chan, 3, ocv);
drawKeypoints(ocv, keypoints, ocv,Scalar(0,0,255));

image description

as you can see, it properly respects the mask now in the kp detection.

the most important part here is to simplify it. no connectedComponentsWithStats nonsense needed here ! also you probably should not iterate over small rois, becaus because orb kp work on 32 pixel patches, thus you have to spare a 16 pixel border per rectangle, which will derease the already sparse kp significantly.

just draw your mask properly, and apply to the detection.

(if you want to retain only 10 kp per square, better filter for that later, but again, there cannot be any guaratee, that it will find at least 10)

// Mat ocv = ... // the input (bgr)
Mat gray; cvtColor(ocv,gray,COLOR_BGR2GRAY);
Mat mask(ocv.size(), CV_8U, Scalar(0));

int w = ocv.cols/5;
int h = ocv.cols/5;
int x=0, y=0;
for (int i=0; i<5; i++) {
    for (int j=0; j<5; j++) {
         int col = (i+j)%2==0 ? 255:0;
        rectangle(mask,Rect(x,y,w,h),Scalar(col),-1);
        x+=w;
    }
    y += h; x=0;
}


Ptr<ORB> detector = ORB::create();
vector<KeyPoint> keypoints;
detector->detect(gray, keypoints, mask);

Mat chan[3] = {mask, gray,gray};
merge(chan, 3, ocv);
drawKeypoints(ocv, keypoints, ocv,Scalar(0,0,255));

image description

as you can see, it properly respects the mask now in the kp detection.

the most important part here is to simplify it. no connectedComponentsWithStats needed here ! also you probably should not iterate over small rois, because orb kp work on 32 pixel patches, thus you have to spare a 16 pixel border per rectangle, which will derease decrease the already sparse kp count significantly.

just draw your mask properly, and apply to the detection.

(if you want to retain only 10 kp per square, better filter for that later, but again, there cannot be any guaratee, guarantee, that it will find at least 10)

// Mat ocv = ... // the input (bgr)
Mat gray; cvtColor(ocv,gray,COLOR_BGR2GRAY);
Mat mask(ocv.size(), CV_8U, Scalar(0));

int w = ocv.cols/5;
int h = ocv.cols/5;
int x=0, y=0;
for (int i=0; i<5; i++) {
    for (int j=0; j<5; j++) {
         int col = (i+j)%2==0 ? 255:0;
        rectangle(mask,Rect(x,y,w,h),Scalar(col),-1);
        x+=w;
    }
    y += h; x=0;
}


Ptr<ORB> detector = ORB::create();
vector<KeyPoint> keypoints;
detector->detect(gray, keypoints, mask);

Mat chan[3] = {mask, gray,gray};
merge(chan, 3, ocv);
drawKeypoints(ocv, keypoints, ocv,Scalar(0,0,255));

image description

as you can see, it properly respects the mask now in the kp detection.