OpenCV cvblob - рендер Blob - PullRequest
       12

OpenCV cvblob - рендер Blob

2 голосов
/ 21 сентября 2011

Я пытаюсь обнаружить объект, используя cvblob.Поэтому я использую cvRenderBlob() метод.Программа скомпилирована успешно, но когда во время выполнения она возвращает необработанное исключение.Когда я его ломаю, стрелка указывает на оператор CvLabel *labels = (CvLabel *)imgLabel->imageData + imgLabel_offset + (blob->miny * stepLbl); в определении метода cvRenderBlob() файла cvblob.cpp Но если я использую метод cvRenderBlobs(), он работает нормально.Мне нужно обнаружить только один шарик, который является самым большим.Кто-нибудь, пожалуйста, помогите мне разобраться с этим исключением.Вот мой код VC ++,

CvCapture* capture = 0;
IplImage* frame = 0;
int key = 0;
CvBlobs blobs;
CvBlob *blob;

capture = cvCaptureFromCAM(0);

if (!capture) {
    printf("Could not initialize capturing....\n");
    return 1;
}

int screenx = GetSystemMetrics(SM_CXSCREEN);
int screeny = GetSystemMetrics(SM_CYSCREEN);

while (key!='q') {
    frame = cvQueryFrame(capture);
    if (!frame) break;

    IplImage* imgHSV = cvCreateImage(cvGetSize(frame), 8, 3);
    cvCvtColor(frame, imgHSV, CV_BGR2HSV);

    IplImage* imgThreshed = cvCreateImage(cvGetSize(frame), 8, 1);
    cvInRangeS(imgHSV, cvScalar(61, 156, 205),cvScalar(161, 256, 305), imgThreshed); // for light blue color

    IplImage* imgThresh = imgThreshed; 
    cvSmooth(imgThresh, imgThresh, CV_GAUSSIAN, 9, 9);

    cvNamedWindow("Thresh"); 
    cvShowImage("Thresh", imgThresh); 
    IplImage* labelImg = cvCreateImage(cvGetSize(imgHSV), IPL_DEPTH_LABEL, 1);
    unsigned int result = cvLabel(imgThresh, labelImg, blobs);

    blob = blobs[cvGreaterBlob(blobs)];
    cvRenderBlob(labelImg, blob, frame, frame);
    /*cvRenderBlobs(labelImg, blobs, frame, frame);*/
    /*cvFilterByArea(blobs, 60, 500);*/ 
    cvFilterByLabel(blobs, cvGreaterBlob(blobs));

    cvNamedWindow("Video");
    cvShowImage("Video", frame);
    key = cvWaitKey(1); 
 }

cvDestroyWindow("Thresh");
cvDestroyWindow("Video");
cvReleaseCapture(&capture);

1 Ответ

1 голос
/ 03 декабря 2011

Прежде всего, я хотел бы отметить, что вы на самом деле используете обычный синтаксис c. C ++ использует класс Mat. Я работал над извлечением капель на основе зеленых объектов на картинке. После правильного определения порога, это означает, что у нас есть «двоичное» изображение, background / foreground. Я использую

findContours() //this function expects quite a bit, read documentation

Более подробно описано в документации по структурному анализу. Это даст вам контур всех капель в изображении. В векторе, который обрабатывает другой вектор, который обрабатывает точки на изображении; вот так

vector<vector<Point>> contours;

Мне тоже нужно найти самый большой блоб, и хотя мой подход в какой-то степени может быть ошибочным, мне не нужно, чтобы он был другим. Я использую

minAreaRect() // expects a set of points (contained by the vector or mat classes

Описано также при структурном анализе Затем получите доступ к размеру прямоугольника

int sizeOfObject = 0;
int idxBiggestObject = 0; //will track the biggest object

if(contours.size() != 0) //only runs code if there is any blobs / contours in the image
{
    for (int i = 0; i < contours.size(); i++) // runs i times where i is the amount of "blobs" in the image.
    {
        myVector = minAreaRect(contours[i])
        if(myVector.size.area > sizeOfObject)
        {
             sizeOfObject = myVector.size.area; //saves area to compare with further blobs
             idxBiggestObject = i; //saves index, so you know which is biggest, alternatively, .push_back into another vector
        }
    }
}

Итак, мы действительно измеряем только повернутую ограничивающую рамку, но в большинстве случаев это подходит. Я надеюсь, что вы либо переключитесь на синтаксис c ++, либо получите вдохновение от базового алгоритма.

Наслаждайтесь.

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