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

第四章 OpenCV篇—图像梯度与边缘检测—Python

目录

一.Sobel算子

二.Scharr算子与laplacian算子

三.Canny边缘检测

1.高斯滤波器

2.梯度和方向

3.非极大值抑制

4.双阈值检测


此章节主要讲解图像梯度计算方法和边缘检测算法,分别主要是:sobel算子、scharr与lapkacian算子、canny边缘检测流程。

一.Sobel算子

A代表选取的卷积核。Gx,Gy分别代表水平梯度和垂直梯度

注:

图像的梯度算法就是卷积操作。公式如下:

这里与矩阵乘法有差异的地方在于求垂直梯度。

公式中的K代表卷积核

以下是水平梯度运算的方法。

Gx= 1*p3-1*p1+2*p6-2*p4+1*p9-1*p7

这个运算通过右边减去左边的区域,求出它的像素点的差异值。通过这个差异值,将求出的这个差异值视作水平方向的梯度

Gy = 1*p7-1*p1+2*p8-2*p2+1*p9-1*p3

G = Gx+Gy

垂直梯度的计算是从下减上的一个操作流程。以上是Sobel算子的一个运算规则方法。

Sobel算子的语法格式:

cv2.Sobel(src,ddepth,dx,dy,ksize)

  • src:当前图像
  • ddepth:图像的深度
  • dx和dy分别表示水平和竖直方向
  • ksize是Sobel算子的大小(指定核,一般是3×3或5×5)

注:

一般深度计算默认是-1,表示我输出的深度和输入的深度是一模一样的。

Sobel算子的ddepth 的参数共有五种类型分别为:cv2.CV_8U,cv2.CV_16S,cv2.CV_32F,cv2.CV_64F,cv2.CV_16U这五种类型的图像,分别表示8位无符号整数、16位有符号整数、32位浮点数、64位浮点数和16位无符号整数。

求水平梯度代码演示如下:

原图如下

代码如下:

import cv2
import numpy as np
def cv_show(img,name):cv2.imshow(name,img)cv2.waitKey(0)cv2.destroyAllWindows()
def cv_Xshow(image):# Sobel算子第二个参数一共有5种,分别是:cv2.CV_8U,cv2.CV_16S,cv2.CV_32F,cv2.CV_64F,cv2.CV_16U
# 这五种类型的图像,分别表示8位无符号整数、16位有符号整数、32位浮点数、64位浮点数和16位无符号整数。sobelx = cv2.Sobel(image,cv2.CV_64F,1,0,ksize=3)cv_show(sobelx,'sobelx')
if __name__ == '__main__':image = cv2.imread('10.png')cv_Xshow(image)

运行代码后,求水平梯度图像如下:

注:

原本应该右边应该也出现白边但是这个图像并无这条边,原因是:白到黑是整数,黑到白就是负数,所有的负数会被截断成0,所以要取绝对值。

调整后的代码如下:

注:

cv2.convertScaleAbs的作用是把图像的像素值转换成绝对值,并返回一个图像

调整后代码的图像呈现如下:

import cv2
import numpy as np
def cv_show(img,name):cv2.imshow(name,img)cv2.waitKey(0)cv2.destroyAllWindows()
def cv_Xshow(image):# Sobel算子第二个参数一共有5种,分别是:cv2.CV_8U,cv2.CV_16S,cv2.CV_32F,cv2.CV_64F,cv2.CV_16U
# 这五种类型的图像,分别表示8位无符号整数、16位有符号整数、32位浮点数、64位浮点数和16位无符号整数。sobelx = cv2.Sobel(image,cv2.CV_64F,1,0,ksize=3)# cv2.convertScaleAbs的作用是把图像的像素值转换成绝对值,并返回一个图像sobelx = cv2.convertScaleAbs(sobelx)cv_show(sobelx,'sobelx')
if __name__ == '__main__':image = cv2.imread('10.png')cv_Xshow(image)

求垂直梯度代码演示如下:

原图如下:

代码如下:

