Delphi-OpenCV/samples/VCLDemo/vclChessboardCorners/MainForm.pas

321 lines
8.7 KiB
ObjectPascal
Raw Normal View History

// *****************************************************************
// Delphi-OpenCV Demo
// Copyright (C) 2013 Project Delphi-OpenCV
// ****************************************************************
// Contributor:
// Samuele Trentin
// ****************************************************************
// 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.
// *******************************************************************
unit MainForm;
interface
uses
Winapi.Windows,
Winapi.Messages,
System.SysUtils,
System.Variants,
System.Classes,
Vcl.Graphics,
Vcl.Controls,
Vcl.Forms,
Vcl.Dialogs,
highgui_c,
core.types_c,
Vcl.ExtCtrls,
Vcl.StdCtrls;
type
TFormMain = class(TForm)
ImageOut: TImage;
Panel1: TPanel;
ButtonClose: TButton;
ButtonAR: TButton;
ImageCaptured: TImage;
ButtonShow: TButton;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure ButtonCloseClick(Sender: TObject);
procedure ButtonARClick(Sender: TObject);
procedure ButtonShowClick(Sender: TObject);
private
{ Private declarations }
FCamCapture : pCvCapture;
FFrameBitmap : TBitmap;
FOverlaySize : TCvSize;
FbAR2D : boolean;
FCorner : array [0 .. 100] of TCvPoint2D32f;
FOverlayImage: pIplImage;
procedure OnIdle(Sender: TObject; var Done: boolean);
public
{ Public declarations }
end;
var
FormMain: TFormMain;
implementation
{$R *.dfm}
uses
core_c,
cvUtils,
calib3d_c,
imgproc_c,
imgproc.types_c;
const
nWidthGrid = 9;
nHeightGrid = 6;
procedure TFormMain.ButtonCloseClick(Sender: TObject);
begin
Application.OnIdle := nil;
FbAR2D := False;
Close;
end;
procedure TFormMain.FormCreate(Sender: TObject);
begin
ButtonShowClick(Self);
// Initialization
FbAR2D := False;
FOverlaySize.height := nHeightGrid - 1;
FOverlaySize.width := nWidthGrid - 1;
FOverlayImage := cvLoadImage('Resource\baboon.jpg');
// Link to the first camera available
FCamCapture := cvCreateCameraCapture(CV_CAP_ANY);
if Assigned(FCamCapture) then
begin
// Structure for treating the images captured by camera
FFrameBitmap := TBitmap.Create;
FFrameBitmap.PixelFormat := pf24bit;
// Show frame captured..
Application.OnIdle := OnIdle;
end;
end;
procedure TFormMain.FormDestroy(Sender: TObject);
begin
// Free camera and structure..
if Assigned(FCamCapture) then
cvReleaseCapture(FCamCapture);
if Assigned(FFrameBitmap) then
FFrameBitmap.Free;
cvReleaseImage(FOverlayImage);
end;
procedure TFormMain.OnIdle(Sender: TObject; var Done: boolean);
Var
frame : pIplImage;
nResult : Integer;
resizeImg, blankImg, negImg, copyImg, greyImg: pIplImage;
p, q : pCvPoint2D32f;
warp_matrix : pCvMat;
begin
// Retrieve frame
frame := cvQueryFrame(FCamCapture);
if Assigned(frame) then
begin
// Show input
if ImageCaptured.Visible then
begin
IplImage2Bitmap(
frame,
FFrameBitmap);
ImageCaptured.Picture.Bitmap.Assign(FFrameBitmap);
end;
// Overlay image..
if FbAR2D then
begin
try
// Create gray image from source
greyImg := cvCreateImage(
cvGetSize(frame),
IPL_DEPTH_8U,
1);
cvCvtColor(
frame,
greyImg,
CV_BGR2GRAY);
nResult := cvCheckChessboard(
greyImg,
CvSize(nWidthGrid, nHeightGrid));
if nResult > 0 then
begin
nResult := cvFindChessboardCorners(
greyImg,
FOverlaySize,
@FCorner);
if nResult > 0 then
begin
try
// Identifies the pattern from the gray image and saves the valid group of corners
cvFindCornerSubPix(
greyImg,
@FCorner,
40,
CvSize(11, 11),
CvSize(-1, -1),
CvTermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 40, 0.1));
// Set the source points
q := AllocMem(SizeOf(TCvPoint2D32f) * 4);
// Src Top left
q[0].x := 0;
q[0].y := 0;
// Src Top right
q[1].x := FOverlayImage.width - 1;
q[1].y := 0;
// Src Bottom left
q[2].x := 0;
q[2].y := FOverlayImage.height - 1;
// Src Bot right
q[3].x := FOverlayImage.width - 1;
q[3].y := FOverlayImage.height - 1;
// Set the destination points
p := AllocMem(SizeOf(TCvPoint2D32f) * 4);
// Src Top right
p[0].x := FCorner[0].x;
p[0].y := FCorner[0].y;
// Src Top left
p[1].x := FCorner[nWidthGrid - 2].x;
p[1].y := FCorner[nWidthGrid - 2].y;
// Src Bottom left
p[2].x := FCorner[(nWidthGrid - 1) * (nHeightGrid - 2)].x;
p[2].y := FCorner[(nWidthGrid - 1) * (nHeightGrid - 2)].y;
// Src Bot right
p[3].x := FCorner[(nWidthGrid - 1) * (nHeightGrid - 1) - 1].x;
p[3].y := FCorner[(nWidthGrid - 1) * (nHeightGrid - 1) - 1].y;
// Create the transformation matrix
warp_matrix := cvCreateMat(
3,
3,
CV_32FC1);
cvGetPerspectiveTransform(
q,
p,
warp_matrix);
// Support structures
blankImg := cvCreateImage(
cvGetSize(FOverlayImage),
FOverlayImage.depth,
FOverlayImage.nChannels);
negImg := cvCreateImage(
cvGetSize(frame),
frame.depth,
frame.nChannels);
copyImg := cvCreateImage(
cvGetSize(frame),
frame.depth,
frame.nChannels);
// Transform overlay image
cvWarpPerspective(
FOverlayImage,
negImg,
warp_matrix,
CV_INTER_LINEAR or CV_WARP_FILL_OUTLIERS,
cvScalarAll(0));
// Set to white
cvSet(
blankImg,
cvScalarAll(255));
// Transform blank image
cvWarpPerspective(
blankImg,
copyImg,
warp_matrix,
CV_INTER_LINEAR or CV_WARP_FILL_OUTLIERS,
cvScalarAll(0));
// Invert image
cvNot(
copyImg,
copyImg);
// Join Frame and overlay image
cvAnd(
copyImg,
frame,
copyImg);
cvOr(
copyImg,
negImg,
frame);
// Show output
IplImage2Bitmap(
frame,
FFrameBitmap);
ImageOut.Picture.Bitmap.Assign(FFrameBitmap);
finally
FreeMem(q);
FreeMem(p);
cvReleaseImage(blankImg);
cvReleaseImage(negImg);
cvReleaseImage(copyImg);
end;
end;
end;
except
on E: Exception do
end;
end;
Done := False;
end
else
Application.OnIdle := nil;
end;
procedure TFormMain.ButtonARClick(Sender: TObject);
begin
// Start / Stop
if not FbAR2D then
ButtonAR.Caption := 'Disable'
else
ButtonAR.Caption := 'Active';
FbAR2D := not FbAR2D;
end;
procedure TFormMain.ButtonShowClick(Sender: TObject);
begin
ImageCaptured.Visible := not ImageCaptured.Visible;
// Show / hide captured frame..
if ImageCaptured.Visible then
begin
ButtonShow.Caption := '<< Hide cap.';
Self.width := 1384;
end
else
begin
ButtonShow.Caption := 'Show cap. >>';
Self.width := 746;
end;
end;
end.