Ограничительная коробка с использованием OpenCV - PullRequest
1 голос
/ 08 сентября 2010

Я хочу получить ограничивающий прямоугольник из закрашенного черного круга на белом фоне, используя opencv BoundingRect.Я использовал пример кода из http://cgi.cse.unsw.edu.au/~cs4411/wiki/index.php?title=OpenCV_Guide#Finding_bounding_boxes_around_regions_of_a_binary_image, но не смог получить свойства ограничивающего прямоугольника и нарисовать его на изображении.Думаю, это должно быть простой проблемой, но все же я не могу это сделать ...

Было бы неплохо, если бы вы могли записать пример кода.

Спасибо.


В данный момент я использую изображение размером 1392x1040 пикселей с большим черным кружком посередине (диаметр около 1000 пикселей), а остальное изображение белое.

Мой источниккод:

#include <iostream>
#include <vector>
#include <cv.h>
#include <highgui.h>

using namespace std;

int main(int argc, char** argv){


IplImage* img_in = cvLoadImage("Schwarzer_Kreis.png",1);


IplImage* img_working = cvCreateImage(cvGetSize(img_in), 8, 1);
cvCvtColor(img_in, img_working, CV_BGR2GRAY);

CvSeq* seq;

vector<CvRect> boxes;

CvMemStorage* storage = cvCreateMemStorage(0);
cvClearMemStorage(storage);

cvFindContours(img_working, storage, &seq, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE, cvPoint(600,200));

CvRect boundbox ;

for(; seq; seq = seq->h_next) {
 boundbox = cvBoundingRect(seq);
 boxes.push_back(boundbox);
}

for (int ii=0; ii<boxes.size(); ii++) {
cout << boxes[ii].x << endl;
cout << boxes[ii].y << endl;
cout << boxes[ii].width << endl;
cout << boxes[ii].height << endl;
}


cvWaitKey(0);

return 0;

}

Вывод, который я получаю из программы:

601

201

1390

1038

Ответы [ 4 ]

8 голосов
/ 15 сентября 2011

Этот код использует функции OpenCV 2.1 «findContours» и «boundingRect», чтобы получить ограничивающую рамку бинаризованного изображения (0-255), которое рисует на ограничительной рамке. Избегайте шума, вычисляя ограничивающую рамку вокруг формы самой большой области.

Дополнительная информация http://www.davidlopez.es/?p=65

// Declares a vector of vectors for store the contours
vector<vector<Point> > v;

Mat originalimage;
Mat image;

// Loads the original image
originalimage = imread("original.ppm");
// Converts original image to an 8UC1 image
cvtColor(originalimage, image, CV_BGR2GRAY);

// Finds contours
findContours(image,v,CV_RETR_LIST,CV_CHAIN_APPROX_NONE);

// Finds the contour with the largest area
int area = 0;
int idx;
for(int i=0; i<v.size();i++) {
    if(area < v[i].size())
        idx = i; 
}

// Calculates the bounding rect of the largest area contour
Rect rect = boundingRect(v[idx]);
Point pt1, pt2;
pt1.x = rect.x;
pt1.y = rect.y;
pt2.x = rect.x + rect.width;
pt2.y = rect.y + rect.height;
// Draws the rect in the original image and show it
rectangle(originalimage, pt1, pt2, CV_RGB(255,0,0), 1);

cvNamedWindow( "Ejemplo", CV_WINDOW_AUTOSIZE );
imshow("Ejemplo", originalimage );
cvWaitKey(0);

cvDestroyWindow("Ejemplo" );
3 голосов
/ 14 сентября 2010

Я сделал свой собственный код для вычисления ограничивающей рамки:

int* get_boundingbox(
        IplImage* img_input){

int width     = img_input->width;
int height    = img_input->height;

int* Output = NULL;
Output = new int[4];


//----- Top boundary -----
for(int ii = 0 ; ii < height ; ii++ ){

    int value;

    for(int jj = 0 ; jj < width ; jj++ ) {

        value = static_cast<int>(cvGetReal2D(img_input,1039-ii,jj));

        if (value == 0) {
            Output[1] = 1039-ii; // upper left corner, y-value
            break;
      }
    if (value == 0) break;
    }
}


//----- Left boundary -----
for(int ii = 0 ; ii < width ; ii++ ){

    int value;

    for(int jj = 0 ; jj < height ; jj++ ) {

        value = static_cast<int>(cvGetReal2D(img_input,jj,1391-ii));

        if (value == 0) {
            Output[0] = 1391-ii; //upper left corner. x-value
            break;
      }
    if (value == 0) break;
    }
}


//----- Right boundary -----
for(int ii = 0 ; ii < width ; ii++ ){

    int value;

    for(int jj = 0 ; jj < height ; jj++ ) {

        value = static_cast<int>(cvGetReal2D(img_input,jj,ii));

        if (value == 0) {
            Output[2] = ii+1; // lower right corner, x-value
            break;
      }
    if (value == 0) break;
    }
}


//----- Bottom boundary -----
for(int ii = 0 ; ii < height ; ii++ ){

    int value;

    for(int jj = 0 ; jj < width ; jj++ ) {

        value = static_cast<int>(cvGetReal2D(img_input,ii,jj));

        if (value == 0) {
            Output[3] = ii+1; // lower right corner, y-value
            break;
      }
    if (value == 0) break;
    }
}


Output[2] = Output[2] - Output[0] + 1; // width
Output[3] = Output[3] - Output[1] + 1; // height

return Output;
delete []Output;

}
2 голосов
/ 09 сентября 2010

вы можете нарисовать его, используя

boundingRect=cvBoundingRect(seq,0); 
cvRectangle(contourImage,cvPoint(boundingRect.x,boundingRect.y),
                    cvPoint(boundingRect.x+boundingRect.width,
                    boundingRect.y+boundingRect.height),
                    _GREEN,1,8,0);
1 голос
/ 06 августа 2011

Вы можете рассмотреть возможность получения негатива изображения, которое у вас есть (кружок белого цвета на черном фоне) и затем попробовать свой код. Команда cvNot (src, dst).

Некоторые функции OpenCV требуют, чтобы фон был черным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...