import cv2
import numpy as np
def cv_show(img,name):cv2.imshow(name,img)cv2.waitKey(0)cv2.destroyAllWindows()
def cv_Yshow(image):sobelY = cv2.Sobel(image,cv2.CV_64F,0,1,ksize=3)sobelY = cv2.convertScaleAbs(sobelY)cv_show(sobelY,'sobelY')
if __name__ == '__main__':image = cv2.imread('10.png')cv_Yshow(image)

代码过后的图像如下:

完整图像梯度的代码如下:

import cv2
import numpy as np
def cv_show(img,name):cv2.imshow(name,img)cv2.waitKey(0)cv2.destroyAllWindows()
def cv_Xshow(image):# Sobel算子第二个参数一共有5种,分别是:cv2.CV_8U,cv2.CV_16S,cv2.CV_32F,cv2.CV_64F,cv2.CV_16U# 这五种类型的图像,分别表示8位无符号整数、16位有符号整数、32位浮点数、64位浮点数和16位无符号整数。sobelx = cv2.Sobel(image,cv2.CV_64F,1,0,ksize=3)# cv2.convertScaleAbs的作用是把图像的像素值转换成绝对值,并返回一个图像sobelx = cv2.convertScaleAbs(sobelx)return sobelx
def cv_Yshow(image):sobelY = cv2.Sobel(image,cv2.CV_64F,0,1,ksize=3)sobelY = cv2.convertScaleAbs(sobelY)return sobelY
def cv_XYshow(image,sobelX,sobelY):sobelXY = cv2.addWeighted(sobelX,0.5,sobelY,0.5,0)cv_show(sobelXY,'sobelXY')return None
if __name__ == '__main__':image = cv2.imread('10.png')cv_XYshow(image,cv_Xshow(image),cv_Yshow(image))

运行代码后的图像呈现如下:

注:

不建议直接进行计算,建议使用cv2.addWeighted进行梯度的计算。

直接计算梯度的代码演示如下:

import cv2
import numpy as np
src = cv2.imread('10.png')
sobelX = cv2.Sobel(src,cv2.CV_64F,1,0)
sobelY = cv2.Sobel(src,cv2.CV_64F,0,1)
sobelXY = cv2.Sobel(src,cv2.CV_64F,1,1)
cv2.imshow('sobelXY',sobelXY)
cv2.waitKey(0)
cv2.destroyAllWindows()

注:

从此可以看出来如果直接计算图像的呈现并不好。因此最好使用cv2.addWeighted进行水平和垂直的相加进行的一个比例分布。

综合运行梯度计算的代码如下:

原图如下:

代码如下:

import cv2
import numpy as np
def cv_show(img,name):cv2.imshow(name,img)cv2.waitKey(0)cv2.destroyAllWindows()
img = cv2.imread('2.jpg')
sobelX = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobelX = cv2.convertScaleAbs(sobelX)
sobelY = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobelY = cv2.convertScaleAbs(sobelY)
sobelXY = cv2.addWeighted(sobelX,0.5,sobelY,0.5,0)
cv_show(sobelXY,'sobelXY')

代码运行后的图像呈现如下:

注:

这种计算梯度的方式可以取出一个图像的基本框架。

二.Scharr算子与laplacian算子

Scharr算子与Sobel本质没什么太大区别,基本原理依旧如同Sobel算子一样。唯一区别是Scharr算子核的数据要比Sobel算子的处理的数据更敏感(较大)。

接下来讲解讲解laplacian算子。

从图可以看出laplacian算子与前面二种算子有很大区别。

laplacian算子的计算方法如下:

laplacian算子计算方式是G = 1*p2+ 1*p4+1*p6+1*p8-4*p5

相当于拿中间的P6与周围边缘点进行比较,由于周围边缘点是4个都是正的,所以是中间的点为-4,这就是它与其他算子核不同的原因。

三种算子的程序如下:

原图:

代码如下:

