Delphi-OpenCV/samples/CameraCalibrate/CameraCalibrate.dpr
Laex 13286756ea [+] CameraCalibrate
[+] Stereo

Signed-off-by: Laex <laex@bk.ru>
2013-04-01 00:30:13 +04:00

278 lines
8.8 KiB
ObjectPascal
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ×òåíèå øèðèíû è âûñîòû øàõìàòíîé äîñêè,
// ÷òåíèå è êîëëåêöèîíèðîâàíèå çàïðîøåííîãî êîëè÷åñòâà âèäîâ
// è êàëèáðîâêà êàìåðû
// calib.cpp
// Èíèöèàëèçàöèÿ âõîäíûõ äàííûõ:
// calib board_w board_h number_of_views
//
// Íàæàòèå p - óñòàíîâêà/âûêëþ÷åíèå ïàóçû, ESC - âûõîä
{$APPTYPE CONSOLE}
// JCL_DEBUG_EXPERT_GENERATEJDBG OFF
// JCL_DEBUG_EXPERT_INSERTJDBG OFF
// JCL_DEBUG_EXPERT_DELETEMAPFILE OFF
program CameraCalibrate;
{$R *.res}
uses
System.SysUtils,
LibName in '..\..\include\LibName.pas',
highgui_c in '..\..\include\highgui\highgui_c.pas',
core_c in '..\..\include\ñore\core_c.pas',
Core.types_c in '..\..\include\ñore\Core.types_c.pas',
imgproc.types_c in '..\..\include\imgproc\imgproc.types_c.pas',
imgproc_c in '..\..\include\imgproc\imgproc_c.pas',
legacy in '..\..\include\legacy\legacy.pas',
calib3d in '..\..\include\calib3d\calib3d.pas',
types_c in '..\..\include\ñore\types_c.pas';
Type
pCvPoint2D32fArray = ^TCvPoint2D32fArray;
TCvPoint2D32fArray = array [0 .. 1] of TCvPoint2D32f;
Const
float = SizeOf(Single);
Var
n_boards: Integer = 0; // Óñòàíîâèì âõîäíîé ñïèñîê
board_dt: Integer = 20; // Æäåì 20 ôðåéìîâ ñ âèäàìè øàõìàòíîé äîñêè
board_w: Integer;
board_h: Integer;
board_n: Integer;
board_sz: TCvSize;
capture: pCvCapture;
image_points: pCvMat;
object_points: pCvMat;
point_counts: pCvMat;
intrinsic_matrix: pCvMat;
distortion_coeffs: pCvMat;
corners: pCvPoint2D32f;
corner_count: Integer;
successes: Integer = 0;
step: Integer = 0;
frame: Integer = 0;
image: pIplImage;
gray_image: pIplImage;
found: Integer;
i, j: Integer;
c: Integer;
object_points2: pCvMat;
image_points2: pCvMat;
point_counts2: pCvMat;
intrinsic: pCvMat;
Distortion: pCvMat;
mapx: pIplImage;
mapy: pIplImage;
t: pIplImage;
s: Single;
procedure CV_MAT_ELEMS(const Mat: pCvMat; const x, y: Integer; const Value: Single); overload;
Var
P: Pointer;
begin
P := Pointer(Integer(Mat^.data) + SizeOf(Value) * x * Mat^.step + SizeOf(Value) * y);
Move(Value, P^, SizeOf(Value));
end;
function CV_MAT_ELEMS(const Mat: pCvMat; const x, y: Integer): Single; overload;
begin
Result := pSingle(Integer(Mat^.data) + SizeOf(Result) * x * Mat^.step + SizeOf(Result) * y)^;
end;
procedure CV_MAT_ELEMI(const Mat: pCvMat; const x, y: Integer; const Value: Integer); overload;
Var
P: Pointer;
begin
P := Pointer(Integer(Mat^.data) + SizeOf(Value) * x * Mat^.step + SizeOf(Value) * y);
Move(Value, P^, SizeOf(Value));
end;
function CV_MAT_ELEMI(const Mat: pCvMat; const x, y: Integer): Integer; overload;
begin
Result := pInteger(Integer(Mat^.data) + SizeOf(Result) * x * Mat^.step + SizeOf(Result) * y)^;
end;
begin
try
if ParamCount <> 3 then
begin
Writeln('ERROR: Wrong number of input parameters');
Halt;
end;
board_w := StrToInt(ParamStr(1));
board_h := StrToInt(ParamStr(2));
n_boards := StrToInt(ParamStr(3));
board_n := board_w * board_h;
board_sz := cvSize(board_w, board_h);
capture := cvCreateCameraCapture(0);
assert(Assigned(capture));
cvNamedWindow('Calibration');
// ÂÛÄÅËßÅÌ ÕÐÀÍÈËÈÙÅ ÏÀÌßÒÈ
image_points := cvCreateMat(n_boards * board_n, 2, CV_32FC1);
object_points := cvCreateMat(n_boards * board_n, 3, CV_32FC1);
point_counts := cvCreateMat(n_boards, 1, CV_32SC1);
intrinsic_matrix := cvCreateMat(3, 3, CV_32FC1);
distortion_coeffs := cvCreateMat(5, 1, CV_32FC1);
corners := AllocMem(SizeOf(CvPoint2D32f) * board_n);
image := cvQueryFrame(capture);
gray_image := cvCreateImage(cvGetSize(image), 8, 1); // subpixel
// ÇÀÕÂÀÒ Â ÖÈÊËÅ ÈÇÎÁÐÀÆÅÍÈÉ Ñ ÓÃËÀÌÈ ÏÎÊÀ ÌÛ ÍÅ ÏËÎÓ×ÈÌ n_boards
// ÏÎËÍÛÕ ÇÀÕÂÀÒÎÂ (ÂÑÅ ÓÃËÛ ÍÀ ÄÎÑÊÅ ÁÛËÈ ÍÀÉÄÅÍÛ)
//
while (successes < n_boards) do
begin
// Ïðîïóñêàåì board_dt ôðåéìîâ, ïðåäîñòàâëåííûå ïîëüçîâàòåëåì, äâèãàþùèì äîñêó
if ((frame div board_dt) = 0) then
begin
// Íàõîäèì óãëû øàõìàòíîé äîñêè:
found := cvFindChessboardCorners(image, board_sz, corners, @corner_count, CV_CALIB_CB_ADAPTIVE_THRESH or
CV_CALIB_CB_FILTER_QUADS);
// Ïîëó÷åíèå ñóáïèêñåëüíîé òî÷íîñòè íà ýòèõ óãëàõ
cvCvtColor(image, gray_image, CV_BGR2GRAY);
cvFindCornerSubPix(gray_image, corners, corner_count, cvSize(11, 11), cvSize(-1, -1),
cvTermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
// Íàðèñóåì ýòî
cvDrawChessboardCorners(image, board_sz, corners, corner_count, found);
cvShowImage('Calibration', image);
// Åñëè ìû ïîëó÷èëè õîðîøóþ äîñêó, äîáàâèì åå ê íàøèì äàííûì
if (corner_count = board_n) then
begin
step := successes * board_n;
i := step;
j := 0;
while j < board_n do
begin
Inc(i);
Inc(j);
CV_MAT_ELEMS(image_points, i, 0, pCvPoint2D32fArray(corners)^[j].x);
CV_MAT_ELEMS(image_points, i, 1, pCvPoint2D32fArray(corners)^[j].y);
CV_MAT_ELEMS(object_points, i, 0, j / board_w);
CV_MAT_ELEMS(object_points, i, 1, j div board_w);
CV_MAT_ELEMS(object_points, i, 2, 0);
end;
CV_MAT_ELEMI(point_counts, successes, 0, board_n);
Inc(successes);
end;
end; // end skip board_dt between chessboard capture
// Handle pause/unpause and ESC
c := cvWaitKey(15);
if (c = Ord('p')) then
begin
c := 0;
while (c <> Ord('p')) and (c <> 27) do
begin
c := cvWaitKey(250);
end;
end;
if (c = 27) then
Halt;
image := cvQueryFrame(capture); // Ïîëó÷àåì ñëåäóþùåå èçîáðàæåíèå
end; // ÊÎÍÅÖ ÊÎËËÅÊÖÈÎÍÈÐÎÂÀÍÈÅ ÖÈÊËÎÌ WHILE.
// ÂÛÄÅËßÅÌ ÌÀÒÐÈÖÛ Ê ÒÀÊÎÌÓ ÊÎËÈ×ÅÑÒÂÓ ØÀÕÌÀÒÍÛÕ ÄÎÑÊ, ÑÊÎËÜÊÎ ÁÛËÎ ÍÀÉÄÅÍÎ
object_points2 := cvCreateMat(successes * board_n, 3, CV_32FC1);
image_points2 := cvCreateMat(successes * board_n, 2, CV_32FC1);
point_counts2 := cvCreateMat(successes, 1, CV_32SC1);
// ÏÅÐÅÌÅÙÀÅÌ ÒÎ×ÊÈ Â ÌÀÒÐÈÖÛ ÏÐÀÂÈËÜÍÎÃÎ ÐÀÇÌÅÐÀ
// Íèæå ìû îïèøåì ýòî äåòàëüíî â ñëåäóþùèõ äâóõ öèêëàõ.
// Ìû ìîæåì âìåñòî ýòîãî íàïèñàòü:
// image_points->rows := object_points->rows := \
// successes*board_n; point_counts->rows := successes;
i := 0;
While i < successes * board_n do
begin
Inc(i);
CV_MAT_ELEMS(image_points2, i, 0, CV_MAT_ELEMS(image_points, i, 0));
CV_MAT_ELEMS(image_points2, i, 1, CV_MAT_ELEMS(image_points, i, 1));
CV_MAT_ELEMS(object_points2, i, 0, CV_MAT_ELEMS(object_points, i, 0));
CV_MAT_ELEMS(object_points2, i, 1, CV_MAT_ELEMS(object_points, i, 1));
CV_MAT_ELEMS(object_points2, i, 2, CV_MAT_ELEMS(object_points, i, 2));
end;
i := 0;
While i < successes do
begin // Çäåñü âñå òå æå ÷èñëà
Inc(i);
CV_MAT_ELEMI(point_counts2, i, 0, CV_MAT_ELEMI(point_counts, i, 0));
end;
cvReleaseMat(object_points);
cvReleaseMat(image_points);
cvReleaseMat(point_counts);
// Äëÿ ýòèõ òî÷åê ìû èìååì âñå óãëû øàõìàòíîé äîñêè, êîòîðûå íàì íóæíû.
// Èíèöèàëèçèðóåì ìàòðèöó âíóòðåííèõ ïàðàìåòðîâ òàê, ÷òî îáà ôîêàëüíûõ
// ðàññòîÿíèÿ áóäóò èìåòü ñîîòíîøåíèå 1.0
CV_MAT_ELEMS(intrinsic_matrix, 0, 0, 1);
CV_MAT_ELEMS(intrinsic_matrix, 1, 1, 1);
// ÊÀËÈÁÐÓÅÌ ÊÀÌÅÐÓ!
cvCalibrateCamera2(object_points2, image_points2, point_counts2, cvGetSize(image), intrinsic_matrix,
distortion_coeffs, nil, nil, 0, // CV_CALIB_FIX_ASPECT_RATIO
cvTermCriteria(CV_TERMCRIT_ITER + CV_TERMCRIT_EPS, 30, DBL_EPSILON));
// ÑÎÕÐÀÍßÅÌ ÂÍÓÒÐÅÍÍÈÅ ÏÀÐÀÌÅÒÐÛ È ÄÈÑÒÎÐÑÈÞ
cvSave('Intrinsics.xml', intrinsic_matrix);
cvSave('Distortion.xml', distortion_coeffs);
// ÏÐÈÌÅÐ ÇÀÃÐÓÇÊÈ ÝÒÈÕ ÌÀÒÐÈÖ ÍÀÇÀÄ Â ÏÐÎÃÐÀÌÌÌÓ:
intrinsic := cvLoad('Intrinsics.xml');
Distortion := cvLoad('Distortion.xml');
// Ñòðîèì êàðòó àíäèñòîðñèè, êîòîðóþ ìû áóäåì èñïîëüçîâàòü
// äëÿ âñåõ ïîñëåäóþùèõ êàäðîâ.
//
mapx := cvCreateImage(cvGetSize(image), IPL_DEPTH_32F, 1);
mapy := cvCreateImage(cvGetSize(image), IPL_DEPTH_32F, 1);
cvInitUndistortMap(intrinsic, Distortion, mapx, mapy);
// Òîëüêî êàìåðà ñíèìàåò, ñðàçó âèäèì ñûðîå
// è íåèñêàæåííîå èçîáðàæåíèå.
//
cvNamedWindow('Undistort');
while Assigned(image) do
begin
t := cvCloneImage(image);
cvShowImage('Calibration', image); // Show raw image
cvRemap(t, image, mapx, mapy, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, cvScalarAll(0)); // Undistort image
cvReleaseImage(t);
cvShowImage('Undistort', image); // Show corrected image
// Handle pause/unpause and ESC
c := cvWaitKey(15);
if (c = Ord('p')) then
begin
c := 0;
while (c <> Ord('p')) and (c <> 27) do
begin
c := cvWaitKey(250);
end;
end;
if (c = 27) then
break;
image := cvQueryFrame(capture);
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.