基于Opencv3.0对图像进行透视变换
一,计算图片
垂直拍摄的标定板
倾斜30度拍摄的标定板
待处理图像
二,矫正效果
矫正效果图
二,源码
全局变量
//#######################################
std::vector pointsCZ, pointsQX; //垂直,倾斜
//#######################################
1,计算标定板,获取内角点坐标
//标定板内角点计算
void C透视变换Dlg::OnBnClickedButton1()
{
ofstream oFileExcel1;
ofstream oFileExcel2;
string strExcel1 = "D:\\程序测试图片\\7_7自定义标定板2\\垂直30Excel1.csv";
oFileExcel1.open(strExcel1.c_str(), ios::out | ios::trunc);
string strExcel2 = "D:\\程序测试图片\\7_7自定义标定板2\\倾斜30Excel2.csv";
oFileExcel2.open(strExcel2.c_str(), ios::out | ios::trunc);
cv::Mat calibmat[2];
int width, height;
calibmat[0] = imread("D:\\程序测试图片\\7_7自定义标定板2\\cz16cm0.bmp", 4);
calibmat[1] = imread("D:\\程序测试图片\\7_7自定义标定板2\\x30_0.bmp", 4);
width = calibmat[0].cols;
height = calibmat[0].rows;
//#######################获取内角点坐标########################################################################
bool iffindpoint;
iffindpoint = findChessboardCorners(calibmat[0], cv::Size(7, 9), pointsCZ, CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE + CALIB_CB_FAST_CHECK);
if (iffindpoint)
{
for (int i = 0; i < pointsCZ.size(); i++)
{
oFileExcel1 << "[x:y]" << "," << pointsCZ[i].x << "," << pointsCZ[i].y << ",";
if ((i + 1) % 7 == 0)
{
oFileExcel1 << endl;
}
}
oFileExcel1.close();
drawChessboardCorners(calibmat[0], cv::Size(7, 9), pointsCZ, true); //用于在图片中标记角点
imwrite("D:\\程序测试图片\\7_7自定义标定板2\\垂直30.bmp", calibmat[0]);
}
iffindpoint = findChessboardCorners(calibmat[1], cv::Size(7, 9), pointsQX, CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE + CALIB_CB_FAST_CHECK);
if (iffindpoint)
{
for (int i = 0; i < pointsQX.size(); i++)
{
oFileExcel2 << "[x:y]" << "," << pointsQX[i].x << "," << pointsQX[i].y << ",";
if ((i + 1) % 7 == 0)
{
oFileExcel2 << endl;
}
}
drawChessboardCorners(calibmat[1], cv::Size(7, 9), pointsQX, true); //用于在图片中标记角点
imwrite("D:\\程序测试图片\\7_7自定义标定板2\\倾斜30.bmp", calibmat[1]);
//#######################获取内角点坐标########################################################################
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
2,通过上面获得的对应角点坐标,取其中不在同一平面上的4点计算转换矩阵,并通过转换矩阵矫正图像
//4点透视变换
void C透视变换Dlg::OnBnClickedTestButton()
{
//###################################################################################################
//获取映射矩阵
//###################################################################################################
// get original image.
cv::Mat originalImage = cv::imread("D:\\程序测试图片\\7_7自定义标定板2\\dx30_1.bmp", 4);
// perspective image.
cv::Mat perspectiveImage;
// perspective transform
cv::Point2f objectivePoints[4], imagePoints[4];
imagePoints[0].x = 923.43; imagePoints[0].y = 1284.55;
imagePoints[1].x = 938.906; imagePoints[1].y = 857.076;
imagePoints[2].x = 1590; imagePoints[2].y = 853.5;
imagePoints[3].x = 1619.71; imagePoints[3].y = 1277.56;
// objective points of perspective image.
// move up the perspective image : objectivePoints.y - value .
// move left the perspective image : objectivePoints.x - value.
double moveValueX = 0.0;
double moveValueY = 0.0;
objectivePoints[0].x = 717.5 + moveValueX; objectivePoints[0].y = 1380.5 + moveValueY;
objectivePoints[1].x = 714.5 + moveValueX; objectivePoints[1].y = 750.5 + moveValueY;
objectivePoints[2].x = 1562.82 + moveValueX; objectivePoints[2].y = 745.389 + moveValueY;
objectivePoints[3].x = 1563.13 + moveValueX; objectivePoints[3].y = 1379.65 + moveValueY;
//获取转换矩阵 //原点 //目标点
cv::Mat transform = cv::getPerspectiveTransform(objectivePoints, imagePoints);
// 透视变换
cv::warpPerspective(originalImage,
perspectiveImage,
transform,
cv::Size(originalImage.rows, originalImage.cols),
cv::INTER_LINEAR | cv::WARP_INVERSE_MAP);
// cv::imshow("perspective image", perspectiveImage);
// cvWaitKey(0);
//cv::imwrite("D:\\程序测试图片\\透视变换原图.bmp", originalImage);
cv::imwrite("D:\\程序测试图片\\7_7自定义标定板2\\dx30_1透视变换矫正图.bmp", perspectiveImage);
//return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
3,通过1计算出的所有角点坐标计算转换矩阵,并通过转换矩阵矫正图像
//多点透视变换
void C透视变换Dlg::OnBnClickedButton2()
{
//###################################################################################################
//获取映射矩阵
//###################################################################################################
Mat math, origimg, desimg, mask;
math = cv::findHomography(pointsQX, pointsCZ, mask);
origimg = imread("D:\\程序测试图片\\7_7自定义标定板2\\y30_0.bmp", 4);//读取垂直标定图像
//cv::perspectiveTransform(origimg,desimg,math);
cv::warpPerspective(origimg, desimg, math, Size(origimg.cols, origimg.rows));
imwrite("D:\\程序测试图片\\7_7自定义标定板2\\y30_0opencv多点矫正.bmp", desimg);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
<link href="https://****img.cn/release/phoenix/mdeditor/markdown_views-7f770a53f2.css" rel="stylesheet">
</div>
一,计算图片
垂直拍摄的标定板