procedure TFrmMain.BtnFreeManClick(Sender: TObject);
var
oImg, oImg2, oImg3: PIplImage;
contours: PCvSeq;
p: Pchar;
pSeq: PCvSeq;
oMem: TCvMemStorage;
I, nCnt, nMaxArea, total: Integer;
stor: pCvMemStorage;
cont: pCvSeq;
pnt:CvPoint;
sFileName: string;
pChain: PCvChain;
nDistance: Integer;
nDelay: Integer;
IsDeflection: Boolean;
seqReader: CvSeqReader;
pChainReader: PCvChainPtReader;
chainReader: CvChainPtReader;
c: PCvChain;
arr: TIntegerArr;
aPoints: array of CvPoint2D32f;
pS: PSingle;
box: CvBox2D;
pointMat: PCvMat;
aboxPoint: array[0..3] of CvPoint2D32f;
lines_header: CvSeq;
lines_block: CvSeqBlock;
lines: PCvSeq;
begin
Randomize;
nMaxArea := 0;
OpenDialog1.InitialDir := ExtractFilePath(ParamStr(0)) + 'pic';
if OpenDialog1.Execute then
sFileName := OpenDialog1.FileName
else
Exit;
nDelay := THelp.GetSysTickCount64;
stor := cvCreateMemStorage(0);
cont := cvCreateSeq(0, sizeof(CvSeq), sizeof(CvPoint), stor);
oImg := cvLoadImage(PChar(sFileName), CV_LOAD_IMAGE_GRAYSCALE);
oImg3 := cvCreateImage(cvSize_(oImg.Width, oImg.Height), oImg.Depth, oImg.NChannels);
oImg2 := cvCloneImage(oImg);
cvAdaptiveThreshold(oImg, oImg3, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, 11, 5);
cvCanny(oImg, oImg, StrToInt(EdtCanny_P1.Text), StrToInt(EdtCanny_P2.Text));
cvSaveImage('C:\1.bmp', oImg3);
cvSaveImage('C:\2.bmp', oImg);
cvNamedWindow('Example1', CV_WINDOW_AUTOSIZE);
cvNamedWindow('Example2', CV_WINDOW_AUTOSIZE);
pChain := nil;
nCnt := cvFindContours(oImg, stor, @pChain, SizeOf(CvChain), CV_RETR_LIST, CV_CHAIN_CODE, cvPoint_(0,0));
cont := cvApproxChains(PCvSeq(pChain), stor, CV_CHAIN_APPROX_SIMPLE, 0, 0, 1); //多边形逼近
cvZero(oImg);
nCnt := 0;
while cont <> nil do
begin
if cont.total > 2 then
begin
SetLength(arr, cont.total * 2);
SetLength(aPoints, High(aPoints) + cont.total + 1);
cvCvtSeqToArray(cont, @arr[0], CvSlice_(0, CV_WHOLE_SEQ_END_INDEX));
for i := Low(arr) to High(arr) div 2 do
begin
aPoints[nCnt] := cvPoint2D32f_(arr[i * 2], arr[i * 2 + 1]);
Inc(nCnt);
end;
end;
cont := cont.h_next;
end;
pointMat := cvCreateMat(1, nCnt * 2, CV_32FC2);
pS := PSingle(pointMat.ptr);
for i := Low(aPoints) to High(aPoints) do
begin
pS^ := aPoints[i].x;
Inc(pS);
pS^ := aPoints[i].y;
Inc(pS);
end;
lines := cvMakeSeqHeaderForArray(CV_32FC2, SizeOf(CvSeq), SizeOf(Single) * 2, @aPoints[0], High(aPoints) + 1, @lines_header, @lines_block);
box := cvMinAreaRect2(lines);
cvBoxPoints(box, @aboxPoint[0]);
for i := Low(aboxPoint) to High(aboxPoint) do
cvLine(oImg3, CvPoint2D32fToCvPoint(aboxPoint[i]), CvPoint2D32fToCvPoint(aboxPoint[(i + 1) mod 4]), CV_RGB(100, 100, 100), 2, 8, 0);
cvSaveImage('C:\2.bmp', oImg3);
cvShowImage('Example1', oImg);
cvShowImage('Example2', oImg3);
cvWaitKey(0);
cvReleaseImage(oImg);
cvReleaseImage(oImg2);
cvDestroyWindow('Example1');
cvDestroyWindow('Example2');
end;
原图:
获取的倾斜矩形: