图像倾斜角度求取-Radon变换

Radon算法

Radon(拉东)算法是一种通过定方向投影叠加,找到最大投影值时角度,从而确定图像倾斜角度的算法。具体过程如图所示 

图1 Radon变换算法

Radon计算示例

对于纹理方向明显的图像,如图2所示,可以通过Radon变换求取倾斜角度。

图2 带求倾斜角度图像

具体步骤如下:

1、图像傅里叶变换

采用Cv2.Dft函数,对图2进行傅里叶变换,变换后的图像如图3所示:

图3 二值化后的傅里叶变换图像

从上面图像可以看到,傅里叶变化图像3方向,与图像2纹理方向呈现垂直关系。我们只要求出来图3的倾斜方向,即可求出来实际图像的倾斜方向。

对于尺寸较大的图像,可采取金字塔下采样方式,将图像进行压缩,以减少Radon计算的时间。

2、金字塔下采样

应用Cv2.PyrDown进行金字塔下采样,减少图像3的尺寸。

while (pyrMat.Width > 100 || pyrMat.Height > 100)
{Cv2.PyrDown(pyrMat, pyrMat, new OpenCvSharp.Size(tempMat.Cols * 0.5, tempMat.Rows * 0.5));
}

压缩后的图像如下图4所示。

图4 金字塔下采样的图片 

3、Radon变换

