mirror of
https://github.com/Laex/Delphi-OpenCV.git
synced 2024-11-16 16:25:53 +01:00
4049cda768
Signed-off-by: Laex <laex@bk.ru>
321 lines
8.7 KiB
ObjectPascal
321 lines
8.7 KiB
ObjectPascal
// *****************************************************************
|
|
// 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.
|