最新OpenCV图像处理入门_opencv alpha和beta(2),大数据开发开发者跳槽面试

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

在这里插入图片描述
这中心点的P5的Sobel算子就是按照这个方式进行计算。
对于P5点完成的Sobel算子计算就是这样:
在这里插入图片描述
那么好,我们来看一下在python中对于Sobel是一个什么样的函数:

dst = cv2.Sobel( src , ddepth , dx , dy , [ksize] )

其中src表示原始图像,ddeph表示图像的深度,那么我们一般设定为-1,用来表示和原图像保持一致。dx,dy表示x轴的方向或者y轴的方向,ksize表示核大小。
其中我们在已经知道的256色位图中,白色点像素值255,黑色点像素值0。
这里对于dx,dy方向为什么我们取绝对值进行一下解答,因为加入一块黑块在一个白色背景下,那么我们在水平方向上,左侧那么得到的数值就是一个负数,对于右侧那么我们得到的是就是一个正常的正数,那么对于OpenCV来说,当我们没有加绝对值得时候如果出现了负数,统一处理成0。
在这里插入图片描述
根据图我们就可以知道,左侧的线被OpenCV处理成了0。所以我们这里要加上一个绝对的运算。无论对于水平方向还是垂直方向都是如此。
然后我们要将原始图像处理成256为的色位图。其函数是:

dst = cv2.convertScaleAbs( src [, alpha[, beta]] )

目标图像=调整(原始图像*alpha+beta)
其中alpha和beta可以理解为权重的意思。
当我们想要计算水平方向上的Sobel算子的时候,那么我们就设定函数中的参数dx=1,dy=0.对于垂直方向也是如此。那么这里我们就会想:如果我们两个方向都一起设置这样是不是比计算完x的方向然后计算y方向,然后进行结合这样是不是更加的方便一些呢?也就是说下图中的方式一比方式二更加的简介方便呢?
在这里插入图片描述
事实上不是这样的,而且两个图像有很大的差异,这个我们后续会看到结果。
那么当我们完成了这一步操作之后,我们还要做两个图像的权重和,其函数是:

dst=cv2.addWeighted( src1 , alpha , src2 , beta , gamma )

这里我们说的通俗一点就是,src1表示计算的x轴方向的图像,alpha表示x轴方向上的图像所占的比重,src2表示计算的y轴方向的图像,beta表示y轴方向上的图像所占的比重是多少,最后gamma表示一个修正数值。

dst(I)=saturate(src1(I)*alpha+src2(I)*beta+gamma)

接下来我们来验证一下各个结果:

