本文介绍了在视频节目边缘过滤器更好的算法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我还在工作的虽然我终于找到了如何解决问题(关于如何过滤最大的轮廓),我现在有一个新的问题,或者说有问题。

I'm still working on the last program and although I finally found out how to solve the problem (on how to filter the biggest contour), I now have a new question, or rather a problem.

正如你可以看到我使用Canny算子在视频搜索的边缘。但我会为检测使用对象没有特别的颜色,所以当物体的颜色是大致相同周围的颜色(例如,如果对象是银,背景为白色)对象的边缘就会消失,我不能让对象的轮廓。

As you can see I am using Canny algorithm for searching the edges in the video. But the object I will using for the detection has no particular color so when the object's color is about the same as the surrounding's color (for example if the object is silver and the background is white) the object's edge will disappear and I cannot get the object's contour.

现在我将测试在OpenCV中提供,但把我的工作很短的每条边滤波算法,我需要你帮忙推荐的最好的(或至少是更好)算法比精明。现在,我已经测试索贝尔但结果并不比精明的要好。如果可能的话,请联系我一些很好的例子,以供参考。

For now I will test every edge filtering algorithm available in OpenCV but to cut my work short, I need your help to recommend the best(or at least better) algorithm than canny. Now I have tested Sobel but the result is no better than canny's. If possible, please link me to some good example for reference.

在code:

int main( int argc, char** argv )
{
CvCapture *cam;
CvMoments moments;
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* contours = NULL;
CvSeq* contours2 = NULL;
CvPoint2D32f center;
int i;

cam=cvCaptureFromCAM(0);
if(cam==NULL){
    fprintf(stderr,"Cannot find any camera. \n");
    return -1;
}
while(1){
    IplImage *img=cvQueryFrame(cam);
    if(img==NULL){return -1;}
    IplImage *src_gray= cvCreateImage( cvSize(img->width,img->height), 8, 1);
    cvCvtColor( img, src_gray, CV_BGR2GRAY );
    cvSmooth( src_gray,  src_gray, CV_GAUSSIAN, 5, 11);
    cvCanny(src_gray, src_gray, 70, 200, 3);

    cvFindContours( src_gray, storage, &contours, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE, cvPoint(0,0));
    if(contours==NULL){ contours=contours2;}
    contours2=contours;
    CvSeq* current_contour = contours;
    double largestArea = 0;
    CvSeq* largest_contour = NULL;
    while (current_contour != NULL){
        double area = fabs(cvContourArea(current_contour,CV_WHOLE_SEQ, false));       
        if(area > largestArea){
            largestArea = area;
            largest_contour = current_contour;
        }
        current_contour = current_contour->h_next;
    }

    cvMoments(largest_contour, &moments, 1);

    double m_00 = cvGetSpatialMoment( &moments, 0, 0 );
    double m_10 = cvGetSpatialMoment( &moments, 1, 0 );
    double m_01 = cvGetSpatialMoment( &moments, 0, 1 );
    float gravityX = (m_10 / m_00)-150;
    float gravityY = (m_01 / m_00)-150;
    if(gravityY>=0&&gravityX>=0&&m_00>=3000){
        printf("center point=(%.f, %.f), Area = %.f \n",gravityX,gravityY,m_00); }


    if(m_00>=3000){
        CvScalar color = CV_RGB(250,0,0);
        cvDrawContours(img,largest_contour,color,color,-1,-1, 8, cvPoint(0,0));
    }

    cvShowImage( "Input", img );
    cvShowImage( "Contours", src_gray );
    cvClearMemStorage(storage);
    if(cvWaitKey(33)>=0) break;
}
cvDestroyWindow("Contours");
cvDestroyWindow("Source");
cvReleaseCapture(&cam);
}

...最后,期待已久的例子图片:

...and finally, the long waited example pictures:

首先,好的(我的黑皮夹)

First, the good one(my black wallet)

其次,故障(橙色框)

Second, the failure(an orange box)

和最后,再次失败(白框)

And last, another failure(a white box)

P.S,一些注意事项:

P.S., Some notes:


  • 的对象没有特定的形状,颜色或大小,所以IMO最好的办法是找到对象的边缘,而不是颜色过滤它。

  • 我将持有的对象,所以也许我的手指可以使物体的边缘改变或消失。

  • 我工作的一个视频处理程序所以处理时间越短,需要较小的处理能力,更好的。

  • 我的程序会过滤掉最大的轮廓,并用红色(见第一张图片)填充它。

在此先感谢。干杯

推荐答案

您的问题不是边缘检测算法。你的问题是,你是硬编码的算法参数,期待它神奇地为你扔在所有图像的工作。此外,使用前平滑图像 cvCanny 是不必要的,因为Canny算子已经进行平滑你。

Your problem isn't the edge detection algorithm. Your problem is that you are hard-coding the algorithm parameters and expecting it to magically work for all images you throw at it. Also, smoothing the image before using cvCanny is unnecessary, as the Canny operator already performs smoothing for you.

由于它是更清楚现在要达到的目标位,我可以给一个建议:工作与视频,而不是在每一帧单独看。如果照相机是固定的,与对象的手正在移动,则检测该形状是通过。如果相机是不固定的,你仍然可以( PDF链接)和工作从那里。此外,使用任何其他应用程序特定知识可能具有(例如项目将在屏幕中间,用手将项目下方)。

Since it's a bit more clear what you want to achieve now, I can give a suggestion: work with the video instead of looking at each frame individually. If the camera is fixed, and the hand with the object is moving, then detecting the shape is trivial through background subtraction. If the camera is not fixed, you can still detect the hand (PDF link) and work from there. Also, use any other application-specific knowledge you may possess (e.g. item will be in the middle of the screen, hand will be below the item).

这篇关于在视频节目边缘过滤器更好的算法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-15 21:43