Jump to content
Compvision.ru

Smorodov

Главные администраторы
  • Content count

    3,833
  • Joined

  • Last visited

  • Days Won

    343

Everything posted by Smorodov

  1. В руководстве описана процедура калибровки камер, доска для калибровки в аттаче. pattern.pdf
  2. Для любителей классики, старая версия OpenCV 1.0 от Intel: OpenCV_1.0.rar
  3. Цитата(FormatCft @ 30.4.2009, 0:35) Доброго времени суток! Допустим есть такая задачка: Есть набор разкиданных по столу объектов. Каждый объект имеет свою форму и надпись. Надпись может быть едва читаема. Нужно разпознать каждый из объектов и поместить каждый объект в своё определеное место. Легко ли такая задача реализуема? Меня интересует прежде всего вопросы написания ПО для PC. Хотя физическая реализация "манипулятора" тоже интересует. Спасибо! Доброго времени суток. Есть такой проектик: ContourMatching.rar Проект находит контуры и выводит степень их похожести, сравнение идет с первым найденным контуром см картинку. Код //--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "cv.h" #include "highgui.h" #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; CvCapture* capture = 0; IplImage *frame, *frame_copy,*gray = 0; void ProcessFrame( IplImage* image ); int Val=100,Val1=100; // Значение переменной (для разных нужд) CvFont font; // Описатель шрифта (см. дальше) float edge_thresh=100; #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(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); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { capture = cvCaptureFromCAM(0); // Инициализация шрифта (теперь можем вывести какой-нибудь текст) cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX,0.5,0.5,0,1,8); Application->OnIdle = IdleLoop; // Поток обработки простоя } //--------------------------------------------------------------------------- void __fastcall TForm1::IdleLoop(TObject*, bool& done) { done = false;// Поток обработки простоя if( capture ) { 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); if( frame->origin == IPL_ORIGIN_TL ) cvCopy( frame, frame_copy, 0 ); else cvFlip( frame, frame_copy, 0 ); ProcessFrame( frame_copy ); } skip:; } //--------------------------------------------------------------------------- void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action) { cvReleaseImage( &frame_copy ); cvReleaseCapture( &capture ); } //--------------------------------------------------------------------------- void ProcessFrame( IplImage* Grab ) { float XC[1000]={0}; float YC[1000]={0}; float S[1000]={0}; double mt=0; int ID=0; int NumCont=0; int NumCont1=0; CvMemStorage* storage = 0; CvSeq* contours; CvSeq* Templ; CvSeq* result; storage = cvCreateMemStorage(0); CvSeq* polygons = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvPoint), storage ); CvMoments moments; cvCvtColor(Grab, gray, CV_BGR2GRAY); // Получаем серый цвет if(Form1->CheckBox1->Checked) {cvThreshold( gray, gray, Val,255,CV_THRESH_BINARY_INV);} else {cvThreshold( gray, gray, Val,255,CV_THRESH_BINARY);} // Необходимо удалить белый бордюр cvRectangle(gray, cvPoint(0,0), cvPoint(gray->width-1,gray->height-1),CV_RGB(0,0,0)); // Утолщаем контуры cvDilate( gray, gray, 0, 1 ); // Нах. границы cvCanny( gray, gray, 50, Val1, 5 ); // Нах. контуры cvFindContours( gray, storage,&contours,sizeof(CvContour),CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0)) ; //-------------- if(contours!=0) { NumCont=contours->total; // количество найденных контуров } int NC=0; for(;contours!=0;contours = contours->h_next) { // Аппр. контуров полигонами result = cvApproxPoly( contours, sizeof(CvContour), storage,CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.001, 0 ); // Площадь полигона double area=fabs(cvContourArea(result,CV_WHOLE_SEQ)); // Объявление читалки точек CvSeqReader reader; // Инициализация читалки точек cvStartReadSeq( result, &reader, 0 ); // Две точки CvPoint pt[2]; if(area>500) { // Вычисляем моменты cvMoments( result, &moments); // Центр тяжести float xc=(moments.m10/moments.m00); float yc=(moments.m01/moments.m00); // Обрубаем клонов bool ok=1; for (int o=0;o<NC;o++) { if( ((xc-XC[o])*(xc-XC[o])+(yc-YC[o])*(yc-YC[o]))<10 && fabs((area-S[o])/(area+S[o]))<0.3){ok=0;} } // if(ok){ // Запоминаем шаблон if(NumCont1==0) {Templ=cvCloneSeq(result);} // Сравниваем с найденными контурами mt=cvMatchShapes( Templ, result,CV_CONTOURS_MATCH_I3); NumCont1++; double M00=moments.m00; double M20=moments.m20; double M02=moments.m02; double M11=moments.m11; double A=(M20/M00)-xc*xc; double B=2*((M11/M00)-xc*yc); double C=(M02/M00)-yc*yc; double LL=sqrt( ( (A+C)+sqrt(B*B+(A-C)*(A-C)) )/2)*2; double LW=sqrt( ( (A+C)-sqrt(B*B+(A-C)*(A-C)) )/2)*2; // Для вычисления угла нужны центральные моменты инерции M20=moments.mu20; M02=moments.mu02; M11=moments.mu11; double theta=(atan2(2*M11,(M02-M20))/2)*(180/M_PI); // Отмечаем центр cvCircle( Grab, cvPoint(xc,yc), 3, CV_RGB(0,255,255), -1, 8, 0 ); cvPutText( Grab,(FloatToStrF(mt,ffGeneral,4,3)).c_str(), cvPoint(xc,yc),&font, CV_RGB(255,255,0)); // Достаем точки из хранилища точек и рисуем линии for (int i=0;i<result->total-1;i++) { CV_READ_SEQ_ELEM( pt[0], reader ); CV_READ_SEQ_ELEM( pt[1], reader ); if(mt>0.5){cvLine(Grab,pt[0],pt[1],CV_RGB(255,0,0));} else{cvLine(Grab,pt[0],pt[1],CV_RGB(0,255,0));} } } XC[NC]=xc; YC[NC]=yc; S[NC]=area; NC++; } // if } // for cvPutText( Grab,("NCont1="+FloatToStrF(NumCont1,ffGeneral,4,3)).c_str(), cvPoint(20,5),&font, CV_RGB(255,255,0)); //----------------------------------------------------------------------------- APIDrawIpl(10,10,gray,Form1->Handle); // Рисуем результат APIDrawIpl(10+Grab->width,10,Grab,Form1->Handle); // Рисуем результат cvReleaseMemStorage(&storage); } void __fastcall TForm1::TrackBar1Change(TObject *Sender) { Val=TrackBar1->Position; edge_thresh=float(Val); } //--------------------------------------------------------------------------- void __fastcall TForm1::TrackBar2Change(TObject *Sender) { Val1=TrackBar2->Position; } //---------------------------------------------------------------------------[/code]
  4. Как прикрутить OpenCV к билдеру?

    Создание нового проекта в среде C++ Builder 6. (Для OpenCV v1.1) Библиотеки * cv.lib * cvaux.lib * cvhaartraining.lib * cxcore.lib * cxts.lib * Half.lib * highgui.lib * Iex.lib * IlmImf.lib * IlmThread.lib * Imath.lib * libjasper.lib * libjpeg.lib * libjpeg_bcc.lib * libpng.lib * libpng_bcc.lib * libtiff.lib * libtiff_bcc.lib * ml.lib * videoInput.lib * zlib.lib * zlib_bcc.lib короче все файлы из директории OpenCV с расширением lib, необходимо сконвертировать при помощи утилиты coff2omf.exe лежащей в поддиректории /bin директории, где у Вас установлен C++ Builder 6 (или LibConverter см. в прикрепленных ниже файлах) Конвертация необходима ввиду того, что в OpenCV библиотеки с расширением .lib сделаны для использования с Microsoft Visual C. Подключить сконвертированные библиотеки проекту (Меню Project -> Add to project). Еще нужно указать пути к заголовочным файлам библиотеки OpenCV, делается это на вкладке Directories/Conditionals, диалога Options вызываемого выбором пункта меню Project. Эти файлы расположены в нескольких поддиректориях директории в которую Вы поставили OpenCV.Например для OpenCV v1.1 это директории представленные ниже. * C:\Program Files\OpenCV\cv\include * C:\Program Files\OpenCV\cvaux\include * C:\Program Files\OpenCV\cxcore\include * C:\Program Files\OpenCV\ml\include * C:\Program Files\OpenCV\otherlibs\_graphics\include * C:\Program Files\OpenCV\otherlibs\ffopencv * C:\Program Files\OpenCV\otherlibs\highgui Побросать все сконвертированные lib файлы в директорию libs проекта (или другую) и указать путь к этой нашей директории аналогично тому, как это сделано для заголовочных файлов. Чекбокс Use dynamic RTL на вкладке Linker должен быть установлен, иначе требует несуществующую haartraining.dll Чекбокс Build with runtimre packages тоже должем быть установлен, иначе требует ilmthread.dll (тоже не знаю где взять). Так же рекомендуется установить флажок MFC compatibility, это необходимо для правильной работы функции cvGetSize(). И не забудте что DLL должны быть в зоне видимости программы. Приведенный ниже пример использует библиотеку OpenCV v1.1. Проект просто выводит захваченное видео в форму в соответствии с заданными координатами, в данном случае x=10, y=10 И еще если возникает ошибка 0xc0150002, то для корректной работы OpenCV1.1pre1 надо установить MSVCRT 8.0 (visual c++ run time). MSVCRT8.0 *Архив с проектом:simple.rar *Конвертер библиотек:LibConverter.rar *Набор сконвертированных lib:libs.rar *Набор DLL (на всякий случай):OpenCV11DLLs.rar //--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "cv.h" #include "highgui.h" #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; CvCapture* capture = 0; IplImage *frame, *frame_copy = 0; void ProcessFrame( IplImage* image ); // Описатель шрифта (см. дальше) CvFont font; #define WIDTHBYTES(bits) ((((bits) + 31) / 32) * 4) //--------------------------------------------------------------------------- // Создание API шного битмапа из интеловского RGB изображения //--------------------------------------------------------------------------- HBITMAP CreateRGBBitmap(IplImage* _Grab) { char *App; IplImage *_Grab3=0,*_Grabf=0; 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; // Если глубина изображения не IPL_DEPTH_8U (однобайтовое целое), конвертируем if(_Grab->depth!=IPL_DEPTH_8U) { _Grabf=cvCloneImage(_Grab); if(_Grab) {cvReleaseImage( &_Grab);} _Grab = cvCreateImage( cvSize(_Grabf->width,_Grabf->height),IPL_DEPTH_8U,_Grabf->nChannels); cvConvert(_Grabf,_Grab); if(_Grabf) {cvReleaseImage( &_Grabf);} } // Если изображение содержит один канал, создаем трехканальное изображение // Серое или бинарное if(_Grab->nChannels==1) { _Grab3 = cvCreateImage( cvSize(_Grab->width,_Grab->height),IPL_DEPTH_8U,3); cvMerge(_Grab,_Grab,_Grab,NULL,_Grab3); } // Если входное изображение трехканальное, просто копируем указатель на него // Цветное if(_Grab->nChannels==3) { _Grab3=_Grab; } // Получаем указатель на данные unsigned char* data; cvGetRawData(_Grab3, (uchar**)&data); // Копируем данные if(_Grab3) { for (int i=0;i<_Grab->height;i++) { memcpy(App+_Grab3->widthStep*(_Grab3->height-i-1),data+_Grab3->widthStep*i,_Grab3->width*3); } } // Очищаем память если создавали изображение, а не копировали указатель if(_Grab->nChannels==1) {cvReleaseImage( &_Grab3);} return hBitmap; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // Функция вывода изображения на HANDLE оконного компонента //--------------------------------------------------------------------------- void APIDrawIpl(int x,int y,IplImage* _Grab,void *HANDLE) { HDC hMemDC,hDC; hDC=GetDC(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); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { capture = cvCaptureFromCAM(0); // Инициализация шрифта (теперь можем вывести какой-нибудь текст) cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX,0.5,0.5,0,1,8); Application->OnIdle = IdleLoop; // Поток обработки простоя } //--------------------------------------------------------------------------- void __fastcall TForm1::IdleLoop(TObject*, bool& done) { done = false;// Поток обработки простоя if( capture ) { 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 ); // Делаем копию кадра, иначе может пропасть. // 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 ); } skip:; } //--------------------------------------------------------------------------- void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action) { cvReleaseImage( &frame_copy ); cvReleaseCapture( &capture ); } //--------------------------------------------------------------------------- void ProcessFrame( IplImage* img ) { APIDrawIpl(10,10,img,Form1->Handle); }[/code]
×