image-processing - 如何使用openCV库提取视频中的清晰轮廓

大家好,我在从视频中提取清晰轮廓时遇到了一些问题。目前,轮廓看起来像一团糟。我正在执行的步骤是:

  • 将视频作为输入
  • 将其转换为灰度的
  • 将其阈值设置为二进制
  • 使用cvFindContours()查找轮廓
  • 遍历轮廓并使用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;
        //==============================================================================================//
    

    我还提供了各个步骤结果的图像实例。
  • 源视频输入(http://imageshack.us/photo/my-images/823/sourcevideo.jpg/)
  • 灰度视频(http://imageshack.us/photo/my-images/23/grayscalei.jpg/)
  • 二进制视频(http://imageshack.us/photo/my-images/684/binaryi.jpg/)
  • 最终轮廓输出(http://imageshack.us/photo/my-images/35/finaloutput.jpg/)

  • 如果您需要更多信息,请说:)
    我想知道你们中的每个人是否可以给我一些建议,例如如何进行或做错了什么。谢谢 !!!

    最佳答案

    您的Step: 3 Threshold it to binary 需要一些改进。我认为您希望在语义上有意义的对象周围绘制轮廓。在这种情况下,由于相同的灰度值是许多对象的一部分,因此生成的图像不是对象边界的准确度量。

    您需要尝试分割方法-例如分水岭算法或区域增长算法。 OpenCV本身有很多实现。

    https://stackoverflow.com/questions/8649245/

    相关文章:

    opencv - C++ Eclipse OpenCV : . 生成了 exe 文件和二进制文件,但

    android - Android:BitmapFactory.decodeFile/OpenCV确

    image-processing - 读取 RGBA 图像 OpenCV

    opencv - 我可以在POSIT + OpenCV中使用mm吗?

    opencv - cvBlobsLib 的特征向量和特征值

    iphone - openCV CvSVM::save为iPhone生成太大的文件

    opencv - 在opencv中未检测到网络摄像头

    android - 1 channel iplimage -> Android 位图

    android - Android OpenCV手势识别

    windows - OpenCV捕获的视频比实时运行的快吗?