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

Spok

Пользователи
  • Количество публикаций

    7
  • Зарегистрирован

  • Посещение

Репутация

0 Новичек

О Spok

  • Звание
    Новичок
  1. Ассемблер, MMX, SSE, CUDA - это явления одного порядка, когда уже ничего другое не помогает. Для CUDA видеокарты нет. Я уж скорее буду на кластере считать, программа всё равно должна синхронизировать внутреннюю базу по сети. По-моему, с этими наиболее значимыми точками - наиболее перспективно. Только порог никак придумать не могу. Порог можно определить только после прогона на всей коллекции, что не имеет смысла. И к площади он не привязан. И к количеству точек. Я потом напишу, как решу (ггг, я оптимист!), если кому-то надо.
  2. Мдя. Вот же задачка... Фрагмент никак не 20x20. Вот, самый маленький реальный: 350x60. Я пока додумался только до двух вещей: 1) "критические точки" - количество мест появления фрагментов огромно, но всяко меньше количества точек в скриншоте; 2) наложил все фрагменты друг на друга и для нашёл вероя... эээ... значимость каждого пикселя в этом фрагменте. Теперь как дурак сижу и думаю, что мне это даст. То есть надо как-то последовательно сверять значимые точки... и тут не могу придумать порог, по которому следует переходить от поиска изображения к принятию решения, что это какой-то фрагмент. Причём какой?............ И почему этот, а не иной.... За скоростью я не гонюсь. Но минута и четыре дня (на тестовой выборке - это принципиально). Задумывался о ИНС, но, я так понимаю, это не мой случай.
  3. Здравствуйте! Сам с OpenCV работаю нечасто и в данном случае задумался о переходе на него, если того будет стоить (проект почти закончен, кроме вот такой закавыки). Задача: Надо на скриншоте поискать кое-какие фрагменты (если они там есть). Фрагменты с этого же скриншота или с одного из тысяч предыдущих (возможны минимальные искажения). Набросав несложную программу на одном из общеизвестных языков программирования получил, что картинка порядка 20x20 пикселей ищется на скриншоте (попиксельно, по RGB компонентам, по методу наименьших квадратов) 1280x800 порядка сорока секунд (тестовая машина, в жизни экран будет больше). А надо где-то пару... десятков... тысяч (или больше...) фрагментов в разумное время (секунды... полминуты максимум). Порыскал по нету, узнал о существовании cvMatchTemplate - оно самое сюда, я так понимаю. Насколько она быстро работает? Хватит ли для моей задачи или мне надо что-нибудь оптимизировать, другое придумывать? Буду благодарен за любые подсказки. P.S. Фрагменты - относительно контрастный текст, но часто и значимая полноцветная графика попадается.
  4. Про преобразование Хафа, в принципе, и так знаю, но третья ссылочка реально понравилась, а на концентрических окружностях я уже обломался Хочу спросить у вас, как у сведущего человека: я правильно уловил, что преобразование Хафа работает с чёрно-белым (бинарным изображением)? И, грубо говоря, меряет расстояние от каждой точки до каждой точки? Если "да", то получается, что в худшем случае сложность будет width*height * width*height (всё белое)... Лично у меня при средне-сильно помеховом изображении (только так, блин, всегда и бывает...) количество помех, оставшихся после подавления в бинарном изображении, приближается к количеству значимых точек. Причём сверху приближается. Кажется, понял свою ошибку. В преобразовании Хафа четвертый порядок - худший случай, а у меня - третий, но всегда. А ваши мысли? Может, нормальную камеру купить? У вас какая? Где-то встречал, что маленькая вебка 352x288...
  5. Весь форум прочитал - примера не нашёл. 1) Нельзя ли как-нибудь посмотреть на этот мифический пример? Гонял на своей супер-камере (352x288-->640x480) - находит тысячи окружностей, если не миллионы. 2) Поэтому вопрос: что можно подкрутить, чтобы повысить вероятность, так сказать, успешного нахождения чего искал, а не всего подряд вокруг шума? Пока возился, придумал и реализовал алгоритм поиска окружностей сложности порядка const*(Rmax-Rmin)*width*height, относительно медленный. 3) Поэтому - где и что можно почитать на предмет поиска окружностей... на изображении низкого качества?
  6. Хм. Дело в ошибке, а не в листинге. Проект - совершенно любой, а исключение возникает в строчке VI.setupDevice(index) в функции bool CvCaptureCAM_DShow::open( int _index ) модуля cvcap_dshow.cpp. Уж если вы так хотите, пожалуйста. Внизу - четыре примера (три закомментировано, но тоже работали, то есть не работали). //#include "stdafx.h" //#include "highgui.h" //int main (int argc, char** argv) //{ //IplImage* img = cvLoadImage( argv[1] ); //cvNamedWindow( "Example1", CV_WINDOW_AUTOSIZE); //cvShowImage( "Example1", img ); //cvWaitKey(0); //cvReleaseImage( &img ); //cvDestroyWindow( "Example1" ); //} /* #include "stdafx.h" #include <cv.h> #include <cxcore.h> #include <highgui.h> #include <iostream> using namespace std; void processFrame(IplImage*& image); int main(int argc, char** argv) { // Инициализируем источник наших изображений. // В данном случае - это видеокамера, подключенная по // одному из интерфейсов. 0 означает, что надо // выбрать первую попавшуюся камеру. У нас их одна, // поэтому не стоит волноваться по этому поводу CvCapture* capture = 0; capture = cvCreateCameraCapture(0); if (!capture) { cout << "Initialization failed" << endl; return EXIT_FAILURE; } // Работа с GUI упрощена до невозможного. Необходимо // определить идентификатор (по совместительству - // заголовок окна), по которому мы будем определять // наши окна. const char *windowName = "First steps with OpenCV"; cvNamedWindow(windowName, CV_WINDOW_AUTOSIZE); while(true) { // Опрашиваем камеру для получения следующего кадра IplImage* frame = cvQueryFrame( capture ); if(!frame) break; // processFrame(frame); // Отобразим наш фрейм в окне (не забыли, как мы его // определили? - через идентификатор) cvShowImage(windowName, frame); // По нажатию ESC - выход из цикла char c = cvWaitKey(33); if (c == 27) break; } // Никогда не забываем освобождать память! cvReleaseCapture( &capture ); cvDestroyWindow(windowName); return 0; } */ #include <windows.h> #include "stdafx.h" #include <cv.h> #include <cxcore.h> #include <highgui.h> #include <iostream> #include "cv.h" #include "highgui.h" using namespace std; float edge_thresh=50; #define WIDTHBYTES(bits) ((((bits) + 31) / 32) * 4) //--------------------------------------------------------------------------- // Создание API шного битмапа из интеловского RGB изображения //--------------------------------------------------------------------------- HBITMAP CreateRGBBitmap(IplImage* _Grab) { char *App; LPBITMAPINFO lpbi = new BITMAPINFO; lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); lpbi->bmiHeader.biWidth = _Grab->width; lpbi->bmiHeader.biHeight =_Grab->height; lpbi->bmiHeader.biPlanes = 1; lpbi->bmiHeader.biBitCount = 24; lpbi->bmiHeader.biCompression = BI_RGB; lpbi->bmiHeader.biSizeImage = WIDTHBYTES((DWORD)_Grab->width * 8) * _Grab->height; lpbi->bmiHeader.biXPelsPerMeter = 0; lpbi->bmiHeader.biYPelsPerMeter = 0; lpbi->bmiHeader.biClrUsed = 0; lpbi->bmiHeader.biClrImportant = 0; void* pBits; HBITMAP hBitmap = CreateDIBSection( NULL, lpbi, DIB_RGB_COLORS, (void **)&pBits, NULL, 0 ); delete lpbi; if ( hBitmap ) App=(char*)pBits; long int length=0; if(_Grab->nChannels==1) // Серое или бинарное { length = _Grab->width*(_Grab->height); for (int i=0;i<_Grab->height;i++) { for (int j=0;j<_Grab->width;j++) { App[_Grab->width*3*(_Grab->height-i-1)+j*3]=_Grab->imageData[_Grab->width*(i)+j]; App[_Grab->width*3*(_Grab->height-i-1)+j*3+1]=_Grab->imageData[_Grab->width*(i)+j]; App[_Grab->width*3*(_Grab->height-i-1)+j*3+2]=_Grab->imageData[_Grab->width*(i)+j]; } } } if(_Grab->nChannels==3) // Цветное { for (int i=0;i<_Grab->height;i++) { // Копируем строчку за строчкой (переворачивая вверх ногами) memcpy(App+_Grab->width*3*(_Grab->height-i-1),_Grab->imageData+_Grab->width*3*i,_Grab->width*3); } } return hBitmap; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // Функция вывода изображения на HANDLE оконного компонента //--------------------------------------------------------------------------- void APIDrawIpl(int x,int y,IplImage* _Grab,void *HANDLE) { HDC hMemDC,hDC; hDC=GetDC((HWND)HANDLE); hMemDC = CreateCompatibleDC(hDC); HBITMAP Bitmap=CreateRGBBitmap(_Grab); SelectObject(hMemDC,Bitmap); BitBlt(hDC,x,y,_Grab->width,_Grab->height,hMemDC,0,0,SRCCOPY); DeleteObject(Bitmap); DeleteDC(hMemDC); DeleteDC(hDC); } IplImage* frame_copy; IplImage* gray; void processFrame(IplImage*& image){ HBITMAP hBmp = CreateRGBBitmap( image ); IplImage *Grab = image; // GetBitmapBits( DeleteObject( hBmp ); cvSaveImage( "p:\\temp.BMP", image); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// CvSeq* lines; CvMemStorage* storage = cvCreateMemStorage(0); cvCvtColor(Grab, gray, CV_BGR2GRAY); // Получаем серый цвет cvSmooth( gray, gray, CV_GAUSSIAN, 9, 9 ); // сгладим, чтобы уменьшить помехи cvThreshold( gray, gray, edge_thresh,255,/*CV_THRESH_BINARY_INV*/CV_THRESH_BINARY); // Нах. границы cvCanny( gray, gray, 20, 1, 3 ); // Собственно здесь линии и выделяются lines = cvHoughLines2( gray, storage, CV_HOUGH_PROBABILISTIC, 2, CV_PI/180, 20, 10, 5 ); for(int i = 0; i < lines->total; i++ ) { CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i); cvLine( Grab, line[0], line[1], CV_RGB(255,0,0), 1, 8 ); } cvReleaseMemStorage(&storage); APIDrawIpl(10,10,Grab, GetForegroundWindow() ); // Рисуем результат APIDrawIpl(Grab->width+10,10,gray, GetForegroundWindow() ); // Рисуем результат //CloseHandle( hBmp ); }; int main(int argc, char** argv) { // Инициализируем источник наших изображений. // В данном случае - это видеокамера, подключенная по // одному из интерфейсов. 0 означает, что надо // выбрать первую попавшуюся камеру. У нас их одна, // поэтому не стоит волноваться по этому поводу CvCapture* capture = 0; capture = cvCreateCameraCapture(0); if (!capture) { cout << "Initialization failed" << endl; return EXIT_FAILURE; } // Работа с GUI упрощена до невозможного. Необходимо // определить идентификатор (по совместительству - // заголовок окна), по которому мы будем определять // наши окна. const char *windowName = "First steps with OpenCV"; cvNamedWindow(windowName, CV_WINDOW_AUTOSIZE); while(true) { // Опрашиваем камеру для получения следующего кадра IplImage* frame = cvQueryFrame( capture ); if(!frame) break; // Даем приказ на захват кадра if( !cvGrabFrame( capture )) goto skip; // Если удачно - получаем кадр frame = cvRetrieveFrame( capture ); if( !frame ) // Если захват не удался - пропускаем дальнейшее goto skip; // Выделяем память под копию кадра if( !frame_copy ) frame_copy = cvCreateImage( cvSize(frame->width,frame->height), IPL_DEPTH_8U, frame->nChannels ); // Выделяем память под серую копию кадра if( !gray ) gray = cvCreateImage( cvSize(frame->width,frame->height), IPL_DEPTH_8U,1); //********************************************************* // Если стерли то что ниже - это надо раскомментировать // frame_copy = cvCreateImage( cvSize(frame->width,frame->height), // IPL_DEPTH_8U, frame->nChannels ); // Делаем копию кадра, иначе может пропасть. // cvCopy( frame, frame_copy, 0 ); // Если стерли то что ниже - это надо раскомментировать //********************************************************* //********************************************************* // Если не нужно подгонять размер кадра - это можно стереть // Выделяем память под копию кадра if( !frame_copy ) frame_copy = cvCreateImage( cvSize(352,288), IPL_DEPTH_8U, frame->nChannels ); // Масштабируем под заданный размер cvResize( frame, frame_copy, CV_INTER_LINEAR ); // Если не нужно подгонять размер кадра - это можно стереть //********************************************************* // Обработка полученного кадра processFrame( frame_copy ); // processFrame(frame); /* IplImage* buf = cvCreateImage( cvSize(640,480), 8, 4); if(!buf) abort(); cvCopyImage(frame,buf); cvSmooth(buf,buf); */ // Отобразим наш фрейм в окне (не забыли, как мы его // определили? - через идентификатор) // cvShowImage(windowName, frame); /* cvShowImage(windowName, buf); // cvReleaseImage(&buf); */ skip: // По нажатию ESC - выход из цикла char c = cvWaitKey(33); if (c == 27) break; } // Никогда не забываем освобождать память! cvReleaseCapture( &capture ); cvDestroyWindow(windowName); return 0; }[/code] P.S. Исключение только в самом первом консольном примере (закомментированном палочками //) - там исключение не возникает. P.P.S. Конечно, спасибо вам за ваш забавный пример HoughLines.rar.
  7. OpenCV 2.0a [DEBUG], MS VSE 9.0.30729.1 SP. Windows Vista SP1. Не идёт приложение, если его запустить из среды (сначала один exception, потом другой...). Трассировка показала, что проблема в cvCreateCameraCapture, внутри неё в cvCreateCameraCapture_DShow, а потом в неизбежном месте, относящемся к, собственно, DirectShow в функции bool CvCaptureCAM_DShow::open( int _index ). Если приложение Win32, то можно два - четыре раза нажать "пропустить" исключение и дальше работа пойдёт как надо. Если приложение CLR, то в конечном итоге всё выльется в неперехваченный SEH-эксепшн (как бы я его не перехватывал...) и приложение завершает свою работу. Если запустить из Windows - всё, конечно же, работает как надо. На форумах видел, что только сталкиваются с проблемой, но решения никто не привёл. Вопрос: кто-нибудь знает, как преодолеть эту проблему и получить возможность отлаживать приложение в среде?
×