OpenCV图像旋转、缩放、翻转、仿射变换的坐标变换计算

文章目录

  • 前言
  • 一、旋转+缩放+翻转
  • 二、仿射变换


前言

在工业领域进行目标检测的时候,可能会需要先对图像进行旋转校正、多幅图像拼接等操作。这就需要我们将检测到的目标坐标映射到处理后的图像上。下面说几种OpenCV下常用的坐标变换计算,旋转、缩放、翻转和仿射变换,完全同步对应OpenCV的图像处理操作。


一、旋转+缩放+翻转

代码展示的是主要逻辑,稍微改一改就可以用到项目里去。m_img是原图,m_src_corners是你需要转换的原图中的坐标集合。

	Mat image = m_img;
	cv::Point2f center((float(image.cols / resize_scale / 2)), (float)(image.rows / resize_scale / 2));
	cv::Mat rot = cv::getRotationMatrix2D(center, angle, 1);    //获得图像绕中心点旋转angle角度的旋转矩阵 R2*3
	cv::Rect bbox = cv::RotatedRect(center, Size(image.cols / resize_scale, image.rows / resize_scale), angle).boundingRect();//返回包含旋转矩形的最小矩形

	rot.at<double>(0, 2) += bbox.width / 2.0 - center.x;  //x方向的偏移量Tx
	rot.at<double>(1, 2) += bbox.height / 2.0 - center.y; //y方向的偏移量Ty

	m_rot_trans = rot;
	m_dx = bbox.width / 2 - center.x;
	m_dy = bbox.height / 2 - center.y;
	
	for (auto& pt : m_src_corners)
	{
		Mat p = Mat::ones(3, 1, CV_64F);		
		p.at<double>(0) = pt.x / resize_scale;
		p.at<double>(1) = pt.y / resize_scale;
		Mat pp = m_rot_trans * p;
		
		p.at<double>(0) = pp.at<double>(0) - m_dx;
		p.at<double>(1) = pp.at<double>(1) - m_dy;

		if (flip_code == FLIP_X)
		{
			p.at<double>(1) = image.rows / resize_scale - p.at<double>(1);
			
		} else if (flip_code == FLIP_Y)
		{
			p.at<double>(0) = image.cols / resize_scale - p.at<double>(0);
		} else if (flip_code == FLIP_BOTH)
		{
			p.at<double>(0) = image.cols / resize_scale - p.at<double>(0);
			p.at<double>(1) = image.rows / resize_scale - p.at<double>(1);
		}

		Point2f dst_pt;
		dst_pt.x = p.at<double>(0);
		dst_pt.y = p.at<double>(1);
		m_dst_corners.push_back(dst_pt);
	}

二、仿射变换

需要注意的是仿射变换需要除以z

	Mat p = Mat::ones(3, 1, CV_64F);
	p.at<double>(0) = pt.x;
	p.at<double>(1) = pt.y;
	Mat pp = trans * p;
	Point2f result;
	result.x = pp.at<double>(0) / pp.at<double>(2);
	result.y = pp.at<double>(1) / pp.at<double>(2);

你可能感兴趣的:(opencv,opencv,仿射变换,图像旋转,坐标变换)