Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

How to find specified number keypoints in mask

ORB is very fast, but it always too few points,which make me awkward. So I have made a such mask

I want to find 10 keypoints in every white rectangle by ORB. But as the documentation here. The first argument just mean:

The maximum number of features to retain.

This is my current method

//OpenCV 3.3.1 project
#include<opencv.hpp>
using namespace std;
using namespace cv;

Mat highlight(Mat, Mat);
int main() {
    Mat emptyImg = imread("test.jpg", 0);
    Mat test = emptyImg.clone();

    Mat mask(5, 5, CV_8UC1, Scalar(0));
    for (int i = 0; i < mask.rows; i++) {
        uchar* data = mask.ptr<uchar>(i);
        for (int j = 0; j < mask.cols; j++)
            if ((i + j) % 2 == 0)
                data[j] = 255;
    }
    resize(mask, mask, emptyImg.size(), 0, 0, INTER_NEAREST);
    Mat labels, stats, centroids;
    int nmask = connectedComponentsWithStats(mask, labels, stats, centroids, 4, CV_16U);
    stats.convertTo(stats, CV_8U);

    vector<Mat> rects;
    for (int i = 1; i < nmask; i++) {
        uchar* data = stats.ptr<uchar>(i);
        Mat temImg = Mat(mask.size(), CV_8UC1, Scalar(0));
        rectangle(temImg, Rect(data[0], data[1], data[2], data[3]), Scalar(255), FILLED);
        rects.push_back(temImg);
    }

    Ptr<ORB> detector = ORB::create(10);
    vector<KeyPoint> keypoints_empty;

    for (int i = 0; i < nmask - 1; i++) {
        vector<KeyPoint> tem_keypoints_empty;
        detector->detect(emptyImg, tem_keypoints_empty,rects[i]);
        //string name="rects";
        //imshow((name + to_string(i)).c_str(), rects[i]);
        //waitKey(1);
        keypoints_empty.insert(keypoints_empty.end(), tem_keypoints_empty.begin(), tem_keypoints_empty.end());
    }
    Mat showImg=highlight(emptyImg,mask),resultImg;
    drawKeypoints(showImg, keypoints_empty, resultImg,Scalar(0,255,255));
    imshow("keyImg", resultImg);
    waitKey();
    return 0;
}

Mat highlight(Mat srcImg, Mat mask) {
    if (srcImg.size != mask.size) {
        cout << "Your two images tried to highlight have different SIZE.\n";
        exit(1);
    }
    if (mask.channels() != 1)
        cvtColor(mask, mask, COLOR_BGR2GRAY);
    if (mask.type() != CV_8UC1)
        mask.convertTo(mask, CV_8UC1);
    threshold(mask, mask, 0, 255, THRESH_BINARY_INV + THRESH_OTSU);
    cvtColor(mask, mask, COLOR_GRAY2BGR);
    if (srcImg.channels() != 3)
        cvtColor(srcImg, srcImg, COLOR_GRAY2BGR);
    if (srcImg.type() != CV_8UC3)
        srcImg.convertTo(srcImg, CV_8UC3);
    dilate(mask - Scalar(0, 0, 255), mask, Mat(), Point(-1, -1), 2);
    return srcImg - mask;
}

I don't think any problem in my code, but the resultImg make me confused very much..

As we see, there are two problem in my method.

  1. There are some keypoints out of the white rectange
  2. Some rectangle have a few keypoints even have none

Can anybody can help me out?

How to find specified number keypoints in mask

ORB is very fast, but it always too few points,which make me awkward. So I have made a such mask

I want to find 10 keypoints in every white rectangle by ORB. But as the documentation here. The first argument just mean:

The maximum number of features to retain.

This is my current method

//OpenCV 3.3.1 project
#include<opencv.hpp>
using namespace std;
using namespace cv;