import cv2
import numpy as np
o = cv2.imread('image\\sobel4.bmp',cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(o,-1,1,0)
cv2.imshow("original",o)
cv2.imshow("x",sobelx)
cv2.waitKey()
cv2.destroyAllWindows()

这里我们没有加上绝对值计算x轴方向上的Sobel算子,得到的结果是:
在这里插入图片描述
很明显左侧的没有计算出来。

import cv2
import numpy as np
o = cv2.imread('image\\sobel4.bmp',cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(o,cv2.CV_64F,1,0)
sobelx = cv2.convertScaleAbs(sobelx) # 转回uint8 
cv2.imshow("original",o)
cv2.imshow("x",sobelx)
cv2.waitKey()
cv2.destroyAllWindows()

当我们加上绝对值后的结果是:
在这里插入图片描述
对于垂直方向的结果也是如此。最后我们计算出x,y的方向。进行融合并且和直接将x,y表示成1的结果进行一下对比,我们来看结果:
核心代码:

sobelx = cv2.Sobel(o,cv2.CV_64F,1,0)
sobely = cv2.Sobel(o,cv2.CV_64F,0,1)
sobelx = cv2.convertScaleAbs(sobelx) # 转回uint8 
sobely = cv2.convertScaleAbs(sobely) 
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0) 
sobelxy11=cv2.Sobel(o,cv2.CV_64F,1,1)
sobelxy11=cv2.convertScaleAbs(sobelxy11)

在这里插入图片描述
根据结果我们可以得到:使用了dx,dy的情况下无法检测到边。然后我们用lena来测试一下结果。
在这里插入图片描述
在我们相加表示的情况下,边缘检测的线条十分清晰,将分割的地带表达的特别清楚。

⭐️3.Scharr算子简介及相关操作

经过大量的科学家验证,发现3*3的Sobel算子可能并不是特别的精确,于是又提出了相应的Scharr算子,其实就是改变了运算的尺度而已。
在这里插入图片描述
Sobel算子由原来的121变为了3 10 3,这样的一个组合。其余的操作都是和Sobel算子一致我们来简要的说明一下:
dst=Scharr(src, ddpeth, dx, dy)
这里面少了核的大小,但是和Sobel算子依然一直,参数这里就不解释了,唯一不同的就是我们使用Sobel算子可以设置成dx=1,dy=1。那么对于Scharr算子如果这样设置就会报错。这里需要注意一下。满足条件:
dx >= 0 && dy >= 0 && dx+dy == 1

import cv2
import numpy as np
o = cv2.imread('image\\scharr.bmp',cv2.IMREAD_GRAYSCALE)
scharrx = cv2.Scharr(o,cv2.CV_64F,1,0)
scharry = cv2.Scharr(o,cv2.CV_64F,0,1)
scharrx = cv2.convertScaleAbs(scharrx) # 转回uint8 
scharry = cv2.convertScaleAbs(scharry) 
scharrxy = cv2.addWeighted(scharrx,0.5,scharry,0.5,0) 
cv2.imshow("original",o)
cv2.imshow("x",scharrx)
cv2.imshow("y",scharry)
cv2.imshow("xy",scharrxy)
cv2.waitKey()
cv2.destroyAllWindows()

在这里插入图片描述

⭐️4.Sobel算子和Scharr算子的比较

对于上述我们的测试图,其实看不出来Sobel算子和Scharr算子到底有什么区别,看起来是一致的,那么我们这里使用大美女lena进行一次Sobel和Scharr,得到结果进行对比一下可以知道:

sobelx = cv2.Sobel(o,cv2.CV_64F,1,0,ksize=3)
sobely = cv2.Sobel(o,cv2.CV_64F,0,1,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx) # 转回uint8 
sobely = cv2.convertScaleAbs(sobely) 
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0) 
scharrx = cv2.Scharr(o,cv2.CV_64F,1,0)
scharry = cv2.Scharr(o,cv2.CV_64F,0,1)
scharrx = cv2.convertScaleAbs(scharrx) # 转回uint8 
scharry = cv2.convertScaleAbs(scharry) 
scharrxy = cv2.addWeighted(scharrx,0.5,scharry,0.5,0)

在这里插入图片描述
很明显,这里我们看一下了lena的肩膀部分,可以看到使用Shcarr算子进行计算的时候,刻画的更加细致。

⭐️5.laplacian算子简介及相关操作

拉普拉斯算子类似于二阶sobel导数。实际上,在OpenCV中通过调用sobel算子来计算拉普拉斯算子。使用的公式为:
∆𝑠𝑟𝑐 = 𝜕2𝑠𝑟𝑐/𝜕𝑥2 + 𝜕2𝑠𝑟𝑐/𝜕𝑦2
使用的卷积核也和Sobel和Shcarr算子的不一致:
在这里插入图片描述

看起来有点像高斯的,哈哈哈。
这里我们进行一下讲解,
P5new=(p2+p4+p6+p8)-4*p5
在这里插入图片描述
当没有处于边界的时候呢,我们可以得到P5的数值是变化不大的,当处于边界的时候,P5的数值是变化非常大的,这是因为什么呢?
在这里插入图片描述
对于拉普拉斯算子的函数估计我们也可以猜到:
dst = cv2.Laplacian( src, ddepth )
自然是没有水平方向和垂直方向的。
实际操作中,计算梯度值可能会出现负数。通常处理的图像是np.uint8类型,如果结果也是该类型,所有负数会自动截断为0,发生信息丢失。所以,通常计算时,使用更高的数据类型cv2.CV_64F,取绝对值后,再转换为np.uint(cv2.CV_8U)类型。
所以我们还是要取一次绝对值的运算:
dst = cv2.convertScaleAbs( src )

