вторник, 31 июля 2012 г.

cvblob ( Qt framework)

Блоб (Binary Large OBject — blob) представляет собой скопление связанных пикселов изображения. Существует библиотека cvBlobsLib, которая предоставляет функции для работы с блобами. 
Попробуем применить её в связке с Qt. Для этого скачаем последнюю актуальную версию для Linux (даже если вы работаете в системе windows), скомпилируем статическую библиотеку. Для этого добавим в профайл 
CONFIG += staticlib 
и добавив следующие подключения (возможно есть лишние, позже отредактирую)
INCLUDEPATH += D:\\dev\\opencv\\include
INCLUDEPATH += D:\\dev\opencv\\include\\opencv
INCLUDEPATH += D:\\dev\opencv\\mingw32\\install\\include
INCLUDEPATH += D:\\dev\\opencv\\build\\x64\\mingw\\bin
INCLUDEPATH += D:\\cvblobs8.3_linux
LIBS += D:\\opencv\\libopencv_core231.dll
LIBS += D:\\opencv\\libopencv_highgui231.dll
LIBS += D:\\opencv\\libopencv_imgproc231.dll
LIBS += D:\\opencv\\libopencv_flann231.dll
LIBS += D:\\opencv\\libopencv_features2d231.dll
LIBS += D:\\opencv\\libopencv_calib3d231.dll
LIBS += D:\\opencv\\libopencv_video231.dll
LIBS += D:\\opencv\\libopencv_legacy231.dll
LIBS += D:\\opencv\\libopencv_ml231.dll
LIBS += D:\\opencv\\libopencv_objdetect231.dll
LIBS += D:\\opencv\\libopencv_contrib231.dll
После компиляции получим файл с расширением .a (название зависит от название проекта). Для удобства скопируем библиотеку в отдельную папку, например, в D:\libs.
Теперь рассмотрим examples-пример. Создадим новый консольный проект и не забудем добавить LIBS += D:\\libs\\libblobsLib.a.

#include <QtCore/QCoreApplication>
#include<QDebug>
#include "opencv/cv.h"
#include "opencv/highgui.h"
#include <stdio.h>
#include "BlobResult.h"

char wndname[] = "Blob Extraction";
char tbarname1[] = "Threshold";
char tbarname2[] = "Blob Size";

// The output and temporary images
IplImage* originalThr = 0;
IplImage* original = 0;
IplImage* displayedImage = 0;

int param1,param2;
CvFont font;

//initilize font
void init_font()
{
 cvInitFont(&font, CV_FONT_NORMAL,0.5,0.5,0,1,8);
}

// threshold trackbar callback
void on_trackbar( int dummy )
{
 if(!originalThr)
 {
 originalThr = cvCreateImage(cvGetSize(original), IPL_DEPTH_8U,1);
 }
 if(!displayedImage)
 {
 displayedImage = cvCreateImage(cvGetSize(original), IPL_DEPTH_8U,3);
 }
  
 // gaussianBlur
 cvSmooth(original, originalThr, CV_GAUSSIAN, 5, 5);
  
 // threshold input image
 cvThreshold( originalThr, originalThr, param1, 255, CV_THRESH_BINARY);
 // get blobs and filter them using its area
  CBlobResult blobs;
 int i;
 CBlob *currentBlob;

 // find blobs in image
 blobs = CBlobResult( originalThr, NULL, 0 );
 blobs.Filter( blobs, B_EXCLUDE, CBlobGetArea(), B_LESS, param2 );
 // display filtered blobs
 cvMerge( originalThr, originalThr, originalThr, NULL, displayedImage );
 for (i = 0; i < blobs.GetNumBlobs(); i++ )
 {
 currentBlob = blobs.GetBlob(i);
 double xc=(currentBlob->Moment(1,0)/currentBlob->Moment(0,0));
 double yc=(currentBlob->Moment(0,1)/currentBlob->Moment(0,0));
 double equation =currentBlob->Area()/currentBlob->Perimeter();
 currentBlob->FillBlob( displayedImage, CV_RGB(100,0,0));
 cvCircle( displayedImage, cvPoint(xc,yc),3, CV_RGB(0,255,255), -1, 8, 0 );
 cvPutText(displayedImage,QString::number(equation ,'f',2).toStdString().c_str(), cvPoint(xc,yc),&font, CV_RGB(255,255,0));
 }
 cvShowImage( wndname, displayedImage );
}

void update_view()
{
 for(;;)
 {
 int c;
 on_trackbar(0);
 c = cvWaitKey(0);
 if( c == 27 )
 break;
 }
}

int main(int argc, char *argv[])
{
 QCoreApplication a(argc, argv);
 param1 = 30;
 param2 = 20;
 init_font();
 QString dirPath=QCoreApplication::applicationDirPath();
 dirPath.replace("/","\\");
 original = cvLoadImage(QString(dirPath+"\\image.bmp").toStdString().c_str(),0);
 cvNamedWindow(wndname, CV_WINDOW_AUTOSIZE);
 cvCreateTrackbar( tbarname1, wndname, &param1, 255, on_trackbar );
 cvCreateTrackbar( tbarname2, wndname, &param2, 100, on_trackbar );
 update_view();// Call to update the view
 cvReleaseImage( &original );
 cvReleaseImage( &originalThr );
 cvReleaseImage( &displayedImage );
 cvDestroyWindow( wndname );
 a.exec();
}
Данный пример демонстрирует работу с блобами. Для изображения image.bmp, находящегося в папке .exe программы, выделяет объекты (в зависимости от значений порога бинаризации и минимального размера блоба в пикелях) и для блобов, отвечающих параметрам порога и минимального размера, отмечает отношение площади к периметру.

Результат работы программы
Если есть вопросы с удовольствием на них отвечу.

вторник, 17 июля 2012 г.