OpenCV(十一):图像仿射变换

目录

1.图像仿射变换介绍

 仿射变换:

仿射变换矩阵:

仿射变换公式:

2.仿射变换函数

仿射变换函数:warpAffine()

图像旋转:getRotationMatrix2D()

计算仿射变换矩阵:getAffineTransform() 

3.demo


1.图像仿射变换介绍

 仿射变换:

       仿射变换是由平移、缩放、旋转、翻转和错切组合得到,也称为三点变换。

仿射变换矩阵:

       仿射变换可以通过一个2x3的仿射变换矩阵来表示,该矩阵包含了平移、缩放、旋转和剪切等变换的参数。仿射变换矩阵的一般形式如下:

| A B Tx |

| C D Ty |

其中 (A, B) 和 (C, D) 控制了图像的旋转和缩放,(Tx, Ty) 控制了图像的平移。

仿射变换公式:

       对于一个点 P(x, y) 在原始坐标系中,经过仿射变换后得到的新坐标 P'(x', y') 可以通过以下公式计算:

x' = A * x + B * y + Tx

y' = C * x + D * y + Ty

其中,

  • (x, y) 是原始坐标系中点的坐标。

  • (x', y') 是仿射变换后点的新坐标。

  • A、B、C 和 D 是控制旋转、缩放和剪切的矩阵元素。

  • Tx 和 Ty 是平移的量。

这两个公式描述了仿射变换对坐标点的影响。通过适当地设置矩阵元素和平移量,你可以实现各种类型的仿射变换,包括平移、旋转、缩放和剪切。

2.仿射变换函数

仿射变换函数:warpAffine()

