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