(opencv)图像几何变换——平移

news2024/12/26 0:36:01

图像的平移操作是将图像的所有像素坐标进行水平或垂直方向移动,也就是将所有像素点按照给定的偏移量在水平方向沿x轴、垂直方向上沿y轴移动。平移变换分为两种类型:图像大小变化与图像大小不变。第一种类型保证图像平移的完整信息,第二种图像导致原始图像的部分信息可能丢失。图像平移变换公式如下:(不会用csdn自带的公式编辑器,使用mathtype打出来再截图的)

 对4*4图像矩阵向右平移x轴一个单位,向下平移y轴一个单位,若移动后图像的大小保持不变,多余部分填充为白色时满足:

对4*4图像矩阵向左平移x轴一个单位,向上平移y轴一个单位,若移动后图像的大小变换,多余部分填充为白色时满足:

 

举例说明: 

#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
using namespace std;
using namespace cv;

//平移操作,图像大小不变
Mat imgTranslation1(Mat& src, int xOffset, int yOffset)
{
	int nRows = src.rows;
	int nCols = src.cols;
	Mat result (src.size(), src.type());
	//遍历图像
	for (int i = 0; i < nRows; ++i)
	{
		for (int j = 0; j < nCols; ++j)
		{
			int x = j - xOffset;
			int y = i - yOffset;
			if (x >= 0 && y >= 0 && x < nCols && y < nRows)
			{
				result.at<Vec3b>(i, j) = src.ptr<Vec3b>(y)[x];
			}
		}
	}
	return result;
}

//平移操作,图像大小改变
Mat imgTranslation2(Mat& src, int xOffset, int yOffset)
{
	//设置平移尺寸
	int nRows = src.rows + abs(yOffset);
	int nCols = src.cols + abs(xOffset);
	Mat result(nRows,nCols, src.type());
	//遍历图像
	for (int i = 0; i < nRows; ++i)
	{
		for (int j = 0; j < nCols; ++j)
		{
			//映射变换
			int x = j - xOffset;
			int y = i - yOffset;
			if (x >= 0 && y >= 0 && x < nCols && y < nRows)
			{
				result.at<Vec3b>(i, j) = src.ptr<Vec3b>(y)[x];
			}
		}
		
	}
	return result;
}
int main()
{
	Mat src = imread("C:\\Users\\32498\\Pictures\\16.png");
	if (!src.data)
	{
		return -1;
	}
	imshow("src", src);
	int xOffset = 50, yOffset = 80;
	//图像左平移不改变大小
	Mat dst1 = imgTranslation1(src, xOffset, yOffset);
	imshow("dst1", dst1);
	//图像左平移改变大小
	Mat dst2 = imgTranslation2(src, xOffset, yOffset);
	imshow("dst2", dst2);
	//图像右平移不改变大小
	Mat dst3 = imgTranslation1(src, -xOffset, -yOffset);
	imshow("dst3", dst3);
	waitKey();
	return 0;

}

运行结果如下: 

 

 对程序中的此行代码进行说明

result.at<Vec3b>(i, j) = src.ptr<Vec3b>(y)[x];

result图像(i,j)处的像素值等于src图像第y行,第x个坐标的像素值。这其实是对图像进行逐像素操作。

 ①opencv中的Mat数据类型指针ptr的使用

    cv::Mat image = cv::Mat(400, 600, CV_8UC1); //宽400,长600
    uchar * data00 = image.ptr<uchar>(0);
    uchar * data10 = image.ptr<uchar>(1);
    uchar * data01 = image.ptr<uchar>(0)[1];

        对上面的注解:(注意看这些的区别)

定义一个Mat变量image,

data00是指向image第一行第一个元素的指针

data10是指向image第二行第一个元素的指针

data01是指向image第一行第二个元素的指针 

②Vec3b类型的含义

Vec3b可以看作是vector<uchar,3>,即一个uchar类型,长度为3的vector向量。(不知道vector容器含义的同学可以这样理解vector,它就是一个数组,只不过这个数组的大小可以随时改变,故称vector为动态数组)

由于在opencv中读取到的Mat图像数据都是用uchar类型的数据存储,对于RGB三通道的图像,每个点的数据都是一个vec3b类型的数据。

使用at定位方法如下:

Mat img=imread("123.png");