Mat highlight(Mat, Mat);
int main() {
    Mat emptyImg = imread("test.jpg", 0);
    Mat test = emptyImg.clone();

    Mat mask(5, 5, CV_8UC1, Scalar(0));
    for (int i = 0; i < mask.rows; i++) {
        uchar* data = mask.ptr<uchar>(i);
        for (int j = 0; j < mask.cols; j++)
            if ((i + j) % 2 == 0)
                data[j] = 255;
    }
    resize(mask, mask, emptyImg.size(), 0, 0, INTER_NEAREST);
    Mat labels, stats, centroids;
    int nmask = connectedComponentsWithStats(mask, labels, stats, centroids, 4, CV_16U);
    stats.convertTo(stats, CV_8U);

    vector<Mat> rects;
    for (int i = 1; i < nmask; i++) {
        uchar* data = stats.ptr<uchar>(i);
        Mat temImg = Mat(mask.size(), CV_8UC1, Scalar(0));
        rectangle(temImg, Rect(data[0], data[1], data[2], data[3]), Scalar(255), FILLED);
        rects.push_back(temImg);
    }

    Ptr<ORB> detector = ORB::create(10);
    vector<KeyPoint> keypoints_empty;

    for (int i = 0; i < nmask - 1; i++) {
        vector<KeyPoint> tem_keypoints_empty;
        detector->detect(emptyImg, tem_keypoints_empty,rects[i]);
        //string name="rects";
        //imshow((name + to_string(i)).c_str(), rects[i]);
        //waitKey(1);
        keypoints_empty.insert(keypoints_empty.end(), tem_keypoints_empty.begin(), tem_keypoints_empty.end());
    }
    Mat showImg=highlight(emptyImg,mask),resultImg;
    drawKeypoints(showImg, keypoints_empty, resultImg,Scalar(0,255,255));
    imshow("keyImg", resultImg);
    waitKey();
    return 0;
}

Mat highlight(Mat srcImg, Mat mask) {
    if (srcImg.size != mask.size) {
        cout << "Your two images tried to highlight have different SIZE.\n";
        exit(1);
    }
    if (mask.channels() != 1)
        cvtColor(mask, mask, COLOR_BGR2GRAY);
    if (mask.type() != CV_8UC1)
        mask.convertTo(mask, CV_8UC1);
    threshold(mask, mask, 0, 255, THRESH_BINARY_INV + THRESH_OTSU);
    cvtColor(mask, mask, COLOR_GRAY2BGR);
    if (srcImg.channels() != 3)
        cvtColor(srcImg, srcImg, COLOR_GRAY2BGR);
    if (srcImg.type() != CV_8UC3)
        srcImg.convertTo(srcImg, CV_8UC3);
    dilate(mask - Scalar(0, 0, 255), mask, Mat(), Point(-1, -1), 2);
    return srcImg - mask;
}

I don't think any problem in my code, but the resultImg make me confused very much..much..And this is my test image

As we see, there are two problem in my method.

  1. There are some keypoints out of the white rectange
  2. Some rectangle have a few keypoints even have none

Can anybody can help me out?

How to find specified number keypoints in mask

Cross post here


ORB is very fast, but it always too few points,which make me awkward. So I have made a such mask

I want to find 10 keypoints in every white rectangle by ORB. But as the documentation here. The first argument just mean:

The maximum number of features to retain.

This is my current method

//OpenCV 3.3.1 project
#include<opencv.hpp>
using namespace std;
using namespace cv;

Mat highlight(Mat, Mat);
int main() {
    Mat emptyImg = imread("test.jpg", 0);
    Mat test = emptyImg.clone();

    Mat mask(5, 5, CV_8UC1, Scalar(0));
    for (int i = 0; i < mask.rows; i++) {
        uchar* data = mask.ptr<uchar>(i);
        for (int j = 0; j < mask.cols; j++)
            if ((i + j) % 2 == 0)
                data[j] = 255;
    }
    resize(mask, mask, emptyImg.size(), 0, 0, INTER_NEAREST);
    Mat labels, stats, centroids;
    int nmask = connectedComponentsWithStats(mask, labels, stats, centroids, 4, CV_16U);
    stats.convertTo(stats, CV_8U);

    vector<Mat> rects;
    for (int i = 1; i < nmask; i++) {
        uchar* data = stats.ptr<uchar>(i);
        Mat temImg = Mat(mask.size(), CV_8UC1, Scalar(0));
        rectangle(temImg, Rect(data[0], data[1], data[2], data[3]), Scalar(255), FILLED);
        rects.push_back(temImg);
    }

    Ptr<ORB> detector = ORB::create(10);
    vector<KeyPoint> keypoints_empty;

    for (int i = 0; i < nmask - 1; i++) {
        vector<KeyPoint> tem_keypoints_empty;
        detector->detect(emptyImg, tem_keypoints_empty,rects[i]);
        //string name="rects";
        //imshow((name + to_string(i)).c_str(), rects[i]);
        //waitKey(1);
        keypoints_empty.insert(keypoints_empty.end(), tem_keypoints_empty.begin(), tem_keypoints_empty.end());
    }
    Mat showImg=highlight(emptyImg,mask),resultImg;
    drawKeypoints(showImg, keypoints_empty, resultImg,Scalar(0,255,255));
    imshow("keyImg", resultImg);
    waitKey();
    return 0;
}

