Я впервые работаю с OpenCV. Приведенный ниже код использует пакет Emgu, но я также попробовал его с помощью OpenCVSharp и получил точно такие же результаты.
Я калибрую камеру, используя 6 фотографий с шахматной доски, затем использую калибровку, чтобы удалить изображение. Тестовое изображение - это фотография какой-то бумаги в квадрате. Камера на самом деле не очень искажена - я не могу сказать, что она искажена на глаз, только когда я рисую прямую линию над линиями в программе рисования.
Однако - получающееся изображение выходит из-под контроля более искаженный, чем оригинал - добавление большого количества бочкообразных искажений.
Когда я запускаю закомментированные строки, DrawChessboardCorners показывают, что он точно определяет точки.
Что я делаю здесь не так?
static void Main(string[] args)
{
Size patternSize = new Size(9, 6);
List<VectorOfPointF> ListOfCornerPoints = new List<VectorOfPointF>();
DirectoryInfo dir = new DirectoryInfo(@"Z:\Simon\Dropbox\Apps\OpenCVPlay\Image Processing\Chessboard Pattern Photos With Pixel");
Size calibrationImageSize = new Size(0,0) ;
foreach (var file in dir.GetFiles())
{
VectorOfPointF corners = new VectorOfPointF();
var calibrationImage = new Image<Rgb, byte>(file.FullName);
bool find = CvInvoke.FindChessboardCorners(calibrationImage, patternSize, corners, CalibCbType.AdaptiveThresh | CalibCbType.FilterQuads);
//CvInvoke.DrawChessboardCorners(calibrationImage, patternSize, corners, find);
//calibrationImage.Save(@"Z:\Simon\Dropbox\Apps\OpenCVPlay\Image Processing\Chessboard Pattern Photos With Pixel\test\" + file.Name);
ListOfCornerPoints.Add(corners);
calibrationImageSize = calibrationImage.Size;
}
PointF[][] arrayOfCornerPoints = ListOfCornerPoints.Select(a => a.ToArray()).ToArray();
var modelPoints = CreateModelPoints(ListOfCornerPoints.Count, patternSize.Width, patternSize.Height);
var arrayOfModelPoints = modelPoints.Select(a => a.ToArray()).ToArray();
Matrix<double> cameraDistortionCoeffs = new Matrix<double>(5, 1);
Matrix<double> cameraMatrix = new Matrix<double>(3, 3);
Mat[] rotationVectors;
Mat[] translationVectors;
CvInvoke.CalibrateCamera(
arrayOfModelPoints,
arrayOfCornerPoints,
calibrationImageSize,
cameraMatrix,
cameraDistortionCoeffs,
CalibType.Default,
new MCvTermCriteria(),
out rotationVectors,
out translationVectors);
var imageToProcess = new Image<Rgb, byte>(@"Z:\Simon\Dropbox\Apps\OpenCVPlay\Image Processing\Test data\squarePaper.jpg");
Rectangle Rect2 = new Rectangle();
var newCameraMatrix = CvInvoke.GetOptimalNewCameraMatrix(cameraMatrix, cameraDistortionCoeffs, calibrationImageSize, 1, imageToProcess.Size, ref Rect2, true);
Image<Rgb, byte> processedImage = imageToProcess.Clone();
CvInvoke.Undistort(imageToProcess, processedImage, cameraMatrix, cameraDistortionCoeffs);
processedImage.Save(@"Z:\Simon\Dropbox\Apps\OpenCVPlay\Image Processing\Test data\squarePaperFixed.jpg");
}
static List<List<MCvPoint3D32f>> CreateModelPoints(int length, int chessboardCols, int chessboardRows)
{
var modelPoints = new List<List<MCvPoint3D32f>>();
for (var k = 0; k < length; k++)
{
var chessboard = new List<MCvPoint3D32f>();
for (var y = 0; y < chessboardRows; y++)
{
for (var x = 0; x < chessboardCols; x++)
{
chessboard.Add(new MCvPoint3D32f(x, y, 0));
}
}
modelPoints.Add(chessboard);
}
return modelPoints;
}