图片倾斜矫正处理(Hough Transform)

目录

    • 倾斜矫正原理及实现方式
    • Canny边缘检测
    • 非极大值抑制
    • 霍夫变换

倾斜矫正原理及实现方式

代码连接:https://github.com/shuyeah2356/Image-Angel-correction/tree/main
倾斜矫正的实现原理:

使用霍夫变换检测图片中的直线;
计算直线与水平方向的倾斜角度;
最后根据角度旋转图片

实现步骤:

  1. 边缘检测,将图片转为灰度图,使用Canny边缘检测找到图片中的所有边缘
  2. 使用霍夫变换检测直线
  3. 计算角度:对于每一条直线计算其于水平线的角度,(可以用直线的极坐标表示中的角度得到)
  4. 角度平均:计算所有角度的中位数,用这个角度值来代表图片整体的倾斜角度
  5. 图片旋转:根据该角度对图片进行旋转

图片矫正效果:
在这里插入图片描述
在这里插入图片描述

Canny边缘检测

在边缘检测之前为什么转为灰度图?
1、简化处理,灰度图只有一个通道,而彩色图由三个通道,灰度图容易处理和分析,较少计算的复杂性;
2、降低数据量,灰度图只需要用一个字节来表示像素的亮度,而彩色图像需要三个值,使用灰度图能够减少数据量,节省存储空间;
3、对于边缘检测更关注图像中的边界纹理特征,不需要图片中的色彩信息。

Canny边缘检测的实现步骤

  1. 抑制噪声:通过高斯滤波对图像做平滑处理,滤除图像中的噪声,同时保留边缘的细节;
  2. 计算梯度的幅值和方向:使用sobel算子计算图像中每一个像素点的水平方向和垂直方向的梯度值,根据梯度值计算每一个像素点的梯度幅值和方向;
  3. 非极大值抑制:在计算得到的梯度幅值图上进行非极大值抑制,初步筛选边界;
  4. 双阈值方法:设置高阈值和低阈值,将图像中的像素点分为强边缘、弱边缘和非边缘。
    像素值的梯度幅值超过高阈值称为强边缘,被看作是边缘;
    像素的梯度值结余高阈值和低阈值之间,被看做是弱边缘,如果弱边缘与强边缘连接,则该像素视为边缘,否则将其抑制;
    像素的梯度幅值小于低阈值,则该像素为非边缘。

在OpenCV中通过cv2.Canny(image, threshold1, threshold2, edges=None, apertureSize=None, L2gradient=None)实现,
其中第一个参数表示输入的图像;
threshold1, threshold2表示双阈值中的低阈值和高阈值;
edge表示输出图片的大小;
apertureSize表示sobel算子中卷积核的大小;
L2gradient表示梯度如何计算,默认使用:在这里插入图片描述
该参数设置为True,则计算梯度幅值使用:
在这里插入图片描述

非极大值抑制

边缘检测中的非极大值抑制方法,作用是对边缘做初步筛选,去除图像中冗余的边缘。
判断当前像素点的梯度是都为梯度方向上的极值点,如果当前像素点为梯度方向上的极值点则该点保留为边缘,如果当前像素点不是极值点,则将该点抑制。

周围像素点的梯度可能无法计算,则根据已知的像素只梯度通过插值计算。
非极大值抑制只在水平、垂直和两个对角线方向,每一个像素点的梯度方向按照近似程度用0°、90°、45°、135°来近似表示。
通过a2/a5计算出n像素值的梯度;通过a3/a6计算m像素点的梯度。
在这里插入图片描述
非极大值抑制参考

https://blog.csdn.net/weixin_42491648/article/details/131348643?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-0-131348643-blog-11620357.235v43pc_blog_bottom_relevance_base9&spm=1001.2101.3001.4242.1&utm_relevant_index=3

霍夫变换

