Delphi-OpenCV/samples/MultiDemo/CameraCalibrate/CameraCalibrate.dpr
Laex 8540f5bd44 Add samples
Multidemo
[+] fback_c (cvCalcOpticalFlowFarneback)
[+] minarea (cvMinEnclosingCircle, cvMinAreaRect2)

Signed-off-by: Laex <laex@bk.ru>
2013-04-06 00:58:24 +04:00

278 lines
9.5 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}
{$POINTERMATH ON}
// JCL_DEBUG_EXPERT_GENERATEJDBG OFF
// JCL_DEBUG_EXPERT_INSERTJDBG OFF
// JCL_DEBUG_EXPERT_DELETEMAPFILE OFF
program CameraCalibrate;
{$R *.res}
uses
System.SysUtils,
uLibName in '..\..\..\include\uLibName.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',
imgproc in '..\..\..\include\imgproc\imgproc.pas',
haar in '..\..\..\include\objdetect\haar.pas',
objdetect in '..\..\..\include\objdetect\objdetect.pas',
tracking in '..\..\..\include\video\tracking.pas',
Core in '..\..\..\include\ñore\core.pas'
;
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;
begin
try
if ParamCount = 3 then
begin
board_w := StrToInt(ParamStr(1));
board_h := StrToInt(ParamStr(2));
n_boards := StrToInt(ParamStr(3));
end
else
begin
board_w := 7;
board_h := 3;
n_boards := 10;
end;
board_n := board_w * board_h;
Writeln('Cells: ', board_n);
board_sz := cvSize(board_w, board_h);
capture := cvCreateCameraCapture(CV_CAP_ANY);
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(TCvPoint2D32f) * 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
Writeln('Successes: ', successes);
// Íàõîäèì óãëû øàõìàòíîé äîñêè:
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 i < board_n do
begin
pSingle(CV_MAT_ELEM(image_points^, SizeOf(single), i, 0))^ := corners[j].x;
pSingle(CV_MAT_ELEM(image_points^, SizeOf(single), i, 1))^ := corners[j].y;
pSingle(CV_MAT_ELEM(object_points^, SizeOf(single), i, 0))^ := j / board_w;
pSingle(CV_MAT_ELEM(object_points^, SizeOf(single), i, 1))^ := j div board_w;
pSingle(CV_MAT_ELEM(object_points^, SizeOf(single), i, 2))^ := 0;
Inc(i);
Inc(j);
end;
pInteger(CV_MAT_ELEM(point_counts^, SizeOf(integer), 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(50);
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
pSingle(CV_MAT_ELEM(image_points2^, SizeOf(single), i, 0))^ := pSingle(CV_MAT_ELEM(image_points^, SizeOf(single), i, 0))^;
pSingle(CV_MAT_ELEM(image_points2^, SizeOf(single), i, 1))^ := pSingle(CV_MAT_ELEM(image_points^, SizeOf(single), i, 1))^;
pSingle(CV_MAT_ELEM(object_points2^, SizeOf(single), i, 0))^ := pSingle(CV_MAT_ELEM(object_points^, SizeOf(single), i, 0))^;
pSingle(CV_MAT_ELEM(object_points2^, SizeOf(single), i, 1))^ := pSingle(CV_MAT_ELEM(object_points^, SizeOf(single), i, 1))^;
pSingle(CV_MAT_ELEM(object_points2^, SizeOf(single), i, 2))^ := pSingle(CV_MAT_ELEM(object_points^, SizeOf(single), i, 2))^;
Inc(i);
end;
i := 0;
While i < successes do
begin // Çäåñü âñå òå æå ÷èñëà
pInteger(CV_MAT_ELEM(point_counts2^, SizeOf(Integer), i, 0))^ := pInteger(CV_MAT_ELEM(point_counts^, SizeOf(Integer), i, 0))^;
Inc(i);
end;
cvReleaseMat(object_points);
cvReleaseMat(image_points);
cvReleaseMat(point_counts);
// Äëÿ ýòèõ òî÷åê ìû èìååì âñå óãëû øàõìàòíîé äîñêè, êîòîðûå íàì íóæíû.
// Èíèöèàëèçèðóåì ìàòðèöó âíóòðåííèõ ïàðàìåòðîâ òàê, ÷òî îáà ôîêàëüíûõ
// ðàññòîÿíèÿ áóäóò èìåòü ñîîòíîøåíèå 1.0
cvZero(intrinsic_matrix);
// pSingle(CV_MAT_ELEM(intrinsic_matrix^, CV_32FC1, 0, 0))^ := 1;
// pSingle(CV_MAT_ELEM(intrinsic_matrix^, CV_32FC1, 1, 1))^ := 1;
// pSingle(CV_MAT_ELEM(intrinsic_matrix^, CV_32FC1, 2, 2))^ := 1;
pSingle(CV_MAT_ELEM(intrinsic_matrix^, SizeOf(single), 0, 0))^ := 520.0;
pSingle(CV_MAT_ELEM(intrinsic_matrix^, SizeOf(single), 1, 1))^ := 520.0;
pSingle(CV_MAT_ELEM(intrinsic_matrix^, SizeOf(single), 2, 2))^ := 1;
pSingle(CV_MAT_ELEM(intrinsic_matrix^, SizeOf(single), 0, 2))^ := 70.0;
pSingle(CV_MAT_ELEM(intrinsic_matrix^, SizeOf(single), 1, 2))^ := 70.0;
for i := 0 to intrinsic_matrix^.rows - 1 do
begin
for j := 0 to intrinsic_matrix^.cols - 1 do
Write(Format('%.0f ', [pSingle(CV_MAT_ELEM(intrinsic_matrix^, SizeOf(single), i, j))^]));
Writeln;
end;
Writeln;
// ÊÀËÈÁÐÓÅÌ ÊÀÌÅÐÓ!
cvCalibrateCamera2(object_points2, image_points2, point_counts2, cvGetSize(image), intrinsic_matrix,
distortion_coeffs, nil, nil,
// {}0,
// {}CV_CALIB_FIX_ASPECT_RATIO,
CV_CALIB_USE_INTRINSIC_GUESS,
{ } cvTermCriteria(CV_TERMCRIT_ITER + CV_TERMCRIT_EPS, 30, DBL_EPSILON));
// ÑÎÕÐÀÍßÅÌ ÂÍÓÒÐÅÍÍÈÅ ÏÀÐÀÌÅÒÐÛ È ÄÈÑÒÎÐÑÈÞ
cvSave('result\Intrinsics.xml', intrinsic_matrix);
cvSave('result\Distortion.xml', distortion_coeffs);
// -------------------------------------------------------------
// ÏÐÈÌÅÐ ÇÀÃÐÓÇÊÈ ÝÒÈÕ ÌÀÒÐÈÖ ÍÀÇÀÄ Â ÏÐÎÃÐÀÌÌÌÓ:
intrinsic := cvLoad('result\Intrinsics.xml');
Distortion := cvLoad('result\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.