当前位置: 首页 > wzjs >正文

网站建设与百度推广百度地图推广电话

网站建设与百度推广,百度地图推广电话,长沙做网站的公司,怎样在手机上建设网站前言 书接上文 OpenCV图像处理实战全解析:镜像、缩放、矫正、水印与降噪技术详解-CSDN博客文章浏览阅读1.1k次,点赞38次,收藏29次。本文系统解析OpenCV图像处理五大实战场景:镜像反转的三种坐标变换模式,图像缩放的尺…

前言

书接上文

OpenCV图像处理实战全解析:镜像、缩放、矫正、水印与降噪技术详解-CSDN博客文章浏览阅读1.1k次,点赞38次,收藏29次。本文系统解析OpenCV图像处理五大实战场景:镜像反转的三种坐标变换模式,图像缩放的尺寸控制与插值方法,透视变换的四点定位原理与三维投影消除,基于二值化模板的水印叠加技术,以及均值/高斯/中值滤波器的噪声消除机制。通过11个完整代码示例,详解关键参数设置与算法选择策略,涵盖flip、resize、warpPerspective、bitwise_and、GaussianBlur等核心函数应用,提供从基础操作到复杂形变矫正的全栈解决方案,为计算机视觉开发提供完备的技术参考。 https://blog.csdn.net/qq_58364361/article/details/146971848?spm=1011.2415.3001.10575&sharefrom=mp_manage_link


一、图像梯度处理

1.1 图像梯度

dx和dy是x和y的微分,趋向于无穷小,这是在连续的函数中求导的过程,可以认为这就是函数某一个点的梯度。

上面的连续的函数,但是实际中图像是离散的。如果图像也能微分,可以理解为图像的像素点无穷小,图像分辨率无穷大

理想情况下图像的数据组成也应该可以进行微分的,因此存在x轴和y轴的梯度,需要同时考虑两个方向

图像在计算机中是以离散的像素点分布的,因此使用的差分


1.2 边缘计算 Filter2D

梯度计算的目的是为了寻找图像的边缘,因此把寻找图像边缘的计算称为边缘计算,也是通过卷积核实现的,下面的是一个常用于边缘计算的卷积核:

上面的核用于提取图片的垂直边缘,下图是水平梯度的计算,来提取垂直边缘。

同理,改变卷积核形态,可以把图像的水平边缘提取,进行垂直梯度的计算:

可以看到相关参数如下:

ddepth 深度-1表示保持原图位深度(通常为8位无符号整型)

kernel 卷积核

可自定义核数值

edge_ex_method 边缘检测的方向

upright 垂直 level 水平

此参数在OpenCV函数接口中并不存在

import cv2
import numpy as npif __name__ == '__main__':path = "QiPan.jpg"  # 图片文件路径img = cv2.imread(path)  # 读取图片,返回BGR格式的numpy数组#构建卷积核kernel = np.array([[-1, 0, 1],  # Sobel算子X方向卷积核[-2, 0, 2],  # 用于边缘检测[-1, 0, 1]],dtype=np.float32  # 指定数据类型为32位浮点数)#边缘计算dts_img = cv2.filter2D(img, -1, kernel)  # 使用卷积核进行图像滤波"""cv2.filter2D参数说明:src: 输入图像ddepth: 输出图像深度(-1表示与输入相同)kernel: 卷积核"""#显示图片cv2.imshow("dts_img", dts_img)  # 在窗口中显示处理后的图像cv2.waitKey(0)  # 等待任意按键按下


1.3 Sobel算子

Sobel算子是一种特殊的Filter2D,也是最常用的一种边缘检测算法,使用特定的卷积核进行计算。

  • 使用k1,对原始图像src进行卷积操作,得到水平方向的梯度图Gx

  • 使用k2,对原始图像src进行卷积操作,得到垂直方向的梯度图Gy

  • 支持适应Gx和Gy求出总梯度,这种用法比较严格,需要同时具有水平和垂直梯度的像素才会显示比较明显

dx,dy参数分别表示是否考虑x和y方向的梯度,不支持全零。

k1k2必须使用上述参数否则不是Sobel子。除了Sober算子外,也可以更改卷积核的权重比例形成其他的算子:

import cv2
import numpy as npif __name__ == '__main__':path = "QiPan.jpg"  # 图片文件路径img = cv2.imread(path)  # 读取图片,返回BGR格式的numpy数组# 灰度图转换# 将BGR格式图像转换为灰度图img_h = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 转换为灰度图# Sobel算子边缘检测"""使用Sobel算子计算图像梯度参数:img_h: 输入灰度图像cv2.CV_16S: 输出图像深度(16位有符号整型)1: x方向上的差分阶数1: y方向上的差分阶数ksize=3: Sobel核大小返回:包含梯度值的图像(可能有负值)"""img_sobel = cv2.Sobel(img_h,cv2.CV_16S,1,  # x方向上的差分阶数1,  # y方向上的差分阶数ksize=3  # Sobel算子大小)# 梯度绝对值处理img_j = np.abs(img_sobel)  # 取梯度绝对值,消除负值# 归一化处理max = np.max(img_j)  # 获取图像最大梯度值img_g = (img_j / max) * 255  # 归一化到0-255范围# 类型转换img_end = img_g.astype(np.uint8)  # 转换为8位无符号整型# 显示结果cv2.imshow("img_end", img_end)  # 显示处理后的图像cv2.waitKey(0)  # 等待用户按键


1.4 Laplacian(拉普拉斯)算子

上面算子都是一阶导数这些极值地方二阶倒数0因此梯度计算可以通过二阶倒数

推理过程如下

import cv2if __name__ == '__main__':# 图片文件路径path = "QiPan.jpg"# 读取图片,返回BGR格式的numpy数组# @param path 图片路径# @return numpy.ndarray BGR格式的图像数组img = cv2.imread(path)# 拉普拉斯边缘检测# @param img 输入图像# @param ddepth 输出图像深度(-1表示与输入相同)# @return numpy.ndarray 边缘检测结果img_l = cv2.Laplacian(img,-1)# 显示处理后的图像# @param winname 窗口名称# @param mat 要显示的图像cv2.imshow("Laplacian", img_l)# 等待键盘输入# @param delay 延迟时间(毫秒),0表示无限等待cv2.waitKey(0)

拉普拉斯是二阶算子的典型代表,相比于一阶算子各有优缺点:

综上所述,一阶求导和二阶求导算法在图像梯度处理中各有优缺点,在实际应用中,应根据具体需求选择合适的方法。


二、图像边缘检测

上一章中仅仅进行梯度计算,如果要进行边缘检测需要继续优化流程

本实验使用的算法为Canny算法,此算法进行边缘检测被誉为最优方法。

Canny算法的输入图像应该为二值化图像,包括以下步骤:

1. 高斯滤波

2. 计算图像的梯度和方向

3. 非极大值抑制

4. 双阈值筛选


2.1 高斯滤波

边缘检测属于对噪点比较敏感的算法,因此需要降噪,对图像进行平滑处理,这里直接使用一个5*5的高斯核对图像降噪:

经过高斯滤波后,图下会变得更加模糊,边缘会变粗。


2.2 计算图像梯度与方向

内部使用的是Sobel算子来计算图像的梯度值,分为水平和垂直方向的核:

同时计算两个方向的梯度Gx和Gy,然后根据欧式距离(L2距离)来计算具体的梯度值:

根据三角函数,可以基于直角三角形的边长求出对应的角度:

这个角度θ就是总梯度放在哪个方向,按照以下规定制定梯度角度方向:

根据上面的设定,可以得到每个边缘像素点所在的边缘方向:

  • 黄色区域为水平梯度方向,表示垂直边缘
  • 蓝色区域为垂直梯度方向,表示水平边缘
  • 绿色区域为45°梯度方向,表示135°边缘
  • 红色区域为135°梯度方向,表示水平边缘

4. 非极大值抑制

之前使用高斯滤波会让画面的边缘变粗,但是变粗的同时边缘的也会变得模糊,因此这种图像经过梯度计算后,得到的边缘像素点会比原始图像更多,因此需要对这些像素点进行过滤。

非极大值抑制就是过滤边缘像素点的一种方法,可以让边缘变细。假设当前的像素点为(x, y),其梯度方向是0°,梯度值为G(x, y),需要比较G(x, y)与两个相邻像素点的梯度值:G(x-1, y)和G(x+1, y)。如果G(x, y)是这三个梯度值中最大的,就保留该梯度值,否则直接抑制为0。

例如,梯度方向为0°时,比较下图中X是否大于8和4;梯度方向为45°时,比较下图中X是否大于3和7。

经过了非极大值抑制之后,还需要经过双阈值筛选。如果阈值设置的太低,就会出现假边缘;如果阈值设置的太高,一些较弱的边缘就会被丢弃,因此适应双阈值再次筛选,需要设定高低阈值的比例。

