为了更好的测试OpenCV中cvHoughCircles函数的功能和各个参数作用,使用Delphi生成了一个工程,利用Trackbar调整各个参数,每次调整都调用一次cvHoughCircles函数比便于对比参数的效果.OpenCV作为开源项目,文档不够详细,每个函数的参数都只是做了简要的说明,在不同的实际应用中,有必要对函数中的每个参数进行系统测试,才能得到自己能体会的作用.
unit MainForm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls;
type
TFrmMain = class(TForm)
BtnHouphCircle: TButton;
TrackBar1: TTrackBar;
Label1: TLabel;
TrackBar2: TTrackBar;
Label2: TLabel;
TrackBar3: TTrackBar;
Label3: TLabel;
TrackBar4: TTrackBar;
Label4: TLabel;
TrackBar5: TTrackBar;
Label5: TLabel;
TrackBar6: TTrackBar;
Label6: TLabel;
TrackBar7: TTrackBar;
Label7: TLabel;
TrackBar8: TTrackBar;
Label8: TLabel;
EdtPicture: TEdit;
Label9: TLabel;
BtnPictureFile: TButton;
procedure BtnHouphCircleClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure TrackBar1Change(Sender: TObject);
procedure BtnPictureFileClick(Sender: TObject);
private
procedure DoHoughCircle;
public
{ Public declarations }
end;
var
FrmMain: TFrmMain;
implementation
uses IPL, OpenCV;
{$R *.dfm}
procedure TFrmMain.BtnHouphCircleClick(Sender: TObject);
var
sFileName: string;
img: PIplImage;
storage: PCvMemStorage;
seq: PCvSeq;
i: Integer;
p: PFloat;
x, y, radiu: Integer;
pt: CvPoint;
pc: PChar;
begin
if EdtPicture.Text = '' then Exit;
sFileName := EdtPicture.Text;
img := cvLoadImage(PChar(sFileName), CV_LOAD_IMAGE_GRAYSCALE);
cvNamedWindow('test', CV_WINDOW_AUTOSIZE );
cvEqualizeHist(img, img);//直方图均衡化后效果更好
storage := cvCreateMemStorage(0);
//cvCanny(img, img, 90, 120);
//cvSmooth(img, img);
cvSaveImage('c:\1.jpg', img);
seq := cvHoughCircles(img, storage, CV_HOUGH_GRADIENT,
TrackBar1.Position, //累加分辨率 1表示与源图像相同 2表示比源图像小两倍 3
TrackBar2.Position, //圆心间的最小距离 10
TrackBar3.Position, //第一个方法的相关参数 13
TrackBar4.Position,//第二个方法的相关参数 76
TrackBar5.Position, //圆弧最小半径 5
TrackBar6.Position);//圆弧最大半径 9
for i := 0 to seq.total - 1 do
begin
pc := cvGetSeqElem(seq, i);
p := PFloat(pc);
x := cvRound(p^);
Inc(p);
y := cvRound(p^);
Inc(p);
radiu :=cvRound(p^);
pt := cvPoint_(x, y);
cvCircle(img, pt, radiu, CV_RGB($FF, $FF, $FF), 2);
end;
cvShowImage('test', img);
end;
procedure TFrmMain.BtnPictureFileClick(Sender: TObject);
begin
with TOpenDialog.Create(Self) do
begin
try
InitialDir := ExtractFilePath(ParamStr(0)) + '..\Data';
if Execute then
EdtPicture.Text := FileName;
finally
Free;
end;
end;
end;
procedure TFrmMain.DoHoughCircle;
var
sFileName: string;
img: PIplImage;
storage: PCvMemStorage;
seq: PCvSeq;
i: Integer;
p: PFloat;
x, y, radiu: Integer;
pt: CvPoint;
pc: PChar;
begin
if EdtPicture.Text = '' then Exit;
sFileName := EdtPicture.Text;
img := cvLoadImage(PChar(sFileName), CV_LOAD_IMAGE_GRAYSCALE);
cvShowImage('test', img);
storage := cvCreateMemStorage(0);
//cvCanny(img, img, TrackBar7.Position, TrackBar8.Position);
cvSaveImage('c:\1.jpg', img);
seq := cvHoughCircles(img, storage, CV_HOUGH_GRADIENT,
TrackBar1.Position, //累加分辨率 1表示与源图像相同 2表示比源图像小两倍 3
TrackBar2.Position, //圆心间的最小距离 10
TrackBar3.Position, //第一个方法的相关参数 13
TrackBar4.Position,//第二个方法的相关参数 76
TrackBar5.Position, //圆弧最小半径 5
TrackBar6.Position);//圆弧最大半径 9
for i := 0 to seq.total - 1 do
begin
pc := cvGetSeqElem(seq, i);
p := PFloat(pc);
x := cvRound(p^);
Inc(p);
y := cvRound(p^);
Inc(p);
radiu :=cvRound(p^);
pt := cvPoint_(x, y);
cvCircle(img, pt, radiu, CV_RGB($FF, $FF, $FF), 2);
end;
cvShowImage('test', img);
cvReleaseMemStorage(storage);
cvReleaseImage(img);
end;
procedure TFrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
{cvReleaseMemStorage(storage);
cvReleaseImage(img);
cvDestroyWindow('test'); }
end;
procedure TFrmMain.TrackBar1Change(Sender: TObject);
begin
DoHoughCircle;
end;
end.