Kotlin Bytedeco OpenCV 图像图像54 透视变换 图像矫正

Kotlin Bytedeco OpenCV 图像图像54 透视变换 图像矫正

  • 1 添加依赖
  • 2 测试代码
  • 3 测试结果

在OpenCV中,仿射变换(Affine Transformation)和透视变换(Perspective Transformation)是两种常用的图像几何变换方法。

变换方法适用场景
仿射变换简单的几何变换(平移、旋转、缩放、剪切)。
透视变换改变图像视角和模拟3D投影效果。
变换方法解释特点应用场景实现方法
仿射变换仿射变换是一种线性变换,它保持了图像中直线的直线性和平行线的平行性。常见的仿射变换包括平移、旋转、缩放、剪切等。输入空间和输出空间之间存在线性关系。
直线和平行性在变换后保持不变,但角度和长度可能发生改变。
图像平移、旋转或缩放。
图像对齐(如在模板匹配中的坐标对齐)。
简单的几何变形,如剪切变换。
准备变换矩阵(2x3)。
使用 OpenCV 的 cv2.warpAffine() 方法进行变换。
透视变换透视变换是一种非线性变换,用于将图像从一个平面映射到另一个平面。它允许改变图像的视角,从而获得三维的透视效果。输入空间和输出空间之间是非线性的。
直线保持直线,但平行线不再平行。
需要 4 对点来定义变换关系。
图像校正(如将拍摄的书本照片调整为平面图)。
视角转换(如模拟3D效果或鸟瞰视图)。
投影变换(如在增强现实中的投影映射)。
定义输入和输出平面上的 4 个对应点。
使用 cv2.getPerspectiveTransform() 获取 3x3 的透视变换矩阵。
使用 cv2.warpPerspective() 方法进行变换。

1 添加依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://maven.apache.org/POM/4.0.0"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.xu</groupId><artifactId>KotlinOpenCV</artifactId><version>1.0</version><properties><kotlin.version>2.0.0</kotlin.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><kotlin.code.style>official</kotlin.code.style><kotlin.compiler.jvmTarget>1.8</kotlin.compiler.jvmTarget></properties><repositories><repository><id>mavenCentral</id><url>https://repo1.maven.org/maven2/</url></repository></repositories><dependencies><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.29</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-compress</artifactId><version>1.27.0</version></dependency><dependency><groupId>org.tukaani</groupId><artifactId>xz</artifactId><version>1.10</version></dependency><dependency><groupId>org.jetbrains.kotlinx</groupId><artifactId>kotlinx-coroutines-core</artifactId><version>1.9.0-RC</version></dependency><!--        <dependency>--><!--            <groupId>org.opencv</groupId>--><!--            <artifactId>opencv</artifactId>--><!--            <version>4100</version>--><!--            <scope>system</scope>--><!--            <systemPath>${project.basedir}/lib/opencv/opencv-4100.jar</systemPath>--><!--        </dependency>--><dependency><groupId>org.bytedeco</groupId><artifactId>opencv-platform</artifactId><version>4.10.0-1.5.11</version></dependency><!--        <dependency>--><!--            <groupId>org.bytedeco</groupId>--><!--            <artifactId>ffmpeg-platform</artifactId>--><!--            <version>6.1.1-1.5.10</version>--><!--        </dependency>--><dependency><groupId>org.jetbrains.kotlin</groupId><artifactId>kotlin-test-junit5</artifactId><version>2.0.0</version><scope>test</scope></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>5.10.0</version><scope>test</scope></dependency><dependency><groupId>org.jetbrains.kotlin</groupId><artifactId>kotlin-stdlib</artifactId><version>2.0.0</version></dependency></dependencies><build><sourceDirectory>src/main/kotlin</sourceDirectory><testSourceDirectory>src/test/kotlin</testSourceDirectory><plugins><plugin><groupId>org.jetbrains.kotlin</groupId><artifactId>kotlin-maven-plugin</artifactId><version>2.0.0</version><executions><execution><id>compile</id><phase>compile</phase><goals><goal>compile</goal></goals></execution><execution><id>test-compile</id><phase>test-compile</phase><goals><goal>test-compile</goal></goals></execution></executions></plugin><plugin><artifactId>maven-surefire-plugin</artifactId><version>2.22.2</version></plugin><plugin><artifactId>maven-failsafe-plugin</artifactId><version>2.22.2</version></plugin><plugin><groupId>org.codehaus.mojo</groupId><artifactId>exec-maven-plugin</artifactId><version>1.6.0</version><configuration><mainClass>MainKt</mainClass></configuration></plugin></plugins></build></project>