void cv::warpAffine ( InputArray    src,

OutputArray    dst,

InputArray        M,

Size                    dsize,

int                      flags = INTER_LINEAR,

int                      borderMode =BORDER CONSTANT,

const Scalar &    borderValue = scalar()

  • src:输入图像
  • dst:仿射变换后输出图像,与src数据类型相同,但是尺寸与dsize相同
  • M:2X3的变换矩阵。
  • dsize:输出图像的尺寸
  • flags:插值方法标志
  • borderMode:像素边界外推方法的标志
  • borderValue:填充边界使用的数值,默认情况下为0

其中,边界填充方法和对应标志:

图像旋转:getRotationMatrix2D()

Mat cv::getRotationMatrix2D ( Point2f center.

double angle

double scale

  • center:图像旋转的中心位置。
  • angle:图像旋转的角度,单位为度,正值为逆时针旋转。
  • scale: 两个轴的比例因子,可以实现旋转过程中的图像缩放,不缩放输入1。

计算仿射变换矩阵:getAffineTransform() 

Mat cv::getAffineTransform ( const Point2f src[]

const Point2f dst[]

)

  • src[]:原图像中的三个像素坐标。
  • dst[]:目标图像中的三个像素坐标。

3.demo

#include <jni.h>
#include <string>
#include <android/bitmap.h>
#include <opencv2/opencv.hpp>
#include <iostream>
#include <android/log.h>#define LOG_TAG "xxx"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)using namespace cv;
using namespace std;
extern "C"
JNIEXPORT void JNICALL
Java_com_example_myapplication_MainActivity_opencv_1test(JNIEnv *env, jclass clazz,jobject bitmap) {AndroidBitmapInfo info;void *pixels;CV_Assert(AndroidBitmap_getInfo(env, bitmap, &info) >= 0);//判断图片是位图格式有RGB_565 、RGBA_8888CV_Assert(info.format == ANDROID_BITMAP_FORMAT_RGBA_8888 ||info.format == ANDROID_BITMAP_FORMAT_RGB_565);CV_Assert(AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0);CV_Assert(pixels);//将bitmap转化为Mat类  原图像MatMat image(info.height, info.width, CV_8UC4, pixels);Mat rotation0,img_warp0;double angle=30;//设置图像的旋转角度Size dst_size(image.rows,image.cols);//设置输出图像Point2f center(image.rows/2.0,image.cols/2.0);//设置图像的旋转中心rotation0=getRotationMatrix2D(center,angle,1);//计算仿射变换矩阵warpAffine(image,img_warp0,rotation0,dst_size);imwrite("/sdcard/DCIM/img_warp0.jpg",img_warp0);//根据定义的三个点进行仿射变换Point2f src_points[3];Point2f dst_points[3];//原始图像中的三个点src_points[0]=Point2f(0,0);src_points[1]=Point2f (0,(float )(image.cols-1));src_points[2]=Point2f ((float )(image.rows-1),(float )(image.cols-1));//仿射变换后图像中的三个点dst_points[0]=Point2f ((float )(image.rows)*0.11,(float )(image.cols)*0.20);dst_points[1]=Point2f ((float )(image.rows)*0.15,(float )(image.cols)*0.70);dst_points[2]=Point2f ((float )(image.rows)*0.81,(float )(image.cols)*0.85);Mat rotation1,img_warp1;rotation1= getAffineTransform(src_points,dst_points);//根据对应点求取仿射变换矩阵warpAffine(image,img_warp1,rotation1,dst_size);//进行仿射变换imwrite("/sdcard/DCIM/img_warp1.jpg",img_warp1);}

         (img_warp0)                                                (img_warp1) 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

openGauss学习笔记-52 openGauss 高级特性-LLVM

文章目录 openGauss学习笔记-52 openGauss 高级特性-LLVM52.1 适用场景52.2 非适用场景52.3 其他因素对LLVM性能的影响52.4 LLVM使用建议 openGauss学习笔记-52 openGauss 高级特性-LLVM openGauss借助LLVM&#xff08;Low Level Virtual Machine&#xff09;提供的库函数&…

3D风速仪 Gill Instruments Limited_R3-50 R3-100 and R3A -100 Manual

R3测量超声波脉冲从上部换能器到相反的下部换能器所花费的时间&#xff0c;并将其与脉冲从下部换能器到上部换能器的时间进行比较。 同样&#xff0c;在其他上下换能器之间比较时间。 如图1所示&#xff0c;每对换能器之间沿轴的空气速度可以从每条轴上的飞行次数计算出来。 …

计算机网络 第二节

目录 一&#xff0c;计算机网络的分类 1.按照覆盖范围分 2.按照所属用途分 二&#xff0c;计算机网络逻辑组成部分 1.核心部分 &#xff08;通信子网&#xff09; 1.1电路交换 1.2 分组交换 两种方式的特点 重点 2.边缘部分 &#xff08;资源子网&#xff09; 进程通信的方…

SAP如何添加货币类型。TCODE : OY03

最近公司业务增加了个白俄罗斯的卢布货币收入BYN 类型。系统没有这个类型&#xff08;系统有BYR&#xff09;&#xff0c;于是我找了下资料。添加货币类型步骤如下。或者TCODE&#xff1a; OY03

$nextTick使用

在Vue中&#xff0c;$nextTick是一个实例方法&#xff0c;用于在DOM更新之后执行回调函数。它可以用于在更新视图后执行一些操作&#xff0c;例如访问更新后的DOM元素或执行其他异步任务。 以下是$nextTick的使用方法&#xff1a; this.$nextTick(() > {// 在DOM更新后执行…

Ubuntu本地快速搭建web小游戏网站,公网用户远程访问【内网穿透】

文章目录 前言1. 本地环境服务搭建2. 局域网测试访问3. 内网穿透3.1 ubuntu本地安装cpolar内网穿透3.2 创建隧道3.3 测试公网访问 4. 配置固定二级子域名4.1 保留一个二级子域名4.2 配置二级子域名4.3 测试访问公网固定二级子域名 前言 网&#xff1a;我们通常说的是互联网&am…

【JAVA+Geoserver】使用Geoserver的REST API发布样式,文本丢失问题,已解决

文章目录 问题描述原因分析在geoserver检查sld文本推测一、是否是geoserver-manager的API优化sld文本&#xff0c;导致文本内容丢失结论&#xff1a;geoserver-manager并没有优化文本 推测二、API接口本身就有问题结论&#xff1a;可以确定是geoserver的内部出现问题 解决方法在…

Zookeeper的使用

一、Zookeeper简介 分布式协调框架&#xff0c;小型的树形结构数据共享储存系统。 zookeeper的应用场景 集群管理 注册中心 配置中心 发布者将数据发布到ZooKeeper一系列节点上面&#xff0c;订阅者进行数据订阅&#xff0c;当数据有变化时&#xff0c;可及时得到数据的变…

SQLServer2008数据库还原失败 恢复失败

源地址&#xff1a;http://www.taodudu.cc/news/show-1609349.html?actiononClick 还原数据库问题解决方案 在还原数据库“Dsideal_school_db”时&#xff0c;有时会遇见上图中的问题“因为数据库正在使用&#xff0c;所以无法获得对数据库的独占访问权”&#xff0c;此时我们…

IDEA对Web和Tomcat的一些配置

这里只是做了自己学习中的一点记录&#xff0c;仅供参考哈&#xff01; 配置Tomcat Modules新增Web 新增module后新增Artifacts 新增Artifacts后Tomcat新增布署 将指定的module由普通java项目变成web项目 直接创建布署到Tomcat时所需要的Aritifacts包 配置Servlet的依赖包 配置…

互联网医院|互联网医院系统开发

在数字化时代的浪潮中&#xff0c;互联网医院系统凭借其突出的系统特色、卓越的功能和方便的使用&#xff0c;正在引领着医疗行业的革新与进步。如今&#xff0c;我们将为您全方位地介绍这一医疗领域的创新力量。 1、系统特色&#xff1a;真实还原、医疗无限 互联网医院系统以…

uniapp 微信小程序 锚点跳转

uniapp文档 以下是我遇到的业务场景&#xff0c;是点击商品分类的某一类 然后页面滚动至目标分类&#xff0c; 首先第一步是设置锚点跳转的目的地&#xff0c;在目标的dom上面添加id属性 然后给每个分类每一项添加点击事件&#xff0c;分类这里的item数据里面有一字段是和上…