import cv2
import numpy as np
# 不同算子的差异
img = cv2.imread("5.jpg")
gray = cv2.cvtColor(img,cv2.IMREAD_GRAYSCALE)
# sobel算子
sobelx = cv2.Sobel(gray,cv2.CV_64F,1,0,ksize=3)
sobely = cv2.Sobel(gray,cv2.CV_64F,0,1,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)
sobely = cv2.convertScaleAbs(sobely)
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
# Scharr算子
scharrx = cv2.Scharr(gray,cv2.CV_64F,1,0)
scharry = cv2.Scharr(gray,cv2.CV_64F,0,1)
scharrx = cv2.convertScaleAbs(scharrx)
scharry = cv2.convertScaleAbs(scharry)
scharrxy = cv2.addWeighted(scharrx,0.5,scharry,0.5,0)
#  laplacian算子
laplacian = cv2.Laplacian(gray,cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)res = np.hstack((sobelxy,scharrxy,laplacian))
cv2.imshow("res",res)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行代码后如下:

三.Canny边缘检测

以下是Canny边缘检测算法的步骤如下:

1)使用高斯滤波器,以平滑图像,滤除噪声。

2)计算图像中每个像素点的梯度强度和方向。

3)应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应。

4)应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘。

5)通过抑制孤立的弱边缘最终完成边缘检测。

1.高斯滤波器

2.梯度和方向

运用了Sobel算子

3.非极大值抑制

非极大值抑制有两种方法;

方法一:

方法二:为了简化计算,由于一个像素周围有八个像素,把一个像素的梯度方向离散为八个方向,这样就只需计算前后即可,不用插值了。

4.双阈值检测

Canny边缘检测算法演示代码如下:

import cv2
import numpy as npimg = cv2.imread('9.jpg',cv2.IMREAD_GRAYSCALE)
# 高斯滤波,降噪
img = cv2.GaussianBlur(img,(5,5),0)
# 边缘检测
# 第一个参数是图像,第二个参数是低阈值,第三个参数是高阈值
v1 = cv2.Canny(img,80,160)
v2 = cv2.Canny(img,50,200)res = np.hstack((v1,v2))
cv2.imshow('res',res)
cv2.waitKey(0)
cv2.destroyAllWindows()

注:

从此可以看出来Canny边缘检测,你设置的阈值越大检测的东西检测边界的东西越少,设置阈值越小检测边界的东西越丰富。

Canny语法格式:cv2.Canny(图像,低阈值,高阈值)

http://www.xdnf.cn/news/4648.html

相关文章:

  • 详细聊聊 Synchronized,以及锁的升级过程
  • 二极管的动态特性
  • AI(学习笔记第二课) 使用langchain进行AI开发
  • Coco AI 开源应用程序 - 搜索、连接、协作、您的个人 AI 搜索和助手,都在一个空间中。
  • 【CTFer成长之路】举足轻重的信息搜集
  • 数据结构之串
  • 【PmHub后端篇】PmHub Gateway全局过滤器:接口调用耗时统计及黑白名单配置技术深度解析
  • 57.[前端开发-前端工程化]Day04-webpack插件模式-搭建本地服务器
  • XML语言
  • 企业开发平台大变革:AI 代理 + 平台工程重构数字化转型路径
  • Android单例模式知识总结
  • 02_JVM
  • Mockoon 使用教程
  • 为什么使用Less替代原始CSS?
  • 学习黑客MAC 地址
  • 数字孪生市场格局生变:中国2025年规模214亿,工业制造领域占比超40%
  • 安卓应用卡顿、性能低下的背后原因
  • 【文献阅读】Depth Anything Unleashing the Power of Large-Scale Unlabeled Data
  • 2025-05-08 Unity 网络基础9——FTP通信
  • Linux的基础开发工具
  • 手机上使用的记录笔记的软件推荐哪一款
  • SAP 交货单行项目含税金额计算报cx_sy_zerodivide处理
  • 云手机虚拟地址技术的运营场景
  • n8n - 开放灵活的智能自动化工作流平台
  • uniapp自定义步骤条(可二开进行调试)
  • shader中性能优化
  • docker 部署clickhouse
  • App Store支付新政重构跨境电商生态:eBay卖家的突围之道
  • vue中scss使用js的变量
  • OpenCv实战笔记(3)基于opencv实现调用摄像头并实时显示画面