import cv2
import numpy as np
o = cv2.imread('image\\laplacian.bmp',cv2.IMREAD_GRAYSCALE)
laplacian = cv2.Laplacian(o,cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian) # 转回uint8 
cv2.imshow("original",o)
cv2.imshow("laplacian",laplacian)
cv2.waitKey()
cv2.destroyAllWindows()

在这里插入图片描述
我们对lena进行一次拉普拉斯算子操作,得到的结果是:
在这里插入图片描述

⭐️6.Canny边缘检测的原理

Canny边缘检测算子是John F. Canny于 1986 年开发出来的一个多级边缘检测算法。更为重要的是 Canny 创立了边缘检测计算理论(Computational theory of edge detection)解释这项技术如何工作。
Canny 的目标是找到一个最优的边缘检测算法,最优边缘检测的含义是:
1.最优检测:算法能够尽可能多地标识出图像中的实际边缘,漏检真实边缘的概率和误检非边缘的概率都尽可能小;
2.最优定位准则:检测到的边缘点的位置距离实际边缘点的位置最近,或者是由于噪声影响引起检测出的边缘偏离物体的真实边缘的程度最小;
3.检测点与边缘点一一对应:算子检测的边缘点与实际边缘点应该是一一对应。
Canny边缘检测的一般步骤:1.去噪 2.梯度运算 3.非极大值抑制 4.滞后阈值。下面我们就分别讲解一下这些操作:
🌞1.去噪
边缘检测容易受到噪声的影响。因此,在进行边缘检测前,通常需要先进行去噪。我们一般使用高斯滤波进行图像去噪处理。也就是让临近的像素具有更高的重要度。对周围像素计算加权平均值,较近的像素具有较大的权重值。
在这里插入图片描述
比较像我们之间讲到的k近邻算法的意思哈。进行去噪处理之后呢,我们对于平滑图像进行一次Sobel算子梯度运算。
🌞2.梯度运算
𝐸𝑑𝑔𝑒𝐺𝑟𝑎𝑑𝑖𝑒𝑛𝑡 𝐺 = 根号下(𝐺𝑥2 + 𝐺𝑦2)
对于方向:𝐴𝑛𝑔𝑙𝑒 𝜃 = 𝑡𝑎𝑛−1(𝐺𝑦/𝐺𝑥)

在这里插入图片描述
对于每一个点计算之后的方向就是这样。大小和方向在图中都已经进行了标记。梯度的方向一般总是与边界垂直。梯度方向被归为四类:垂直,水平,和两个对角线。
🌞3.非极大值抑制
在获得了梯度和方向后,遍历图像,去除所有不是边界的点。实现方法:逐个遍历像素点,判断当前像素点是否是周围像素点中具有相同方向梯度的最大值。
在这里插入图片描述
点A、点B、点C三点具有相同的方向,梯度方向垂直于边缘。判断点A是否为点A、点B、点C的局部最大值 :如果是,保留该点;否则,它被抑制(归零)。
在这里插入图片描述
这里就表示在垂直方向上进行了抑制,取出最大值。
🌞4.滞后阈值
这里对非极大值抑制之后,我们进行了一次滞后阈值操作,分别取一个最小阈值和一个最大阈值,然后图像像素点的曲线与最大最小阈值相连则保留,如果不相连则抛弃。
在这里插入图片描述
我们来看一下边缘检测的结果图:
在这里插入图片描述

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

98306)]
[外链图片转存中…(img-xR5uPwKD-1715107798306)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

  • 26
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值