Перейти к содержимому
Compvision.ru

Доска почета


Popular Content

Showing most liked content on 10.05.2011 во всех областях

  1. 1 point
    У меня программа вылетала с ошибкой "divizion by zero" на строчке: if( !cvFindHomography( &_pt1, &_pt2, &_h, CV_RANSAC, 5 )) Стал искать причину, обнаружил, что функция naiveNearestNeighbor может возвращать одну и ту же точку сколько угодно раз. То есть, для примера, у нас найдено n особенностей для исходного изображения и 1 особенность для изображения с камеры, тогда эта одна точка почему-то будет считаться парой для всех n точек из шаблона. Скорее всего функция naiveNearestNeighbor не очень верно работает (я с ней особо не разбирался), возможно, необходимо добавить туда еще какой-то порог или изменить существующие параметры. Добавил в функцию findPairs вот такую заглушку: if( nearest_neighbor >= 0 && nearest_neighbor != last_neighbor) { ptpairs.push_back(i); ptpairs.push_back(nearest_neighbor); last_neighbor = nearest_neighbor; } Хотя, все равно иногда вылетает та же ошибка (может быть это проблема борландовского компилятора), так что надо туда просто повесить обработчик ошибок и забить. На всякий случай прикрепляю проект для borland builder 6, вдруг кому-то пригодится. OpenCV SURF.rar
  2. 1 point
    Отключите ненужные .lib файлы от проекта, вроде была тема с похожей проблемой.
  3. 1 point
    Недавно меня спросили о коде получившейся программы. Я вот и подумал, что он может пригодиться еще кому то, и хотя эта программа всего лишь переделанный пример из OpenCV архива, под работу с видео. Я ничего не менял касающегося SURF алгоритма, только добавил работу с видео. Программа написана для MV С++. image.bmp - имя файла картинки, которая обводится рамкой. #include <cv.h> #include <highgui.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <vector> #define ZOOM 2 using namespace std; IplImage *image = 0; double compareSURFDescriptors( const float* d1, const float* d2, double best, int length ) { double total_cost = 0; assert( length % 4 == 0 ); for( int i = 0; i < length; i += 4 ) { double t0 = d1[i] - d2[i]; double t1 = d1[i+1] - d2[i+1]; double t2 = d1[i+2] - d2[i+2]; double t3 = d1[i+3] - d2[i+3]; total_cost += t0*t0 + t1*t1 + t2*t2 + t3*t3; if( total_cost > best ) break; } return total_cost; } int naiveNearestNeighbor( const float* vec, int laplacian, const CvSeq* model_keypoints, const CvSeq* model_descriptors ) { int length = (int)(model_descriptors->elem_size/sizeof(float)); int i, neighbor = -1; double d, dist1 = 1e6, dist2 = 1e6; CvSeqReader reader, kreader; cvStartReadSeq( model_keypoints, &kreader, 0 ); cvStartReadSeq( model_descriptors, &reader, 0 ); for( i = 0; i < model_descriptors->total; i++ ) { const CvSURFPoint* kp = (const CvSURFPoint*)kreader.ptr; const float* mvec = (const float*)reader.ptr; CV_NEXT_SEQ_ELEM( kreader.seq->elem_size, kreader ); CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader ); if( laplacian != kp->laplacian ) continue; d = compareSURFDescriptors( vec, mvec, dist2, length ); if( d < dist1 ) { dist2 = dist1; dist1 = d; neighbor = i; } else if ( d < dist2 ) dist2 = d; } if ( dist1 < 0.6*dist2 ) return neighbor; return -1; } void findPairs( const CvSeq* objectKeypoints, const CvSeq* objectDescriptors, const CvSeq* imageKeypoints, const CvSeq* imageDescriptors, vector<int>& ptpairs ) { int i; CvSeqReader reader, kreader; cvStartReadSeq( objectKeypoints, &kreader ); cvStartReadSeq( objectDescriptors, &reader ); ptpairs.clear(); for( i = 0; i < objectDescriptors->total; i++ ) { const CvSURFPoint* kp = (const CvSURFPoint*)kreader.ptr; const float* descriptor = (const float*)reader.ptr; CV_NEXT_SEQ_ELEM( kreader.seq->elem_size, kreader ); CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader ); int nearest_neighbor = naiveNearestNeighbor( descriptor, kp->laplacian, imageKeypoints, imageDescriptors ); if( nearest_neighbor >= 0 ) { ptpairs.push_back(i); ptpairs.push_back(nearest_neighbor); } } } /* a rough implementation for object location */ int locatePlanarObject( const CvSeq* objectKeypoints, const CvSeq* objectDescriptors, const CvSeq* imageKeypoints, const CvSeq* imageDescriptors, const CvPoint src_corners[4], CvPoint dst_corners[4] ) { double h[9]; CvMat _h = cvMat(3, 3, CV_64F, h); vector<int> ptpairs; vector<CvPoint2D32f> pt1, pt2; CvMat _pt1, _pt2; int i, n; findPairs( objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors, ptpairs ); n = ptpairs.size()/2; if( n < 4 ) return 0; pt1.resize(n); pt2.resize(n); for( i = 0; i < n; i++ ) { pt1[i] = ((CvSURFPoint*)cvGetSeqElem(objectKeypoints,ptpairs[i*2]))->pt; pt2[i] = ((CvSURFPoint*)cvGetSeqElem(imageKeypoints,ptpairs[i*2+1]))->pt; } _pt1 = cvMat(1, n, CV_32FC2, &pt1[0] ); _pt2 = cvMat(1, n, CV_32FC2, &pt2[0] ); if( !cvFindHomography( &_pt1, &_pt2, &_h, CV_RANSAC, 5 )) return 0; for( i = 0; i < 4; i++ ) { double x = src_corners[i].x, y = src_corners[i].y; double Z = 1./(h[6]*x + h[7]*y + h[8]); double X = (h[0]*x + h[1]*y + h[2])*Z; double Y = (h[3]*x + h[4]*y + h[5])*Z; dst_corners[i] = cvPoint(cvRound(X), cvRound(Y)); } return 1; } int main(int argc, char** argv) { const char* object_filename = argc == 3 ? argv[1] : "image.bmp"; CvMemStorage* storage = cvCreateMemStorage(0); cvNamedWindow("Object", 1); cvNamedWindow("Object Correspond", 1); static CvScalar colors[] = { {{0,0,255}}, {{0,128,255}}, {{0,255,255}}, {{0,255,0}}, {{255,128,0}}, {{255,255,0}}, {{255,0,0}}, {{255,0,255}}, {{255,255,255}} }; IplImage* object = cvLoadImage( object_filename, CV_LOAD_IMAGE_GRAYSCALE ); IplImage* object_color = cvCreateImage(cvGetSize(object), 8, 3); cvCvtColor( object, object_color, CV_GRAY2BGR ); CvSeq *objectKeypoints = 0, *objectDescriptors = 0; int i; CvSURFParams params = cvSURFParams(500, 1); cvExtractSURF( object, 0, &objectKeypoints, &objectDescriptors, storage, params ); CvPoint src_corners[4] = {{0,0}, {object->width,0}, {object->width, object->height}, {0, object->height}}; CvPoint dst_corners[4]; for( i = 0; i < objectKeypoints->total; i++ ) { CvSURFPoint* r = (CvSURFPoint*)cvGetSeqElem( objectKeypoints, i ); CvPoint center; int radius; center.x = cvRound(r->pt.x); center.y = cvRound(r->pt.y); radius = cvRound(r->size*1.2/9.*2); cvCircle( object_color, center, radius, colors[0], 1, 8, 0 ); } cvShowImage( "Object", object_color ); CvCapture* capture = cvCreateCameraCapture(0); IplImage* frame; //Размеры входного изображения int width = (int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH); int height= (int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT); CvSize size = cvSize(width,height); //Для серого изображения IplImage* image1 = cvCreateImage(size, 8, 1); //Для уменьшенного в ZOOM раз серого изображения IplImage* image2 = cvCreateImage(cvSize((int)(width/ZOOM),(int)(height/ZOOM)), 8, 1); while(1){ frame = cvQueryFrame( capture ); if( !frame ) break; //Делаем входное изображение серым cvCvtColor( frame, image1, CV_RGBA2GRAY ); //Уменьшаем серое изображение cvResize(image1,image2,CV_INTER_LINEAR); CvSeq *imageKeypoints = 0, *imageDescriptors = 0; cvExtractSURF( image2, 0, &imageKeypoints, &imageDescriptors, storage, params ); if( locatePlanarObject( objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors, src_corners, dst_corners )) { //Рисуем линии контура рамки на входном изображении(frame) for( i = 0; i < 4; i++ ) { CvPoint r1 = dst_corners[i%4]; CvPoint r2 = dst_corners[(i+1)%4]; cvLine( frame, cvPoint(r1.x*ZOOM, r1.y*ZOOM), cvPoint(r2.x*ZOOM, r2.y*ZOOM), colors[8] ); } } //Выводим входное изображение(frame) в окно программы cvShowImage( "Object Correspond", frame ); char c = cvWaitKey(33); if( c == 27 ) break; } cvReleaseCapture( &capture ); cvDestroyWindow("Object"); cvDestroyWindow("Object Correspond"); return 0; }
×