//(row,col)为所需要定位点的坐标
img.at<Vec3b>(row,col)[0]=255; //修改点(row,col)的B通道数据
img.at<Vec3b>(row,col)[1]=255; //修改点(row,col)的G通道数据
img.at<Vec3b>(row,col)[2]=255; //修改点(row,col)的R通道数据


 同时还需要注意的是,它返回的是uchar类型,直接使用cout输出为字符格式,需要强制转换为int 类型之后输出:


cout<<(int)img.at<Vec3b>(row,col)[0];

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/630703.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue.js 中的 $refs 和 $emit 有什么关系?

Vue.js 中的 $refs 和 $emit 有什么关系&#xff1f; 在 Vue.js 中&#xff0c;$refs 和 $emit 都是非常常用的 API。$refs 用于访问组件、元素和子组件等&#xff0c;而 $emit 则用于在组件之间进行通信。本文将会从语法、使用方式、适用场景等方面进行介绍&#xff0c;并探讨…

接招吧! selenium环境+元素定位大法

selenium 与 webdriver Selenium 是一个用于 Web 测试的工具&#xff0c;测试运行在浏览器中&#xff0c;就像真正的用户在手工操作一样。支持所有主流浏览器 WebDriver 就是对浏览器提供的原生API进行封装&#xff0c;使其成为一套更加面向对象的Selenium WebDriver API。 …

【数据结构与算法分析】使用C语言实现队列的两种(带头结点与不带头结点)链式存储,并且给出一种循环队列的设计思想

文章目录 前言队列实现带头结点单向队列不带头结点单向队列循环队列 总结 前言 当我们编写程序时&#xff0c;经常需要处理各种数据结构。队列是一种常见的数据结构&#xff0c;它有着广泛的应用场景。队列的基本操作包括入队和出队&#xff0c;应用于模拟等待队列、消息队列、…

LVS-DR集群

LVS-DR集群 一.LVS-DR工作原理 1.数据包流向 数据包流向分析&#xff1a; &#xff08;1&#xff09;客户端发送请求到 Director Server&#xff08;负载均衡器&#xff09;&#xff0c;请求的数据报文&#xff08;源 IP 是 CIP,目标 IP 是 VIP&#xff09;到达内核空间。 &…

Flowable工作流入门完整SpringBoot案例

文章目录 一 、Flowable 的出现是为了什么二、Flowable 的优势三、常见的Java类/实例3.1 ProcessEngine3.2 RepositoryService3.3 ProcessDefinition3.4 Deployment3.5 RuntimeService3.6 ProcessInstance3.7 TaskService3.8 JavaDelegate3.9 其他 四、核心数据库表4.1 数据库4…

CET4写译学习

学习记录笔记&#xff1a; 05.四级写译技巧(上)_哔哩哔哩_bilibili 不会的东西不要往上写。寻找可以替换的词。 保证写的所有内容都是正确的。 切题&#xff0c;论证清楚。 要有自己的观点&#xff0c;然后去论证。 词汇&#xff0c;语法&#xff0c;句子结构都整好。 文…

【软件测试】接口测试工具APIpost

说实话&#xff0c;了解APIpost是因为&#xff0c;我的所有接口相关的文章下&#xff0c;都有该APIpost水军的评论&#xff0c;无非就是APIpost是中文版的postman&#xff0c;有多么多么好用&#xff0c;虽然咱也还不是什么啥网红&#xff0c;但是不知会一声就乱在评论区打广告…

Linux日志

rsyslog系统日志管理 哪类程序产生的什么日志放到什么地方 处理日志的进程 第一类&#xff1a; rsyslogd&#xff1a;系统专职日志程序&#xff0c;处理绝大部分日志记录&#xff0c;系统操作相关的信息&#xff0c;如登录信息&#xff0c;程序启动关闭相关信息&#xff0c…

C#语言实现4K图片放大缩小和平移显示性能的速度测试

在介绍“熊猫视图.Net图形控件”系列文章中&#xff0c; 【“熊猫视图.Net图形控件”介绍链接】https://blog.csdn.net/mosangbike/article/details/126026801有对显示图像文件的测试结果&#xff0c;当时测试的不太严谨。今天抽时间详细测试了一下。 从网上找了一张Jpg图像作…

亲宝宝 实习 面经