Mat highlight(Mat srcImg, Mat mask) {
    if (srcImg.size != mask.size) {
        cout << "Your two images tried to highlight have different SIZE.\n";
        exit(1);
    }
    if (mask.channels() != 1)
        cvtColor(mask, mask, COLOR_BGR2GRAY);
    if (mask.type() != CV_8UC1)
        mask.convertTo(mask, CV_8UC1);
    threshold(mask, mask, 0, 255, THRESH_BINARY_INV + THRESH_OTSU);
    cvtColor(mask, mask, COLOR_GRAY2BGR);
    if (srcImg.channels() != 3)
        cvtColor(srcImg, srcImg, COLOR_GRAY2BGR);
    if (srcImg.type() != CV_8UC3)
        srcImg.convertTo(srcImg, CV_8UC3);
    dilate(mask - Scalar(0, 0, 255), mask, Mat(), Point(-1, -1), 2);
    return srcImg - mask;
}

I don't think any problem in my code, but the resultImg make me confused very much..And this is my test image

As we see, there are two problem in my method.

  1. There are some keypoints out of the white rectange
  2. Some rectangle have a few keypoints even have none

Can anybody can help me out?

How to find specified number keypoints in mask

Cross post here


ORB is very fast, but it always too few points,which make me awkward. So I have made a such mask

I want to find 10 keypoints in every white rectangle rectangle by ORB. But as the documentation here. The first argument just mean:

The maximum number of features to retain.

This is my current method

//OpenCV 3.3.1 project
#include<opencv.hpp>
using namespace std;
using namespace cv;

Mat highlight(Mat, Mat);
int main() {
    Mat emptyImg = imread("test.jpg", 0);
    Mat test = emptyImg.clone();

    Mat mask(5, 5, CV_8UC1, Scalar(0));
    for (int i = 0; i < mask.rows; i++) {
        uchar* data = mask.ptr<uchar>(i);
        for (int j = 0; j < mask.cols; j++)
            if ((i + j) % 2 == 0)
                data[j] = 255;
    }
    resize(mask, mask, emptyImg.size(), 0, 0, INTER_NEAREST);
    Mat labels, stats, centroids;
    int nmask = connectedComponentsWithStats(mask, labels, stats, centroids, 4, CV_16U);
    stats.convertTo(stats, CV_8U);

    vector<Mat> rects;
    for (int i = 1; i < nmask; i++) {
        uchar* data = stats.ptr<uchar>(i);
        Mat temImg = Mat(mask.size(), CV_8UC1, Scalar(0));
        rectangle(temImg, Rect(data[0], data[1], data[2], data[3]), Scalar(255), FILLED);
        rects.push_back(temImg);
    }

    Ptr<ORB> detector = ORB::create(10);
    vector<KeyPoint> keypoints_empty;

    for (int i = 0; i < nmask - 1; i++) {
        vector<KeyPoint> tem_keypoints_empty;
        detector->detect(emptyImg, tem_keypoints_empty,rects[i]);
        //string name="rects";
        //imshow((name + to_string(i)).c_str(), rects[i]);
        //waitKey(1);
        keypoints_empty.insert(keypoints_empty.end(), tem_keypoints_empty.begin(), tem_keypoints_empty.end());
    }
    Mat showImg=highlight(emptyImg,mask),resultImg;
    drawKeypoints(showImg, keypoints_empty, resultImg,Scalar(0,255,255));
    imshow("keyImg", resultImg);
    waitKey();
    return 0;
}

Mat highlight(Mat srcImg, Mat mask) {
    if (srcImg.size != mask.size) {
        cout << "Your two images tried to highlight have different SIZE.\n";
        exit(1);
    }
    if (mask.channels() != 1)
        cvtColor(mask, mask, COLOR_BGR2GRAY);
    if (mask.type() != CV_8UC1)
        mask.convertTo(mask, CV_8UC1);
    threshold(mask, mask, 0, 255, THRESH_BINARY_INV + THRESH_OTSU);
    cvtColor(mask, mask, COLOR_GRAY2BGR);
    if (srcImg.channels() != 3)
        cvtColor(srcImg, srcImg, COLOR_GRAY2BGR);
    if (srcImg.type() != CV_8UC3)
        srcImg.convertTo(srcImg, CV_8UC3);
    dilate(mask - Scalar(0, 0, 255), mask, Mat(), Point(-1, -1), 2);
    return srcImg - mask;
}

I don't think any problem in my code, but the resultImg make me confused very much..And this is my test image

As we see, there are two problem in my method.

  1. There are some keypoints out of the white rectange
  2. Some rectangle have a few keypoints even have none

Can anybody can help me out?