根据Radon变换原理,编写Radon变换代码,伪代码如下所示:

            for (int t = 0; t < 180; t++){double tempAngle = t * Math.PI / angle;float[,] R = new float[3, 3] {{(float)Math.Cos(tempAngle), (float)Math.Sin(tempAngle), 0 },{ -(float)Math.Sin(tempAngle), (float)Math.Cos(tempAngle), 0},{ 0, 0, 1 } };Mat mR = new Mat(3, 3, MatType.CV_32FC1, R);Mat rotation = m1 * mR * m0;Mat rotated = new Mat();Cv2.WarpPerspective(dst, rotated, rotation, new OpenCvSharp.Size(dst.Rows, dst.Cols), InterpolationFlags.WarpInverseMap);rotated.ConvertTo(rotated, MatType.CV_8UC1);//Cv2.ImShow("test3", rotated);rotated.ConvertTo(rotated, MatType.CV_32FC1);double Sum = 0;List<float> arrMaxCol = new List<float>();for (int j = 0; j < rotated.Cols; j++){/*正文下载链接中有详细代码*/}             arrMaxAngle.Add(arrMaxCol.Max());}var maxSum = arrMaxAngle.Max();var maxInd = arrMaxAngle.IndexOf(maxSum);return maxInd-90;

 最终计算的倾斜角度如下图5程序界面所示。

图5 最终计算结果 

Radon变换的下载链接如下:

https://download.csdn.net/download/qq_20660115/88550141 

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

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

相关文章

【设计模式】聊聊模板模式

原理和实现 设计模式的原理和实现是比较简单的&#xff0c;难的是掌握具体的应用场景和解决什么问题。而模板模式是为来解决复用和拓展两个问题。 模板模式在一个方法中定义好一个算法框架&#xff0c;然后将某些步骤推迟到子类中实现&#xff0c;子类可以在不修改父类流程的时…

qsort使用举例和qsort函数的模拟实现

qsort使用举例 qsort是C语言中的一个标准库函数&#xff0c;用于对数组或者其他数据结构中的元素进行排序。它的原型如下&#xff1a; void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); 我们可以去官网搜来看一看&#xff1a;…

golang学习笔记——生成随机整数的函数Int31n

介绍 rand.31n()函数是Golang标准库中用来生成介于0到n之间的随机整数的函数。其中n是指定的范围&#xff0c;可以是任意正整数。该函数的具体实现方式是在go语言内部使用C语言的随机数生成函数来生成随机数。 具体来说&#xff0c;rand.Int31n()函数的参数n表示要生成的随机…

Ubuntu20.04安装Beyond Compare 4.4.7

参考链接&#xff1a; 1.Ubuntu20.04 Beyond Compare 4.3.7 安装 2.Ubuntu20.04安装Beyond Compare 4.3.7

MySQL 定时计划任务 事件的使用

目录 查看事件是否开启 开启事件 1&#xff09;通过设置全局参数修改 2&#xff09;更改配置文件 MySQL如何创建并执行事件&#xff1f; 例 1 MySQL查看事件状态信息 MySQL修改和删除事件 例 1 例 2 删除事件 例 3 在数据库管理中&#xff0c;经常要周期性的执行某…

lxml基本使用

lxml是python的一个解析库&#xff0c;支持HTML和XML的解析&#xff0c;支持XPath解析方式&#xff0c;而且解析效率非常高 XPath&#xff0c;全称XML Path Language&#xff0c;即XML路径语言&#xff0c;它是一门在XML文档中查找信息的语言&#xff0c;它最初是用来搜寻XML文…

【C/PTA】数组进阶练习(二)

本文结合PTA专项练习带领读者掌握数组&#xff0c;刷题为主注释为辅&#xff0c;在代码中理解思路&#xff0c;其它不做过多叙述。 目录 7-1 字符串逆序7-2 字符串替换7-3 统计字符出现次数7-4 IP地址转换7-1 删除重复字符7-2 说反话-加强版7-3 数组-回文串7-4 数组-无聊的菇菇…

2024全网最新最全的Pytest接口自动化测试框架教程

pytest编写的规则&#xff1a; 1、测试文件以test_开头&#xff08;以_test结尾也可以&#xff09; 2、测试类以Test开头&#xff0c;并且不能带有__init__方法 3、测试函数以test_开头 4、断言必须使用assert pytest.main([-s,-v]) &#xff1a;用来执行测试用例 -s 打印prin…

卷积神经网络(CNN)天气识别

文章目录 前期工作1. 设置GPU&#xff08;如果使用的是CPU可以忽略这步&#xff09;我的环境&#xff1a; 2. 导入数据3. 查看数据 二、数据预处理1. 加载数据2. 可视化数据3. 再次检查数据4. 配置数据集 三、构建CNN网络四、编译五、训练模型六、模型评估 前期工作 1. 设置GP…

11.10 校招 实习 内推 面经

绿*泡*泡&#xff1a; neituijunsir 交流裙 &#xff0c;内推/实习/校招汇总表格 1、校招丨海康机器人2024校招3大类岗位补录&#xff08;内推&#xff09; 校招丨海康机器人2024校招3大类岗位补录&#xff08;内推&#xff09; 2、校招&实习 | 华为数据存储研究部招聘…

SELinux零知识学习十九、SELinux策略语言之类型强制(4)

接前一篇文章&#xff1a;SELinux零知识学习十八、SELinux策略语言之类型强制&#xff08;3&#xff09; 二、SELinux策略语言之类型强制 2. 类型、属性和别名 &#xff08;4&#xff09;别名 别名是引用类型时的一个备选的名字&#xff0c;能够使用类型名的地方就可以使用别…

EEPROM与Flash的区别

EEPROM与Flash的区别 EEPROMEEPROM内部功能框图实现写入数据内部结构存储管在充电或放电状态下有着不同的阈值电压 问题点EEPROM是如何失效的呢&#xff1f;为何EEPROM不能做大呢&#xff1f; ------------------------------------------------------------------------------…

HTTP请求详解

HTTP请求格式 请求报文通常包含以下部分: 请求行(Request Line): 包括请求方法、请求的URL和协议版本。 示例:GET /index.html HTTP/1.1 请求头(Request Headers): 包含了一系列的键值对,用来描述客户端请求的相关信息,比如Accept(告诉服务器客户端能够处理的MIME类型…

Java多线程(3)

Java多线程(3) 深入剖析Java线程的生命周期&#xff0c;探秘JVM的线程状态&#xff01; 线程的生命周期 Java 线程的生命周期主要包括五个阶段&#xff1a;新建、就绪、运行、阻塞和销毁。 **新建&#xff08;New&#xff09;&#xff1a;**线程对象通过 new 关键字创建&…

tamarin运行

首先我们找到安装tamarin的文件位置&#xff0c;找到以后进入该文件夹下 ubuntuubuntu:~$ sudo find / -name tamarin-prover /home/linuxbrew/.linuxbrew/var/homebrew/linked/tamarin-prover /home/linuxbrew/.linuxbrew/Cellar/tamarin-prover /home/linuxbrew/.linuxbrew/…

mac下vue-cli从2.9.6升级到最新版本

由于mac之前安装了 vue 2.9.6 的版本&#xff0c;现在想升级到最新版本&#xff0c;用官方给的命令&#xff1a; npm uninstall vue-cli -g 发现不行。 1、究其原因&#xff1a;从vue-cli 3.0版本开始原来的npm install -g vue-cli 安装的都是旧版&#xff0c;最高到2.9.6。安…

基于Netty实现的简单聊天服务组件

目录 基于Netty实现的简单聊天服务组件效果展示技术选型&#xff1a;功能分析聊天服务基础设施配置&#xff08;基于Netty&#xff09;定义组件基础的配置&#xff08;ChatProperties&#xff09;定义聊天服务类&#xff08;ChatServer&#xff09;定义聊天服务配置初始化类&am…

后端接口错误总结

今天后端错误总结&#xff1a; 1.ConditionalOnExpression(“${spring.kafka.exclusive-group.enable:false}”) 这个标签负责加载Bean&#xff0c;因此这个位置必须打开&#xff0c;如果这个标签不打开就会报错 问题解决&#xff1a;这里的配置在application.yml文件中 kaf…

数据结构之双向带头循环链表函数功能实现与详细解析

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言程序设计————KTV C语言小游戏 C语言进阶 C语言刷题 数据结构初阶 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力&#xff0c;一起奔赴大厂。 目录 1.前言 2.带头双…

Linux Docker图形化工具Portainer如何进行远程访问?

文章目录 前言1. 部署Portainer2. 本地访问Portainer3. Linux 安装cpolar4. 配置Portainer 公网访问地址5. 公网远程访问Portainer6. 固定Portainer公网地址 前言 Portainer 是一个轻量级的容器管理工具&#xff0c;可以通过 Web 界面对 Docker 容器进行管理和监控。它提供了可…