OpenCV图像平移示例

OpenCV计算机视觉开发实践:基于Qt C++ - 商品搜索 - 京东

图像平移是将一幅图像中所有的点都按照指定的平移量在水平、垂直方向移动,平移后的图像上的每一个点都可以在原图像中找到对应的点。我们知道,图像是由像素组成的,而像素的集合就相当于一个二维矩阵,每一个像素都有一个"位置",也就是像素都有一个坐标。假设原来的像素的坐标为(x 0,y 0),经过平移量(Dx , Dy )后,坐标变为(x 1,y1),用数学式子可以表示为:

x 1 = x0 +Dx

y 1 = y0 +Dy

平移变换分为两种:一种是图像大小不改变,这样原图像中会有一部分不在平移后的图像中;另一种是图像大小改变,这样可以保全原图像的内容。

【例7.1】实现图像平移

打开Qt Creator,新建一个控制台工程,工程名是test。

在工程中打开main.cpp,输入如下代码:

复制代码
#include <iostream>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <iostream>

// 平移操作,图像大小不变
cv::Mat imageTranslation1(cv::Mat & srcImage, int x0ffset, int y0ffset)
{
	int nRows = srcImage.rows;
	int nCols = srcImage.cols;
	cv::Mat resultImage(srcImage.size(), srcImage.type());
	// 遍历图像
	for (int i = 0; i < nRows; i++)
	{
		for (int j = 0; j < nCols; j++)
		{
			// 映射变换
			int x = j - x0ffset;
			int y = i - y0ffset;
			// 边界判断
			if (x >= 0 && y >= 0 && x < nCols && y < nRows)
			{
				// 把y行x列的srcImage上的图像元素值复制到目标图像(i, j)位置上
				resultImage.at<cv::Vec3b>(i, j) = srcImage.ptr<cv::Vec3b>(y)[x];	
			}
		}
	}
	return resultImage;
}
// 平移操作,图像大小改变
cv::Mat imageTranslation2(cv::Mat & srcImage, int x0ffset, int y0ffset)
{
	// 设置平移尺寸
	// 这里先对目标图像的行进行扩展,扩展到原来图像的行列范围,再加上偏移量绝对值
	int nRows = srcImage.rows + abs(y0ffset);	
 	int nCols = srcImage.cols + abs(x0ffset);
	cv::Mat resultImage(nRows, nCols, srcImage.type());
	// 图像遍历
	for (int i = 0; i < nRows; i++)
	{
		for (int j = 0; j < nCols; j++)
		{
			int x = j - x0ffset;
			int y = i - y0ffset;
			// 边界判断
			if (x >= 0 && y >= 0 && x < nCols && y < nRows)
			{
				resultImage.at<cv::Vec3b>(i, j) = srcImage.ptr<cv::Vec3b>(y)[x]; 
			}
		}
	}
	return resultImage;
}

int main()
{
	// 读取图像
	cv::Mat srcImage = cv::imread("img7.jpg");
	if (srcImage.empty())
	{
		return -1;
	}

	// 显示原图像
	cv::imshow("src", srcImage);
	int x0ffset = 50;
	int y0ffset = 80;
	// 图像左平移不改变大小(相对于原图像,目标图像左移了)
	cv::Mat resultImage1 = imageTranslation1(srcImage, x0ffset, y0ffset);
	cv::imshow("resultImage1", resultImage1);
	// 图像左平移改变大小
	cv::Mat resultImage2 = imageTranslation2(srcImage, x0ffset, y0ffset);
	cv::imshow("resultImage2", resultImage2);
	// 图像右平移不改变大小
	x0ffset = -50;
	y0ffset = -80;
	cv::Mat resultImage3 = imageTranslation1(srcImage, x0ffset, y0ffset);
	cv::imshow("resultImage3", resultImage3);
	cv::waitKey(0);
	return 0;
}

注意映射变换,比如加入offset=2后,目标图像的j =10位置的元素值对应原图像的j=8位置的元素值。原图像(0,0)放到目标图像(xOffset,yOffset)。另外,Vec3b是一种图像像素值的类型。

保存工程并运行,结果如图7-1所示。

图7-1

相关推荐
NEFU_Jyj6 小时前
牛客周赛R168
算法
陈嘿萌9 小时前
TIP 2026 | 不再混成一张! RealFusion从模态不变性重想图像融合
图像处理·人工智能·深度学习·计算机视觉·学术研究与理论基础
Navigator_Z13 小时前
LeetCode //C - 1317. Convert Integer to the Sum of Two No-Zero Integers
c语言·算法·leetcode
D e re k ZH14 小时前
C++ 标准库算法全景指南
数据结构·c++·算法
冻柠檬飞冰走茶15 小时前
字母移动游戏题解:贪心求最长可保留连续子串(附 C 实现)
c语言·开发语言·数据结构·算法·动态规划
雪落漂泊15 小时前
C++算法 二分查找篇(上)
开发语言·c++·算法
LabVIEW开发17 小时前
LabVIEW 连接板:28 个端子怎么排,优先级怎么定
java·算法·labview
严肃小白兔18 小时前
MATLAB 数值计算中的精度与误差问题:浮点运算、误差传播与数值稳定性
人工智能·算法·matlab
青少儿编程课堂19 小时前
蓝桥杯青少组图形化省考报名倒计时·全国青少年信息素养大赛·电子学会图形化考级:校园黑白棋人机对战解析
c++·python·算法·bfs·信息学竞赛