Лучший алгоритм для граничного фильтра в видео программировании

я все еще работаю надпоследняя программа и хотя я наконец-то узнал, как решить проблему (о том, как отфильтровать самый большой контур), у меня теперь есть новый вопрос, или, скорее, проблема.

Как вы видите, я использую алгоритм Канни для поиска краев в видео. Но объект, который я буду использовать для обнаружения, не имеет определенного цвета, поэтому, когда объектцвет примерно такой же, как окружающийs цвет (например, если объект серебряный, а фон белый)Край исчезнет, и я не могу получить объектконтур.

Сейчас я протестирую каждый алгоритм реберной фильтрации, доступный в OpenCV, но чтобы сократить мою работу, мне нужна ваша помощь, чтобы рекомендоватьлучший (или, по крайней мере, лучший) алгоритм, чем хитрый, Сейчас я проверил Собель, но результат не лучше, чем canny 's. Если возможно, пожалуйста, свяжите меня с хорошим примером для справки.

Код:

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);
}

... и наконец, долгожданный пример картинки:

Во-первых, хороший (мой черный кошелек)

Во-вторых, сбой (оранжевая коробка)

И, наконец, еще один сбой (белая коробка)

П.С., некоторые заметки:

У объекта нет определенной формы, цвета или размера, поэтому IMO лучше всего найти край объекта, а не фильтровать его по цветам.Я буду держать объект, так что, возможно, мой палец может вызвать объектКрай, чтобы изменить или исчезнуть. ЯЯ работаю над программой обработки видео, поэтому чем меньше время обработки и чем меньше вычислительная мощность требуется, тем лучше.Моя программа отфильтрует самый большой контур и закрасит его красным цветом (см. Первое изображение).

Заранее спасибо. ура

 mpenkov19 окт. 2012 г., 12:53
Вашему вопросу действительно нужны примеры изображений. Без них кажется, что вы хотите обнаруживать края в тех случаях, когда края не существуют, что немного нелепо. Кстати, Canny использует Sobel в качестве промежуточного шага, поэтому результаты обязательно будут похожими.
 Samir Izmier Chong22 окт. 2012 г., 08:44
Уже сделал это. Спасибо за напоминание

Ответы на вопрос(1)

Решение Вопроса

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

С тех пор'Чуть более ясно, чего вы хотите достичь сейчас, я могу предложить: работайте с видео, а не смотрите на каждый кадр отдельно. Если камера зафиксирована, и рука с объектом движется, то определение формы тривиальновычитание фона, Если камера не зафиксирована, вы все равно можетеобнаружить руку (PDF ссылка) и работа оттуда. Кроме того, используйте любые другие знания, относящиеся к конкретному приложению, которыми вы можете обладать (например, предмет будет находиться в центре экрана, рука будет находиться под предметом).

 Samir Izmier Chong24 окт. 2012 г., 11:20
Спасибо за предложения. Я уже пробовал фоновую функцию вычитания, и она отлично работает без определения контура. Но когда я добавил функцию поиска контура, программа вылетает (начальный NULL-указатель для проблемы контура). Кроме того, объект должен быть статическим для расчета положения, поэтому, когда объект не движется, контур не будет обнаружен (если программа нет вылетает).

Ваш ответ на вопрос