双阈值对应的像素梯度值可以分为以下几种情况:

  • 强边缘 → A

如果像素的梯度值超过高阈值maxVal时,该像素必然是边缘像素。

  • 弱边缘

如果像素的梯度值低于高阈值maxVal且高于低阈值minVal时,分为以下两种情况:

(a) 如果该点能连接到一个强边缘点,该像素为边缘像素。→ C

(b) 如果该点不能连接到一个强边缘点,该像素不是边缘像素,被称为伪边缘点。 → B

  • 非边缘

如果像素的梯度值低于低阈值minVal时,该像素必然不是边缘点。

import cv2
import numpy as npif __name__ == '__main__':# 1. 图片输入path = 'QiPan.jpg'image_np = cv2.imread(path)# 2. 灰度化image_np_gray = cv2.cvtColor(image_np, cv2.COLOR_BGR2GRAY)# 3. 二值化ret, image_np_thresh = cv2.threshold(image_np_gray, 40, 255, cv2.THRESH_BINARY)# 4.高斯滤波(可能多次效果更好)no_noise_image = cv2.GaussianBlur(image_np_thresh, (7, 7), 0)# Canny算法: 5.计算梯度与方向 + 6. 非极大值抑制 + 7. 双阈值筛选edges_image = cv2.Canny(image_np_thresh,  # 源图像30,  # 低阈值70  # 高阈值)# 8. 图片输出cv2.imshow('edges_image', edges_image)cv2.waitKey(0)

三、凸包特征检测

3.1 凸包

凸包就是将一张图片中物体的最外层的点连接起来构成的凸多边形,它能包含物体中所有的像素点。

假如在图像中有一些点:

经过凸包检测并绘制之后,应该得到下面的结果:

可以看到整个物体所有的像素点均涵盖在这个凸多边形中。


3.2 基础凸包检测算法

1. 先找到最左边和最右边的点。

2. 连接上面的两个点连接,将点集分为上半区和下半区,以上半区为例:

3. 找到上半区中离直线最远的点。

假设直线的方程为:,则点(x0,y0)到直线的公式为:

4. 把最远的像素点与之前最左和最右的像素点连接,把这两条直线明明为y1和y2。

5. 求出y1和y2的直线方程,把上半区所有的点带入计算与y1和y2的距离(分正负):

  • d=0表示点在y1或y2上,可以忽略
  • d>0时,表示点在y1或y2上方,这表示需要更新凸包点
  • d<0时,表示点在y1和y2下方,忽略

6. 当上一步出现d>0的情况时,需要更新凸包点,重新连接,形成新的y2和y3:

7. 在新的y2和y3中重新反复计算新凸包点,直到上半区计算完成。

8. 下半区执行跟上半区相似的操作,但是判断条件改为寻找d<0的点。

上面的过程都是基于已知坐标点进行的处理,实际上对于未处理的图像,可能并不能直接获取点的坐标,特别是彩色图像,需要转换为二值化后的图像,并通过轮廓检测算法获取边界点的坐标。

在实际图像处理中,通常会直接调用OpenCV的函数接口提取轮廓点并应用凸包算法,不需要手动实现上述过程。这些算法已经内置,可以更加高效。


3.3 Graham扫描

Graham扫描法是一种用于寻找二维平面上点集凸包的算法。其基本思想是先找一个基点,从这个基点出发,按照逆时针方向逐个寻找凸包点。

算法的主要步骤如下:

1. 寻找基点(P0)

通常选择y坐标最小的点,如果有多个这样的点,则选择x坐标更小的点作为基点P0,以P0为原点构建二维直角坐标系。

2. 计算剩下所有点相对P0的极角α(即该点与P0连线与x轴正方向的夹角)。

按照极角从小到大的顺序对点进行排序。如果极角相同,则比较与P0的距离,距离更近的排在前面。

3. 初始化一个栈来记录凸包点,把P0和P1入栈。

4. 扫描点集

把P2入栈,将栈顶的两个点相连(P1和P2),得到一条直线,观察下一个点P3在此直线的右侧还是左侧

  • 如果在右侧

说明P2不是凸包点,P2出栈,重新执行第四步(下一个点入栈)。

  • 如果在左侧或直线上

说明下一个点P3凸包点,P3入栈,重新执行第四步(下一个点入栈)。

5. 遍历完所有点,栈中剩下的点就是凸包的顶点。按照栈的顺序(从栈底到栈顶,即逆时针顺序)输出所有的凸包点。

