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

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

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

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

Код:

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 лучше всего найти край объекта, а не фильтровать его по цветам.
  • Я буду держать объект, чтобы, возможно, мой палец мог заставить кромку объекта измениться или исчезнуть.
  • Я работаю над программой обработки видео, поэтому чем меньше время обработки и чем меньше вычислительная мощность требуется, тем лучше.
  • Моя программа отфильтрует самый большой контур и закрасит его красным цветом (см. Первое изображение).

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

2

Решение

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

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

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]