mirror of
https://github.com/Laex/Delphi-OpenCV.git
synced 2024-11-18 01:05:53 +01:00
2f087607e5
Signed-off-by: Mikhail Grigorev <sleuthhound@gmail.com>
388 lines
7.3 KiB
ObjectPascal
388 lines
7.3 KiB
ObjectPascal
// *****************************************************************
|
|
// Delphi-OpenCV Demo
|
|
// Copyright (C) 2013 Project Delphi-OpenCV
|
|
// ****************************************************************
|
|
// Contributor:
|
|
// Laentir Valetov
|
|
// email:laex@bk.ru
|
|
// ****************************************************************
|
|
// You may retrieve the latest version of this file at the GitHub,
|
|
// located at git://github.com/Laex/Delphi-OpenCV.git
|
|
// ****************************************************************
|
|
// The contents of this file are used with permission, subject to
|
|
// the Mozilla Public License Version 1.1 (the "License"); you may
|
|
// not use this file except in compliance with the License. You may
|
|
// obtain a copy of the License at
|
|
// http://www.mozilla.org/MPL/MPL-1_1Final.html
|
|
//
|
|
// Software distributed under the License is distributed on an
|
|
// "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
// implied. See the License for the specific language governing
|
|
// rights and limitations under the License.
|
|
// *******************************************************************
|
|
|
|
program cv_MatchShapes2;
|
|
|
|
{$APPTYPE CONSOLE}
|
|
{$R *.res}
|
|
|
|
uses
|
|
System.SysUtils,
|
|
System.Math,
|
|
opencv.highgui_c,
|
|
opencv.core_c,
|
|
opencv.core.types_c,
|
|
opencv.imgproc_c,
|
|
opencv.imgproc.types_c,
|
|
opencv.cvutils,
|
|
uResourcePaths;
|
|
|
|
// ñðàâíåíèå îáúåêòîâ ïî ìîìåíòàì èõ êîíòóðîâ
|
|
procedure testMatch(original, templ: pIplImage);
|
|
Var
|
|
src, dst: pIplImage;
|
|
binI : pIplImage;
|
|
binT : pIplImage;
|
|
rgb : pIplImage;
|
|
rgbT : pIplImage;
|
|
|
|
storage : pCvMemStorage;
|
|
contoursI : pCvSeq;
|
|
contoursT : pCvSeq;
|
|
contoursCont: Integer;
|
|
font : TCvFont;
|
|
counter : Integer;
|
|
buf : string;
|
|
seq0 : pCvSeq;
|
|
seqT : pCvSeq;
|
|
perimT : double;
|
|
perim : double;
|
|
seqM : pCvSeq;
|
|
matchM : double;
|
|
match0 : double;
|
|
|
|
point: TCvPoint2D32f;
|
|
rad : Float;
|
|
|
|
begin
|
|
assert(original <> nil);
|
|
assert(templ <> nil);
|
|
|
|
WriteLn('[i] test cvMatchShapes()\n');
|
|
|
|
src := nil;
|
|
dst := nil;
|
|
|
|
src := cvCloneImage(original);
|
|
|
|
binI := cvCreateImage(
|
|
cvGetSize(src),
|
|
8,
|
|
1);
|
|
binT := cvCreateImage(
|
|
cvGetSize(templ),
|
|
8,
|
|
1);
|
|
|
|
// çàâåä¸ì öâåòíûå êàðòèíêè
|
|
rgb := cvCreateImage(
|
|
cvGetSize(original),
|
|
8,
|
|
3);
|
|
cvConvertImage(
|
|
src,
|
|
rgb,
|
|
CV_GRAY2BGR);
|
|
rgbT := cvCreateImage(
|
|
cvGetSize(templ),
|
|
8,
|
|
3);
|
|
cvConvertImage(
|
|
templ,
|
|
rgbT,
|
|
CV_GRAY2BGR);
|
|
|
|
// ïîëó÷àåì ãðàíèöû èçîáðàæåíèÿ è øàáëîíà
|
|
cvCanny(
|
|
src,
|
|
binI,
|
|
50,
|
|
200);
|
|
cvCanny(
|
|
templ,
|
|
binT,
|
|
50,
|
|
200);
|
|
|
|
// ïîêàçûâàåì
|
|
cvNamedWindow(
|
|
'cannyI',
|
|
1);
|
|
cvShowImage(
|
|
'cannyI',
|
|
binI);
|
|
|
|
cvNamedWindow(
|
|
'cannyT',
|
|
1);
|
|
cvShowImage(
|
|
'cannyT',
|
|
binT);
|
|
|
|
// äëÿ õðàíåíèÿ êîíòóðîâ
|
|
storage := cvCreateMemStorage(0);
|
|
contoursI := nil;
|
|
contoursT := nil;
|
|
|
|
// íàõîäèì êîíòóðû èçîáðàæåíèÿ
|
|
contoursCont := cvFindContours(
|
|
binI,
|
|
storage,
|
|
@contoursI,
|
|
sizeof(TCvContour),
|
|
CV_RETR_LIST,
|
|
CV_CHAIN_APPROX_SIMPLE,
|
|
cvPoint(0, 0));
|
|
|
|
// äëÿ îòìåòêè êîíòóðîâ
|
|
cvInitFont(
|
|
@font,
|
|
CV_FONT_HERSHEY_PLAIN,
|
|
1.0,
|
|
1.0);
|
|
counter := 0;
|
|
|
|
// íàðèñóåì êîíòóðû èçîáðàæåíèÿ
|
|
if (contoursI <> nil) then
|
|
begin
|
|
seq0 := contoursI;
|
|
While seq0 <> nil do
|
|
begin
|
|
// ðèñóåì êîíòóð
|
|
cvDrawContours(
|
|
rgb,
|
|
seq0,
|
|
CV_RGB(255, 216, 0),
|
|
CV_RGB(0, 0, 250),
|
|
0,
|
|
1,
|
|
8,
|
|
cvPoint(0, 0));
|
|
// âûâîäèì åãî íîìåð
|
|
cvMinEnclosingCircle(
|
|
seq0,
|
|
@point,
|
|
@rad); // ïîëó÷èì îêðóæíîñòü ñîäåðæàùóþ êîíòóð
|
|
Inc(counter);
|
|
cvPutText(
|
|
rgb,
|
|
c_str(IntToStr(counter)),
|
|
cvPointFrom32f(point),
|
|
@font,
|
|
CV_RGB(0, 255, 0));
|
|
seq0 := seq0^.h_next;
|
|
end;
|
|
end;
|
|
// ïîêàçûâàåì
|
|
cvNamedWindow(
|
|
'cont',
|
|
1);
|
|
cvShowImage(
|
|
'cont',
|
|
rgb);
|
|
|
|
cvConvertImage(
|
|
src,
|
|
rgb,
|
|
CV_GRAY2BGR);
|
|
|
|
// íàõîäèì êîíòóðû øàáëîíà
|
|
cvFindContours(
|
|
binT,
|
|
storage,
|
|
@contoursT,
|
|
sizeof(TCvContour),
|
|
CV_RETR_LIST,
|
|
CV_CHAIN_APPROX_SIMPLE,
|
|
cvPoint(0, 0));
|
|
|
|
seqT := nil;
|
|
perimT := 0;
|
|
|
|
if (contoursT <> nil) then
|
|
begin
|
|
// íàõîäèì ñàìûé äëèííûé êîíòóð
|
|
seq0 := contoursT;
|
|
while seq0 <> nil do
|
|
begin
|
|
perim := cvContourPerimeter(seq0);
|
|
if (perim > perimT) then
|
|
begin
|
|
perimT := perim;
|
|
seqT := seq0;
|
|
end;
|
|
// ðèñóåì
|
|
cvDrawContours(
|
|
rgbT,
|
|
seq0,
|
|
CV_RGB(255, 216, 0),
|
|
CV_RGB(0, 0, 250),
|
|
0,
|
|
1,
|
|
8,
|
|
cvPoint(0, 0)); // ðèñóåì êîíòóð
|
|
seq0 := seq0^.h_next;
|
|
end;
|
|
end;
|
|
// ïîêàæåì êîíòóð øàáëîíà
|
|
cvDrawContours(
|
|
rgbT,
|
|
seqT,
|
|
CV_RGB(52, 201, 36),
|
|
CV_RGB(36, 201, 197),
|
|
0,
|
|
2,
|
|
8,
|
|
cvPoint(0, 0)); // ðèñóåì êîíòóð
|
|
cvNamedWindow(
|
|
'contT',
|
|
1);
|
|
cvShowImage(
|
|
'contT',
|
|
rgbT);
|
|
|
|
seqM := nil;
|
|
matchM := 1000;
|
|
// îáõîäèì êîíòóðû èçîáðàæåíèÿ
|
|
counter := 0;
|
|
if (contoursI <> nil) then
|
|
begin
|
|
// ïîèñê ëó÷øåãî ñîâïàäåíèÿ êîíòóðîâ ïî èõ ìîìåíòàì
|
|
seq0 := contoursI;
|
|
while seq0 <> nil do
|
|
begin
|
|
match0 := cvMatchShapes(
|
|
seq0,
|
|
seqT,
|
|
CV_CONTOURS_MATCH_I3);
|
|
if (match0 < matchM) then
|
|
begin
|
|
matchM := match0;
|
|
seqM := seq0;
|
|
end;
|
|
Inc(counter);
|
|
WriteLn(Format('[i] %d match: %.2f', [counter, match0]));
|
|
seq0 := seq0^.h_next;
|
|
end;
|
|
end;
|
|
// ðèñóåì íàéäåííûé êîíòóð
|
|
cvDrawContours(
|
|
rgb,
|
|
seqM,
|
|
CV_RGB(52, 201, 36),
|
|
CV_RGB(36, 201, 197),
|
|
0,
|
|
2,
|
|
8,
|
|
cvPoint(0, 0)); // ðèñóåì êîíòóð
|
|
|
|
cvNamedWindow(
|
|
'find',
|
|
1);
|
|
cvShowImage(
|
|
'find',
|
|
rgb);
|
|
|
|
// æä¸ì íàæàòèÿ êëàâèøè
|
|
cvWaitKey(0);
|
|
|
|
// îñâîáîæäàåì ðåñóðñû
|
|
cvReleaseMemStorage(storage);
|
|
cvReleaseImage(src);
|
|
cvReleaseImage(dst);
|
|
cvReleaseImage(rgb);
|
|
cvReleaseImage(rgbT);
|
|
cvReleaseImage(binI);
|
|
cvReleaseImage(binT);
|
|
|
|
// óäàëÿåì îêíà
|
|
cvDestroyAllWindows();
|
|
end;
|
|
|
|
const
|
|
const_original = cResourceMedia + 'matchshapes2.jpg';
|
|
const_template = cResourceMedia + 'matchshapes_template.jpg';
|
|
|
|
Var
|
|
original : pIplImage = nil;
|
|
templ : pIplImage = nil;
|
|
filename, filename2: String;
|
|
|
|
begin
|
|
try
|
|
|
|
// èìÿ êàðòèíêè çàäà¸òñÿ ïåðâûì ïàðàìåòðîì
|
|
|
|
filename := ifthen(
|
|
ParamCount > 0,
|
|
ParamStr(1),
|
|
const_original);
|
|
// ïîëó÷àåì êàðòèíêó
|
|
original := cvLoadImage(
|
|
c_str(filename),
|
|
0);
|
|
|
|
WriteLn(
|
|
'[i] image: ',
|
|
filename);
|
|
assert(Assigned(original));
|
|
|
|
// èìÿ øàáëîíà çàäà¸òñÿ âòîðûì ïàðàìåòðîì
|
|
filename2 := ifthen(
|
|
ParamCount > 1,
|
|
ParamStr(2),
|
|
const_template);
|
|
// ïîëó÷àåì êàðòèíêó
|
|
templ := cvLoadImage(
|
|
c_str(filename2),
|
|
0);
|
|
|
|
WriteLn(
|
|
'[i] template: ',
|
|
filename2);
|
|
assert(Assigned(templ));
|
|
|
|
// ïîêàæåì èçîáðàæåíèÿ
|
|
cvNamedWindow(
|
|
'original',
|
|
1);
|
|
cvShowImage(
|
|
'original',
|
|
original);
|
|
cvNamedWindow(
|
|
'template',
|
|
1);
|
|
cvShowImage(
|
|
'template',
|
|
templ);
|
|
|
|
// ñðàâíåíèå
|
|
testMatch(
|
|
original,
|
|
templ);
|
|
|
|
// îñâîáîæäàåì ðåñóðñû
|
|
cvReleaseImage(original);
|
|
cvReleaseImage(templ);
|
|
// óäàëÿåì îêíà
|
|
cvDestroyAllWindows();
|
|
except
|
|
on E: Exception do
|
|
WriteLn(
|
|
E.ClassName,
|
|
': ',
|
|
E.Message);
|
|
end;
|
|
|
|
end.
|