OpenCV C++/Obj-C: goodFeaturesToTrack внутри определенного блоба

Есть ли быстрое решение для указания ROI только в пределах контуров интересующего меня блоба?

Мои идеи на данный момент:

  1. Использую boundingRect, но он содержит слишком много вещей, которые я не хочу анализировать.
  2. Применение goodFeaturesToTrack ко всему изображению, а затем цикл по выходным координатам, чтобы исключить один раз за пределами моего контура капель

Заранее спасибо!

ИЗМЕНИТЬ

Я нашел то, что мне нужно: cv::pointPolygonTest() кажется правильным, но я не уверен, как это реализовать …

Вот код:

// ...
IplImage forground_ipl = result;
IplImage *labelImg = cvCreateImage(forground.size(), IPL_DEPTH_LABEL, 1);

CvBlobs blobs;
bool found = cvb::cvLabel(&forground_ipl, labelImg, blobs);
IplImage *imgOut = cvCreateImage(cvGetSize(&forground_ipl), IPL_DEPTH_8U, 3);

if (found) {
    vb::CvBlob *greaterBlob = blobs[cvb::cvGreaterBlob(blobs)];
    cvb::cvRenderBlob(labelImg, greaterBlob, &forground_ipl, imgOut);
    CvContourPolygon *polygon = cvConvertChainCodesToPolygon(&greaterBlob->contour);
}

"polygon" содержит нужный мне контур.

goodFeaturesToTrack реализован так:

- (std::vector<cv::Point2f>)pointsFromGoodFeaturesToTrack:(cv::Mat &)_image
{
    std::vector<cv::Point2f> corners;
    cv::goodFeaturesToTrack(_image,corners, 100, 0.01, 10);
    return corners;
}

Итак, теперь мне нужно перебрать углы и проверить каждую точку с помощью cv::pointPolygonTest(), верно?


person dom    schedule 22.12.2011    source источник
comment
Можете ли вы сделать быстрый пример того, что вы хотите?   -  person mevatron    schedule 22.12.2011
comment
@mevatron Я получил контуры коробки (другой поток) с вашей помощью и cvBlob, теперь я запускаю goodFeaturesToTrack на входном изображении, чтобы получить интересующие меня углы коробки. Следующий шаг — фильтрация углов, чтобы получить только один раз внутри контура коробки. Надеюсь, ты получишь то, что я хочу сделать…   -  person dom    schedule 22.12.2011


Ответы (1)


Вы можете создать маску над интересующей вас областью:

EDIT Как сделать маску:

Сделать маску;

Mat mask(origImg.size(), CV_8UC1);
mask.setTo(Scalar::all(0));
// here I assume your contour is extracted with findContours, 
// and is stored in a vector<vector<Point>> 
// and that you know which contour is the blob
// if it's not the case, use fillPoly instead of drawContour();
Scalar color(255,255,255); // white. actually, it's monchannel.
drawContours(mask, contours, contourIdx, color );

// fillPoly(Mat& img, const Point** pts, const int* npts, 
//         int ncontours, const Scalar& color)

И теперь вы готовы его использовать. НО внимательно посмотрите на результат - я слышал о некоторых ошибках в OpenCV, касающихся параметра маски для экстракторов функций, и я не уверен, что это именно об этом.

// note the mask parameter:

void goodFeaturesToTrack(InputArray image, OutputArray corners, int maxCorners, 
    double qualityLevel, double minDistance, 
    InputArray mask=noArray(), int blockSize=3, 
    bool useHarrisDetector=false, double k=0.04 )

Это также улучшит скорость вашего приложения — goodFeaturesToTrack съедает огромное количество времени, и если вы применяете его только к меньшему изображению, общий выигрыш будет значительным.

person Sam    schedule 22.12.2011
comment
Спасибо, это хороший момент! Но я не знаю, как преобразовать CvContourPolygon в совместимый с OpenCV InputArray… - person dom; 22.12.2011