基于Opencv3.0对图像进行透视变换

一,计算图片
垂直拍摄的标定板
垂直拍摄的标定板

倾斜30度拍摄的标定板
倾斜30度拍摄的标定板

待处理图像
待处理图像

二,矫正效果
矫正效果图
矫正效果图

二,源码
全局变量
//#######################################
std::vectorcv::Point2f 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]);

		//#######################获取内角点坐标########################################################################
	}
}

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;
}

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);
}

欢迎扫码关注我的微信公众号

在这里插入图片描述

图像配准是指将两幅或多幅图像进行对齐,使它们在几何形状和外观上尽可能的相似。而透视变换是一种仿射变换的扩展,可以将一个平面上的任意四边形转换为另一个平面上的任意四边形。 基于OpenCV图像配准之后,可以使用透视变换来实现图像的矫正、纠偏等操作。具体步骤如下: 1. 首先,通过图像配准的方法将待处理的图像对齐,得到对应的变换矩阵; 2. 然后,利用该变换矩阵进行透视变换,将图像进行矫正、纠偏等操作; 3. 最后,可以进行进一步的图像处理,如图像增强、目标检测等。 下面是一个基于OpenCV透视变换示例代码: ``` import cv2 import numpy as np # 读取原始图像 img = cv2.imread('test.png') # 设置目标图像的四个顶点 dst_points = np.float32([[100, 100], [500, 100], [500, 500], [100, 500]]) # 设置原始图像的四个顶点 src_points = np.float32([[10, 10], [630, 10], [630, 470], [10, 470]]) # 计算透视变换矩阵 M = cv2.getPerspectiveTransform(src_points, dst_points) # 进行透视变换 dst_img = cv2.warpPerspective(img, M, (600, 600)) # 显示结果 cv2.imshow('src_img', img) cv2.imshow('dst_img', dst_img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 其中,dst_points 和 src_points 分别表示目标图像和原始图像的四个顶点坐标,通过 cv2.getPerspectiveTransform 方法计算透视变换矩阵 M,然后通过 cv2.warpPerspective 方法进行透视变换,最终得到矫正后的图像 dst_img。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值