极坐标上的一个点对应直角坐标中的一条直线;
直角坐标中的一个点对应极坐标中的一条正弦曲线。
直角坐标映射为极坐标:
在这里插入图片描述
极坐标映射为直角坐标:
在这里插入图片描述

直角坐标对极坐标的变换可以看作是一个参数方程,不同的θ对应不同的ρ值。
在直角坐标系中多个点共线,对应在极坐标系中,多条正弦曲线相交于一点。
霍夫变换检测直线的原理:

  1. Canny边缘检测后得到图像中所有边缘,遍历每一个边缘的像素点映射到极坐标系下。
  2. 该曲线经过的像素点的像素值+1
  3. 极坐标系下每一个元素的数值代表图像中共线的点的个数,
  4. 数值较大的点可以拟合为一条直线,将极坐标下的点的坐标反映射回直角坐标系下,对应一条直线。

霍夫变换检测到之间可视化结果:
在这里插入图片描述


感谢:
https://blog.csdn.net/weixin_48938349/article/details/128750770

https://blog.csdn.net/weixin_42491648/article/details/131348643?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-0-131348643-blog-11620357.235v43pc_blog_bottom_relevance_base9&spm=1001.2101.3001.4242.1&utm_relevant_index=3

https://blog.csdn.net/weixin_42491648/article/details/131348643?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-0-131348643-blog-11620357.235%5Ev43%5Epc_blog_bottom_relevance_base9&spm=1001.2101.3001.4242.1&utm_relevant_index=3

https://blog.csdn.net/hai411741962/article/details/132144264

https://blog.csdn.net/gangeqian2/article/details/80034070

https://www.bilibili.com/video/BV1Gv4y167t9/?spm_id_from=333.337.search-card.all.click&vd_source=91cfed371d5491e2973d221d250b54ae

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

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

相关文章

【与 Apollo 共创生态:展望自动驾驶全新未来】

1、引言 历经七年的不懈追求与创新,Apollo开放平台已陆续推出了13个版本,汇聚了来自全球170多个国家与地区的16万名开发者及220多家合作伙伴。随着Apollo开放平台的不断创新与发展,Apollo在2024年4月19日迎来了Apollo开放平台的七周年大会&a…

周末总结(2024/05/05)

工作 人际关系核心原则: 要学会随时回应别人的善意。 人际关系的本质是价值交换(利益和情绪) 接受破烂现状,改变状态 - 这周写了两天代码,总结了node.js的面试题,其他时间都在摸鱼,状态很差&am…

猿人学第七题-动态字体-随风漂移

前言:该题主要是考对fontTools.ttLib.TTFont的操作,另外就是对字典互相映射的操作 一、woff文件存储 from fontTools.ttLib import TTFont #pip install fontTools def save_woff(response):woff response[woff]woff_file base64.b64decode(woff.enc…

.排序总讲.

在这里赘叙一下我对y总前四节所讲排序的分治思想以及递归的深度理解。 就以788.逆序对 这一题来讲(我认为这一题对于分治和递归的思想体现的淋淋尽致)。 题目: 给定一个长度为 n𝑛 的整数数列,请你计算数列中的逆序对…

Linux的软件包管理器-yum

文章目录 软件包的概念yum源的配置的原因yum的使用查看软件包安装软件卸载软件 软件包的概念 软件包(SoftWare Package)是指具有特定的功能,用来完成特定任务的一个程序或一组程序。可分为应用软件包和系统软件包两大类 在Linux系统中,下载安装软件的方式…

力扣:100284. 有效单词(Java)

目录 题目描述:输入:输出:代码实现: 题目描述: 有效单词 需要满足以下几个条件: 至少 包含 3 个字符。 由数字 0-9 和英文大小写字母组成。(不必包含所有这类字符。) 至少 包含一个 …

leetcode_46.全排列

46. 全排列 题目描述:给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1: 输入:nums [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]示例 2&#…

Java学习之集合2