目录 1.char varchar 长度是字符数还是字节数 编码格式2.整型数据类型3.decimal及其实现4.慢查询5.索引失效6.explain7.for foreach性能差异8.数据库事务隔离级别9.binlog redolog 二阶段提交10.redis数据类型11.redis实现消息队列12.mybatis传参方法13.insert返回主键 1.char …

数据库实验一 数据库和数据表的建立、修改和删除

任务描述 本关任务&#xff1a;建立数据库 为了完成本关任务&#xff0c;你需要掌握&#xff1a; 如何创建数据库&#xff0c;显示已经建立的数据库 相关知识 创建数据库 创建数据库是在系统磁盘上划分一块区域用于数据的存储和管理。 命令格式&#xff1a; CREATE DATABA…

粮油智能制造MES追溯系统源码

粮油生产加工MES追溯系统源码 粮油生产加工MES追溯系统&#xff0c;实现从种植、加工、检验、销售各个环节的数据采集。 粮油MES质量管控防伪溯源系统可广泛用于粮油生产加工领域。实现种植主体、种植基地、生产计划、压榨、精炼、包装、销售、物料管理、检验检测等各个环节的…

Java对象拷贝MapStruct

介绍 编译期即可生成对象复制代码。简单理解&#xff0c;功能定位org.springframework.beans.BeanUtils。 官网&#xff0c;GitHub-MapStruct。 入门 maven项目引入依赖&#xff1a; mapstruct&#xff1a;包含必要注解&#xff0c;如Mappingmapstruct-processor&#xff1…

Cereal 靶机

环境准备 靶机链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;bcj2 虚拟机网络链接模式&#xff1a;桥接模式 攻击机系统&#xff1a;kali linux 2021.1 信息收集 1.探测目标靶机 arp-scan -l 2.nmap -p- -A -T4 192.168.1.107 探测目标靶机开放端口和服务 漏…

我是如何入门网络安全?有什么自学心得?

我是如何入门&#xff0c;网络安全的 那年我高三毕业的时候要填志愿前几天 我妈问我想学什么专业。 我说&#xff0c;想学网络设计、或者计算机、网络安全工程师 那时候还比较年轻&#xff0c;也对网络&#xff0c;计算机这方面感兴趣嘛 于是我妈和我爸决定让我学网管。 我…

卡尔曼滤波与组合导航原理(十三)无迹卡尔曼滤波UKF

一、蒙特卡洛仿真 蒙特卡洛仿真的基本原理是通过生成大量的随机样本&#xff0c;以近似地估计实际事件的概率和预测结果。 它是以蒙特卡洛赌场命名的&#xff0c;因为它使用随机数和概率统计的方法来模拟现实世界中的各种情况和结果&#xff0c;就像在赌场中抛骰子或发牌一样。…

LeetCode_Day6 | 有效的字母异位词、两个数组的交集、快乐数、两数之和!

LeetCode_哈希表 242.有效的字母异位词1.题目描述2.题解 349.两个数组的交集1.题目描述2.题解 202.快乐数1.题目描述2.题解思路(官方题解啊&#xff01;看了好几遍真难) 3.算法4.代码实现5.复杂度分析 1.两数之和1.题目描述2.哈希表法3.代码实现 242.有效的字母异位词 1.题目描…

《三》TypeScript 中函数的类型

TypeScript 允许指定函数的参数和返回值的类型。 函数声明的类型定义&#xff1a;function 函数名(形参: 形参类型, 形参: 形参类型, ...): 返回值类型 {} function sum(x: number, y: number): number {return x y } sum(1, 2) // 正确 sum(1, 2, 3) // 错误。输入多余的或者…

CAN总线竞争与仲裁机制分析

1、CAN总线的接口 (1)CAN总线是串行、差分信号、异步总线&#xff0c;传输数据用两根信号线组成的差分信号线&#xff1b; (2)CANH和CANL是一组双绞线&#xff0c;两根线的电平差值表示逻辑1和0&#xff1b; 2、CAN总线显性、隐形电平 显性电平代表逻辑0&#xff0c;隐形电平代…

【Prometheus】mysqld_exporter+Grafana+AlertManager预警

环境 prometheus-2.44.0 mysqld_exporter-0.14.0 grafana-enterprise-9.1.2-1.x86_64.rpm alertmanager-0.25.0. 简介 mysql_exporter是用来收集MysQL或者Mariadb数据库相关指标的&#xff0c;mysql_exporter需要连接到数据库并有相关权限。既可以用二进制安装部署&#xff0c;…