Graham-24111张奥博https://docs.qq.com/doc/DTXJ2TWJuU2pPbkFL


3.4 QuickHull

在二维空间中,QuickHull用于计算凸包,采用分而治之的策略,通过递归将点集划分为更小的子集,并构建这些子集的凸包,如下所示:


3.5 Andrew扫描链

import cv2
import numpy as npif __name__ == '__main__':# 1. 图片输入path = 'test.png'image_np = cv2.imread(path)# 2. 灰度化image_np_gray = cv2.cvtColor(image_np, cv2.COLOR_BGR2GRAY)# 3. 二值化ret, image_np_thresh = cv2.threshold(image_np_gray, 127, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)# cv2.imshow('image_np_thresh', image_np_thresh)# 4. 寻找轮廓# 返回值1:所有轮廓的点坐标,是一个list列表# 返回值2:轮廓的层级关系contours, hierarchy = cv2.findContours(image_np_thresh,  # 二值化之后的图像cv2.RETR_EXTERNAL,  # 默认的轮廓查找方式cv2.CHAIN_APPROX_SIMPLE  # 默认的轮廓近似办法)print(len(contours))# print(contours)# print(hierarchy)# 拿到第一个轮廓的数据cnt = contours[0]print(cnt.shape)  # (296, 1, 2)表示由296个点组成,1占位,2表示xy坐标2维# 5. 查找凸包# 参数:当前轮廓的点数据(此处送入的是第一个轮廓)# 返回值:轮廓的凸包点hull = cv2.convexHull(cnt)print(hull.shape)  # (12, 1, 2)print(hull)# 6. 绘制轮廓image_np = cv2.polylines(image_np,  # 在哪个图像上画轮廓[hull],  # 凸包轮廓点的列表isClosed=True,  # TODO 是否闭合color=(0, 0, 255),  # 线段颜色thickness=2  # 线段粗度)# 7. 图片输出cv2.imshow('image_np',image_np)cv2.waitKey(0)

总结 

        本文系统介绍了图像处理中的梯度计算、边缘检测和凸包特征检测三大核心技术。首先,通过微分和差分理论解释了图像梯度的概念,并对比了Sobel算子和Laplacian算子在边缘检测中的优缺点。其次,详细解析了Canny算法的四步流程(高斯滤波、梯度计算、非极大值抑制、双阈值筛选),强调了其在边缘检测中的高效性。最后,深入探讨了凸包检测的三种经典算法(基础凸包检测、Graham扫描法、QuickHull法和Andrew扫描链法),结合OpenCV代码演示了实际应用。全文通过理论推导与代码实践相结合,为图像处理中的特征提取提供了全面的技术指导。

http://www.dtcms.com/wzjs/82308.html

相关文章:

  • 商丘做网站公司新站seo快速收录网页内容页的方法seo单页快速排名
  • 阿里巴巴是搭建的网站吗企业中层管理人员培训课程
  • 广州专业网站制作设计高端定制网站建设公司
  • 中建一局招聘网西安seo网站管理
  • 邢台做移动网站哪儿好江西省水文监测中心
  • wordpress 版权求职seo服务
  • 上饶商城网站建设百度渠道开户哪里找
  • 科技加盟网站建设中国十大品牌策划公司
  • 遂宁网站建设seo技术优化
  • 中企动力骗子公司真的还是假的站长工具seo综合查询官网
  • 霸县网站建设北京seo公司有哪些
  • 网站开发公司代理宁波seo快速优化教程
  • 云南做网站广东新闻今日最新闻
  • 国外psd免费下载网站广州网站建设方案维护
  • 国外网站拼邮需要怎么做seo就业
  • 潍坊做网站公司推广优化
  • 网站地图生成工具西安网站建设优化
  • 价格优化网站建设今日十大热点新闻事件
  • java网站开发框架搭建手册排名网
  • 网站建设电销女生做sem还是seo
  • 软件开发工程师薪资待遇网页优化方法
  • 手机网站建设 广州线上营销推广的公司
  • wordpress内容模型百度搜索引擎优化相关性评价
  • 做网站服务器权限设置网站seo优化外包顾问
  • 管庄网站建设搜索关键词的方法
  • 邢路桥建设总公司网站seo查询网站是什么
  • 渭南哪家公司可以做网站制作公司网站大概多少钱
  • sns网站建设哪家公司好百度收录入口
  • 网站面包屑导航推广赚钱的软件
  • dedecms网站地图 显示三级栏目seo是什么服务器