Как узнать место положения выделенной точки? Мне нужно узнать координаты x и y.
Код:
//---------------------------------------------------------------------------
#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;
IplImage *gray = 0;
/*
IplImage *frame_green = 0;
IplImage *frame_blue = 0;
*/
int Val=0,Val1=0; // Значение переменной (для разных нужд)
// Описатель шрифта (см. дальше)
CvFont font;
TStringList *Lst;
float edge_thresh=1;
void ProcessFrame( IplImage* image );
#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);
//*********************************************************
// Если стерли то что ниже - это надо раскомментировать
// 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 );
cvReleaseImage( &gray );
cvReleaseCapture( &capture );
}
//---------------------------------------------------------------------------
void ProcessFrame( IplImage* Grab )
{
float XC[1000]={0};
float YC[1000]={0};
float S[1000]={0};
int ID=0;
int NumCont=0;
int NumCont1=0;
CvMemStorage* storage = 0;
CvSeq* contours;
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, 0, 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){
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(NumCont1,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 );
cvLine(Grab,pt[0],pt[1],CV_RGB(255,0,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,14),&font, CV_RGB(255,255,0));
//-----------------------------------------------------------------------------
APIDrawIpl(10,10,Grab,Form1->Handle); // Рисуем результат
APIDrawIpl(Grab->width+10,10,gray,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;
}
//---------------------------------------------------------------------------