2 测试代码

package com.xu.com.xu.transimport org.bytedeco.javacpp.Loader
import org.bytedeco.javacpp.Pointer
import org.bytedeco.opencv.global.opencv_core
import org.bytedeco.opencv.global.opencv_highgui
import org.bytedeco.opencv.global.opencv_imgcodecs
import org.bytedeco.opencv.global.opencv_imgproc
import org.bytedeco.opencv.opencv_core.Mat
import org.bytedeco.opencv.opencv_core.Point
import org.bytedeco.opencv.opencv_core.Point2f
import org.bytedeco.opencv.opencv_core.Scalar
import org.bytedeco.opencv.opencv_highgui.MouseCallbackobject Restore {init {Loader.load(opencv_core::class.java)}@JvmStaticfun main(args: Array<String>) {restore(1)}/*** 透视变换 图像修改** @since 2025年1月20日12点33分*/private fun restore(type: Int) {// 读取图像val src = opencv_imgcodecs.imread("C:\\Users\\xuyq\\Desktop\\11.png")if (src == null || src.empty()) {return}// 创建源点矩阵4个点val org = Mat(1, 4, opencv_core.CV_32FC2)org.ptr(0, 0).put<Pointer>(Point2f(0f, 0f))org.ptr(0, 1).put<Pointer>(Point2f(src.cols().toFloat(), 0f))org.ptr(0, 2).put<Pointer>(Point2f(src.cols().toFloat(), src.rows().toFloat()))org.ptr(0, 3).put<Pointer>(Point2f(0f, src.rows().toFloat()))// 创建目标点矩阵4个点val dst = Mat(1, 4, opencv_core.CV_32FC2)if (1 == type) {val target = click(src)for (i in target.indices) {dst.ptr(0, i).put<Pointer>(target[i])}} else {dst.ptr(0, 0).put<Pointer>(Point2f(21f, 20f))dst.ptr(0, 1).put<Pointer>(Point2f(953f, 74f))dst.ptr(0, 2).put<Pointer>(Point2f(847f, 574f))dst.ptr(0, 3).put<Pointer>(Point2f(109f, 643f))}// 获取透视变换矩阵val matrix = opencv_imgproc.getPerspectiveTransform(dst, org)// 应用透视变换val images = Mat()opencv_imgproc.warpPerspective(src, images, matrix, src.size())// 显示结果opencv_highgui.imshow("RESTORE", images)opencv_highgui.waitKey(0)}private fun click(image: Mat): List<Point2f> {// 创建画布(白色背景)val window = "Click"// 创建窗口opencv_highgui.namedWindow(window, opencv_highgui.WINDOW_AUTOSIZE)val points = listOf<Point2f>().toMutableList()// 创建鼠标回调对象val callback = object : MouseCallback() {override fun call(event: Int, x: Int, y: Int, flags: Int, params: Pointer?) {when (event) {opencv_highgui.EVENT_LBUTTONDOWN -> {println("点击点: ($x, $y)")points.add(Point2f(x.toFloat(), y.toFloat()))// 在原图上绘制点opencv_imgproc.circle(image, Point(x, y), 5,Scalar(0.0, 0.0, 255.0, 0.0), -1, opencv_imgproc.LINE_AA, 0)opencv_highgui.imshow(window, image)}}}}// 设置鼠标回调opencv_highgui.setMouseCallback(window, callback, null)// 主循环while (true) {opencv_highgui.imshow(window, image)if (opencv_highgui.waitKey(1).toChar() == 27.toChar() || points.size >= 4) {opencv_highgui.destroyWindow(window)break}}return points}}

3 测试结果

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

电梯系统的UML文档07

从这个类中得到的类图&#xff0c;构划出了软件的大部分设计。 系统结构视图提供软件和整个系统结构最复杂的也是最优雅的描述。和通常的软件系统相比&#xff0c;在分布式嵌入系统中了解系统组件如何协同工作是非常重要的。毕竟&#xff0c;每个类图仅仅是一个系统的静态设计…

文本摘要研究:从统计方法到大型语言模型

论文地址&#xff1a;https://arxiv.org/pdf/2406.11289 &#x1f4d6; 文本摘要研究&#xff1a;从统计方法到大型语言模型 近年来&#xff0c;文本摘要研究经历了多次重大变革&#xff0c;从深度神经网络的出现到预训练语言模型&#xff08;PLMs&#xff09;&#xff0c;再到…

MYSQL 5.7数据库,关于1067报错 invalid default value for,解决方法!

???作者&#xff1a; 米罗学长 ???个人简介&#xff1a;混迹java圈十余年&#xff0c;精通Java、小程序、数据库等。 ???各类成品java毕设 。javaweb&#xff0c;ssm&#xff0c;springboot&#xff0c;mysql等项目&#xff0c;源码丰富&#xff0c;欢迎咨询。 ???…

C ++ 也可以搭建Web?高性能的 C++ Web 开发框架 CPPCMS + MySQL 实现快速入门案例

什么是CPPCMS&#xff1f; CppCMS 是一个高性能的 C Web 开发框架&#xff0c;专为构建快速、动态的网页应用而设计&#xff0c;特别适合高并发和低延迟的场景。其设计理念类似于 Python 的 Django 或 Ruby on Rails&#xff0c;但针对 C 提供了更细粒度的控制和更高效的性能。…

一文大白话讲清楚webpack基本使用——2——css相关loader的配置和使用

一文大白话讲清楚webpack基本使用——2——css相关loader的配置和使用 1. 建议按文章顺序从头看是看 第一篇&#xff1a;一文大白话讲清楚啥是个webpack第二篇&#xff1a;一文大白话讲清楚webpack基本使用——1——完成webpack的初步构建然后看本篇&#xff0c;Loader的配置…

Kafka 日志存储 — 日志索引

每个日志分段文件对应两个索引文件&#xff1a;偏移量索引文件用来建立消息偏移量到物理地址之间的映射&#xff1b;时间戳索引文件根据指定的时间戳来查找对应的偏移量信息。 1 日志索引 Kafka的索引文件以稀疏索引的方式构造消息的索引。它并不保证每个消息在索引文件中都有…

空调可视化监控与管理系统

随着智能化技术的不断发展&#xff0c;空调系统作为现代建筑、工业和商业场所的核心设备&#xff0c;正在从传统管理模式向智能化管理迈进。无论是大型商业楼宇、工业厂房&#xff0c;还是数据中心的精密空调&#xff0c;如何通过智能监控和高效管理降低能耗、提升运行效率&…

用户中心项目教程(五)---MyBatis-Plus完成后端初始化+测试方法

文章目录 1.数据库的链接和创建2.建库建表语句3.引入依赖4.yml配置文件5.添加相对路径6.实体类的书写7.Mapper接口的定义8.启动类的指定9.单元测试10运行时的bug 1.数据库的链接和创建 下面的这个就是使用的我们的IDEA链接这个里面的数据库&#xff1a; 接下来就是输入这个用户…

Mysql InnoDB B+Tree是什么?

“mysql中常用的数据库搜索引擎InnoDB,其索引通过BTree的方式进行构建。” 实在想不起来BTree是怎么一回事了。以点带线&#xff0c;将涉及到的数据结构一起复习一下。 文章目录 数据结构定义红黑树定义使命 BTree定义使命 BTree定义 InnoDB BTree 旋转与调整二叉排序树插入删…

对人型机器人的研究和展望

目录 概述 1 核心软硬件部件 1.1 运动控制部分 1.1.1 减速机 1.1.2 编码器 1.1.3 直流无刷电机 1.2 智能仿生手 1.3 控制板卡 2 人型机器人的应用 3 未来展望 概述 如果现在有人问&#xff1a;当前那个行业最火&#xff1f;毫无疑问答案肯定是人型机器人了。当前各类机…

Flask:后端框架使用

文章目录 1、介绍2、demo演示3、Flask请求和响应 3.1 演示demo3.2 request获取请求体数据3.3 requests发送请求3.4 响应返回和接收 4、特殊路由 4.1 路由重定向4.2 路由拦截器 1、介绍 Flask是由python语言编写的轻量级Web应用框架&#xff0c;主要应用于后端框架&#xff…

递归算法学习v2.3

目标和 设置全局变量&#xff1a; class Solution {int ret,path,aim;public int findTargetSumWays(int[] nums, int target) {aim target;dfs(nums,0);return ret;}public void dfs(int[] nums,int pos){if(pos nums.length){if(path aim){ret ;}return;}path nums[pos…

ui设计公司分享:浅色 UI 设计

在数字化产品琳琅满目的今天&#xff0c;用户对于界面的要求早已不止于功能的实现&#xff0c;更追求一种舒适、无压的交互体验。而浅色UI设计&#xff0c;凭借其独特的魅力&#xff0c;正逐渐成为众多设计师营造优质体验的首选。 一、浅色UI设计的视觉优势 &#xff08;一&a…

Nacos:使用PgSQL数据源

数据源插件开源仓库地址&#xff1a;nacos-datasource-extend-plugins 一、PostgreSQL数据库安装 1、本文使用Docker进行数据库的安装&#xff0c;使用docker命令拉取的PG14版本的数据库&#xff1a; docker pull postgres:14.6 2、创建PG容器并启动&#xff0c;映射了5432…

Linux——入门基本指令汇总

目录 1. ls指令2. pwd3. whoami指令4. cd指令5. clear指令6. touch指令7. mkdir指令8. rm指令9. man指令10. cp指令11. mv指令12. cat指令13. tac指令14. more指令15. less指令16. head指令17. tail指令18. date指令19. cal指令20. find指令21. which指令22. alias指令23. grep…

C语言之装甲车库车辆动态监控辅助记录系统

&#x1f31f; 嗨&#xff0c;我是LucianaiB&#xff01; &#x1f30d; 总有人间一两风&#xff0c;填我十万八千梦。 &#x1f680; 路漫漫其修远兮&#xff0c;吾将上下而求索。 C语言之装甲车库车辆动态监控辅助记录系统 目录 一、前言 1.1 &#xff08;一&#xff09;…

2024年Vue面试题汇总

流程图如下&#xff1a; vue核心知识——语法篇 1.请问 v-if 和 v-show 有什么区别&#xff1f; 相同点&#xff1a; 两者都是在判断DOM节点是否要显示。 不同点&#xff1a; a.实现方式&#xff1a; v-if是根据后面数据的真假值判断直接从Dom树上删除或重建元素节点。 v-…

centos搭建 Node.js 开发环境

Node.js &#xff0c;通常简称为Node&#xff0c;是一个事件驱动 I/O 服务端 JavaScript 环境&#xff0c;基于 Chrome V8引擎&#xff0c;具备速度快、性能强等特点&#xff0c;可用于搭建各类网络应用&#xff0c;及作为小程序后端服务环境。npm 和 npx 都是和 Node.js 相关的…

DuckDB:精通Insert语句处理数据冲突

本文介绍DuckDB insert语句用法&#xff0c;包括常规的批量插入&#xff0c;尤其是插入数据冲突的处理&#xff0c;最后还提及returning子句的用法&#xff0c;每个用法提供示例说明。 insert插入数据 INSERT INTO向表中插入新行。可以插入由值表达式指定的一行或多行&#xf…

【Linux系统】Ext系列磁盘文件系统二:引入文件系统(续篇)

inode 和 block 的映射 该博文中有详细解释&#xff1a;【Linux系统】inode 和 block 的映射原理 目录与文件名 这里有几个问题&#xff1a; 问题一&#xff1a; 我们访问文件&#xff0c;都是用的文件名&#xff0c;没用过 inode 号啊&#xff1f; 之前总是说可以通过一个…