Как извлечь четкие контуры в видео с помощью библиотеки openCV - PullRequest
1 голос
/ 28 декабря 2011

Привет всем, у меня возникли проблемы с извлечением четких контуров из видео.На данный момент контуры выглядят как большой беспорядок.Шаги, которые я выполняю, следующие:

  1. Возьмите видео в качестве ввода
  2. Преобразуйте его в оттенки серого
  3. Установите порог в двоичный файл
  4. Найтиконтуры с помощью cvFindContours ()
  5. Проходить по контурам и рисовать их с помощью cvDrawContours

Код ниже:

IplImage *inFrame;
IplImage *outFrame = cvCreateImage(cvSize(width,height),IPL_DEPTH_8U,3);
CvScalar inPixel, outPixel;

//J.M ================================================//
CvMemStorage *mem = cvCreateMemStorage(0), *polymem = cvCreateMemStorage(0);
CvSeq *contours = NULL, *ptr = NULL, *poly = NULL, *convex_hull = NULL;
IplImage *cc_color = cvCreateImage(cvGetSize(outFrame), IPL_DEPTH_8U, 3);
CvScalar externalColor = CV_RGB( 255, 252, 0 );
CvScalar holeColor = CV_RGB( 255, 0, 0 );
CvFont font;
int contourNum = 0;
//=========================================================================//

frame_no = 0;
processingVideo = true;
this->GetDlgItem(IDC_STOP)->EnableWindow(true);

CString title = "Video Processing";
cvNamedWindow(title, CV_WINDOW_AUTOSIZE);

CvVideoWriter *writer = cvCreateVideoWriter(pathOutVideo,CV_FOURCC('I', 'Y', 'U', 'V'),video->getFPS(),cvSize(width,height),1);

// variables for counting time
clock_t begin, current;
long int secs, rem_secs, t1, t2;
begin = clock();

while(inFrame=cvQueryFrame(video->getCapture()))
{
    if(!processingVideo)
        break;

    // close opencv window?
    if(cvGetWindowHandle(title)==NULL)
        break;

    //==============================================================================================//

    /*Create gray-scale image*/
    IplImage *im_gray = cvCreateImage(cvGetSize(outFrame), IPL_DEPTH_8U, 1);
    cvCvtColor(inFrame, im_gray, CV_RGB2GRAY);
    outFrame = im_gray;

    /*Convert gray-scale image to binary*/
    IplImage* img_bw = cvCreateImage(cvGetSize(im_gray), IPL_DEPTH_8U, 1); 
    cvThreshold(im_gray, img_bw, 128, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);
    outFrame = img_bw;

    contourNum = cvFindContours(outFrame, mem, &contours, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));

    /* I have tried using convex_hull but with no success
    convex_hull = cvConvexHull2( contours, polymem, CV_CLOCKWISE, 2 ); 
    poly = cvApproxPoly(convex_hull, sizeof(CvContour), polymem, CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.02, 0); 
    float size = fabs(cvContourArea( poly, CV_WHOLE_SEQ )); */

    for (ptr = contours; ptr != NULL; ptr = ptr->h_next) {
            cvDrawContours(cc_color, ptr, externalColor, holeColor, -1, CV_FILLED, 8, cvPoint(0,0));
    }

    outFrame = cc_color;
    //==============================================================================================//

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

  1. исходный видеовход (http://imageshack.us/photo/my-images/823/sourcevideo.jpg/)
  2. полутоновое видео (http://imageshack.us/photo/my-images/23/grayscalei.jpg/)
  3. двоичное видео(http://imageshack.us/photo/my-images/684/binaryi.jpg/)
  4. конечный контурный вывод (http://imageshack.us/photo/my-images/35/finaloutput.jpg/)

Если вам нужна дополнительная информация, просто скажите :) Мне было интересно, если кто-нибудьиз вас, ребята, можете дать мне несколько советов о том, как поступить или что я делаю неправильно.Спасибо !!!

1 Ответ

0 голосов
/ 31 декабря 2011

Ваш Step: 3 Threshold it to binary нуждается в некотором улучшении. Я думаю, вы хотите, чтобы контуры были нарисованы вокруг семантически значимых объектов. В этом случае, поскольку одни и те же значения уровня серого являются частью многих объектов, результирующее изображение не является точной мерой границы объекта.

Что вам нужно, так это попробовать методы сегментации, такие как алгоритмы водораздела или алгоритмы роста регионов. Есть много реализаций в самом OpenCV.

...