网站建设 广告推广,wordpress树形导航菜单,做的网站怎么查看点击率,购物网站建设市场调查论文简介:本文深入探讨图像梯度相关知识#xff0c;详细介绍图像梯度是像素灰度值在不同方向的变化速度#xff0c;并以 “pig.JPG” 图像为例#xff0c;通过代码展示如何选取图像部分区域并分析其像素值以论证图像梯度与边缘信息的关联。接着全面阐述了 Sobel 算子#xff0c…
简介:本文深入探讨图像梯度相关知识详细介绍图像梯度是像素灰度值在不同方向的变化速度并以 “pig.JPG” 图像为例通过代码展示如何选取图像部分区域并分析其像素值以论证图像梯度与边缘信息的关联。接着全面阐述了 Sobel 算子包括 ddepth 参数对边缘检测完整性的影响及 dx、dy 参数不同设置的效果差异Scharr 算子的用法及其相较于 Sobel 算子在准确度上的优势Laplacian 算子的特性如在检测微小细节变化方面的优势、对噪声敏感及需先平滑处理的要点并给出了各算子在图像边缘检测应用中的代码示例与实际效果展示助力读者深入理解图像梯度与相关算子在图像处理中的作用。 如果本文对你的图像梯度学习有所帮助请给我点赞收藏关注我会为你持续提供与OpenCV学习相关的文章。 《图像梯度与常见算子全解析原理、用法及效果展示》 图像梯度什么是图像梯度 sobel算子ddepth的用法dx dy参数设置请记住这里有两个知识点 Scharr算子Laplacian算子三个知识点致谢 图像梯度
什么是图像梯度
它是指像素灰度值在不同方向的变化速度。我通过OpenCV的代码把这张命名为pig.JPG的图像选择出一部分给大家展示一下。 这是我项目的文件结构 需要图片的可以直接复制我把他放到文章里了 我用代码选择出猪猪侠的偏底部的部分展示一下
import numpy as np
import cv2
image cv2.imread(pig.JPG)
print(image.shape)
image image[800:850,229:250]
cv2.imshow(image,image)
cv2.waitKey()
cv2.destroyAllWindows()我们现在已经把这个猪猪侠的腿部选出来了我们去打印它的np像素值
import numpy as np
import cv2
image cv2.imread(pig.JPG)
image image[800:850,229:250]
print(image)我们可以看到灰度值从几十变成一两百差别很大而图片中的内容恰好对应的是腿部的轮廓。说明梯度变化大的时候针对的就是轮廓。一切都是为了论证这句话一般情况下图像梯度计算的是图像的边缘信息 再通过我用画图板画的一张图来证明一下画的简陋多多包涵 水平方向同理请看下图
sobel算子
语法 dst cv2.Sobel原始图像srcddepth图像深度dx 计算水平方向的偏导数 dy 计算垂直方向的偏导数ksize算子大小 因为不同的参数影响很大所以要一个一个参数的用法讲
ddepth的用法
比如说我在画图板画出下面这个图命名为so_1.JPG 设置图像深度为 0 就是与原图像一致,ksize 3 dx 1 dy 0
import numpy as np
so_1_img cv2.imread(so_1.JPG,cv2.IMREAD_GRAYSCALE)
dst cv2.Sobel(so_1_img,ddepth 0,dx 1,dy 0,ksize 3)
cv2.imshow(original,so_1_img)
cv2.imshow(sob,dst)
cv2.waitKey()
cv2.destroyAllWindows() 你观察图片可以发现他只找到了一条的边可是这个方向的边应该有两条。原因是因为白色是255黑色是0 白右黑左的时候差值为255而白左黑右的时候-255被自动忽略了。 要解决这种方式需要提高ddepth然后对计算结果取绝对值因为我读入图片的时候选择的是八位灰度值的所以我在使用sobel算子可以设置为64位然后再使用cv2.convertScaleAbs()对图片取绝对值然后就可以出现两条边了。请看下面的代码
import numpy as np
so_1_img cv2.imread(so_1.JPG,cv2.IMREAD_GRAYSCALE)
dst cv2.Sobel(so_1_img,ddepth cv2.CV_64F,dx 1,dy 0,ksize 3)
ddst cv2.convertScaleAbs(dst)
cv2.imshow(original,so_1_img)
cv2.imshow(sob,dst)
cv2.imshow(abs_sob,ddst)
cv2.waitKey()
cv2.destroyAllWindows() dx dy参数设置请记住这里有两个知识点
第一个知识点 设置一者为1 另一者为0可以计算单独方向的轮廓如果想同时计算那么需要二者使用cv2.addweighted函数一者0.5对水平和竖直方向进行加权。 还是拿同一张图展示
import numpy as np
so_1_img cv2.imread(so_1.JPG,cv2.IMREAD_GRAYSCALE)
dst cv2.Sobel(so_1_img,ddepth cv2.CV_64F,dx 1,dy 0,ksize 3)
ddst cv2.convertScaleAbs(dst)
y_dst cv2.Sobel(so_1_img,ddepth cv2.CV_64F,dx 0,dy 1,ksize 3)
y_ddst cv2.convertScaleAbs(y_dst)
add cv2.addWeighted(ddst,0.5,y_ddst,0.5,0)
cv2.imshow(original,so_1_img)
cv2.imshow(abs_x_sob,ddst)
cv2.imshow(abs_y_sob,y_ddst)
cv2.imshow(add,add)
cv2.waitKey()
cv2.destroyAllWindows() 第二个知识点是同时设置dx 1 dy 1与第一个知识点的计算结果并不一致因为 图像中的边缘并不总是简单的水平或垂直方向。在实际的图像中边缘可能是倾斜的、弯曲的或者有噪声干扰。 当分别计算和方向梯度并加权相加时可能会丢失一些复杂边缘的细节信息。而dx 1、dy 1的计算方式会以一种不同的角度来捕捉这些复杂边缘的变化包括对角边缘等所以结果会和简单加权相加的情况不一致。 我们拿猪猪侠这张图来验证一下
import numpy as np
so_1_img cv2.imread(pig.JPG,cv2.IMREAD_GRAYSCALE)
dst cv2.Sobel(so_1_img,ddepth cv2.CV_64F,dx 1,dy 0,ksize 3)
ddst cv2.convertScaleAbs(dst)
y_dst cv2.Sobel(so_1_img,ddepth cv2.CV_64F,dx 0,dy 1,ksize 3)
y_ddst cv2.convertScaleAbs(y_dst)
add cv2.addWeighted(ddst,0.5,y_ddst,0.5,0)
x_y_dst cv2.Sobel(so_1_img,ddepth cv2.CV_64F,dx 1,dy 1,ksize 3)
x_y_ddst cv2.convertScaleAbs(x_y_dst)
cv2.imshow(original,so_1_img)
cv2.imshow(add,add)
cv2.imshow(dxdy11,x_y_ddst)
cv2.waitKey()
cv2.destroyAllWindows() Scharr算子
用法与sobel一样就是函数名不一样 cv2.Scharr()有两个区别就是
scharr没有ksize这个参数。scharr不能同时设置dx dy为1
他比sobel算子准确度更高是一种改良我们还用pig.JPG来展示
import numpy as np
so_1_img cv2.imread(pig.JPG,cv2.IMREAD_GRAYSCALE)x_y_dst cv2.Sobel(so_1_img,ddepth cv2.CV_64F,dx 1,dy 1,ksize 3)
x_y_ddst cv2.convertScaleAbs(x_y_dst)x_scharr cv2.Scharr(so_1_img,ddepth cv2.CV_64F,dx 1,dy 0)
x_sscharr cv2.convertScaleAbs(x_scharr)y_scharr cv2.Scharr(so_1_img,ddepth cv2.CV_64F,dx 0,dy 1)
y_sscharr cv2.convertScaleAbs(y_scharr)x_y_sscharr cv2.addWeighted(x_sscharr,0.5,y_sscharr,0.5,0)cv2.imshow(original,so_1_img)
cv2.imshow(dxdy11,x_y_ddst)
cv2.imshow(scharr,x_y_sscharr)
cv2.waitKey()
cv2.destroyAllWindows() 明显看出来后者抓住了更多轮廓下过更好
Laplacian算子三个知识点
第一个知识点 相比于sobel算子Laplacian 算子在检测一些微小的细节变化如噪点引起的小波动或者很细的线条方面可能更有优势。 第二个知识点由于 Laplacian 算子是二阶导数它对噪声比较敏感。在图像存在噪声时噪声点周围的像素值变化会被 Laplacian 算子放大可能导致误检测出许多假边缘。所以在实际应用中通常会先对图像进行平滑处理如使用高斯滤波然后再应用 Laplacian 算子进行边缘检测以减少噪声的影响。 第三个知识点他的语法 dst cv2.Laplacian原始图像src图像深度ddepthksize核尺寸大小scale缩放因子delta计算结果delta说白了就是个附加值borderType就是个边界样式一般不用修改 还用pig.JPG这个图片做例子
import numpy as np
import cv2
img cv2.imread(pig.JPG,cv2.IMREAD_GRAYSCALE)
lap cv2.Laplacian(img,cv2.CV_64F)
lap cv2.convertScaleAbs(lap)
cv2.imshow(original,img)
cv2.imshow(laplacian,lap)
cv2.waitKey()
cv2.destroyAllWindows()致谢
本文参考了一些博主的文章博取了他们的长处也结合了我的一些经验对他们表达诚挚的感谢使我对 图像梯度与算子 有更深入的了解也推荐大家去阅读一下他们的文章。纸上学来终觉浅明知此事要躬行 OpenCV图像处理(十一)—图像梯度 一文讲解图像梯度