集合: 1.ArrayList集合类 import java.util.ArrayList;public class Demo01ArrayList {public static void main(String[] args) {/*ArrayList类概述底层数据结构是数组,查询快,增删慢TODO 方法插入数据时不会对插入的数据进行自然排序或字…

视频下载器 UC网盘

老王导航 - 复杂问题找老王,简单问题百度搜 神器啊

Spring框架的扩展点

Spring框架是一个非常流行的Java应用程序框架,它提供了一系列的扩展点,使得开发者可以自定义和增强框架的功能。这些扩展点包括: Bean生命周期回调 Spring允许通过实现特定的接口或使用注解来在Bean的生命周期的不同阶段(如初始…

深入理解 ICMP 协议

目录 前言 1. 概述 特性与功能 报文封装与格式 2. ICMP差错报告 3. ICMP查询 4. ICMP应用 总结 前言 ICMP(Internet Control Message Protocol)是互联网控制报文协议,是TCP/IP协议族中的一个重要组成部分。作为网络层的协议之一&#…

保研面试408复习 2——操作系统、计网

文章目录 1、操作系统一、进程、线程的概念以及区别?二、进程间的通信方式? 2、计算机网络一、香农准则二、协议的三要素1. 语法2. 语义3. 时序 标记文字记忆,加粗文字注意,普通文字理解。 1、操作系统 一、进程、线程的概念以及…

利用反射和自定义注解优化参数处理

文章目录 自定义注解类定义反射和注解取值格式化参数测试 自定义注解 Target(ElementType.FIELD) Retention(RetentionPolicy.RUNTIME) public interface PropertyAnnotation {//字段类型: STRING->0,Number 1,Decimal 2,DateTime 3, Date 4 ,int 5,Float 6,Double 7int ty…

力扣经典150题第五十五题:逆波兰表达式求值

目录 题目描述和要求示例解释解题思路算法实现复杂度分析测试和验证总结和拓展参考资料 题目描述和要求 给你一个字符串数组 tokens,表示一个根据逆波兰表示法表示的算术表达式。请你计算该表达式,并返回一个表示表达式值的整数。 注意: 有…

团队经理口才训练教案(3篇)

团队经理口才训练教案(3篇) **篇:基础口才训练 一、教学目标 让团队经理了解口才在团队管理中的重要性。 教授基础口才技巧,如发音、语速、语调等。 二、教学内容 口才的重要性 强调团队经理的口才能力对团队凝聚力、沟通…

牛客NC383 主持人调度(一)【简单 排序 Java/Go/C++】

题目 题目链接: https://www.nowcoder.com/practice/e160b104354649b69600803184094adb 思路 直接看代码,不难Java代码 import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返…

Android Binder机制

一.简介 Binder是什么? Android系统中,涉及到多进程间的通信底层都是依赖于Binder IPC机制。 例如当进程A中的Activity要向进程B中的Service通信,这便需要依赖于Binder IPC。不仅于 此,整个Android系统架构中,大量采…

BI不等同数据分析,别搞错了!

✅作者简介:《数据运营:数据分析模型撬动新零售实战》作者、《数据实践之美》作者、数据科技公司创始人、多次参加国家级大数据行业标准研讨及制定、高端企培合作讲师。 🌸公众号:风姑娘的数字视角,免费分享数据应用相…

小红的循环移位

题目描述:小红拿到了一个数字串,她每次操作可以使得其向左循环移动一位。将串 ss0 s1...sn−1s ​ 向左循环移动一位,将得到串s1...sn−1s0。小红想知道,使得该数字串变成4的倍数,需要最少操作多少次?&…

leetCode80. 删除有序数组中的重复项 II

leetCode80. 删除有序数组中的重复项 II 具体思路见我上篇博客&#xff1a;只不过哪里是只能出现1次&#xff0c;这里只能出现两次 删除有序数组中的重复项打卡博客 代码 class Solution { public:int removeDuplicates(vector<int>& nums) {int k 0;for(auto x :…