OPENCV(三)对图片进行边缘检测

边缘检测的意义

边缘检测是图像处理和计算机视觉中的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点。图像属性中的显著变化通常反映了属性的重要事件和变化。 这些包括(i)深度上的不连续、(ii)表面方向不连续、(iii)物质属性变化和(iv)场景照明变化。 边缘检测是图像处理和计算机视觉中,尤其是特征提取中的一个研究领域。

1.sobel算子

Sobel算子是一种常用的边缘检测算子,是一阶的梯度算法;对噪声具有平滑作用,提供较为精确的边缘方向信息,边缘定位精度不够高;当对精度要求不是很高时,是一种较为常用的边缘检测方法。常见的应用和物理意义是边缘检测。

思想:

算子使用两个3*3的矩阵算子分别和原始图片作卷积,分别得到横向Gx和纵向Gy的梯度值,如果梯度值大于某一个阈值,则认为该点为边缘点;
在这里插入图片描述
矩阵转换:
事实上卷积矩阵也可以由两个一维矩阵卷积而成,在opencv源码中就是用两个一维矩阵卷积生成一个卷积矩阵:
在这里插入图片描述
梯度值:

图像的梯度值由以下公式计算:
图像近似梯度值如下:
对于原始图像,P5的梯度值为:
在这里插入图片描述
而opencv中怎么使用,请看下面的代码:

import cv2
import numpy as np
from scipy import signal

#读取图片
src_s = cv2.imread('../img/dip_switch_02.bmp', 0)
#对图片进行反色
src = cv2.bitwise_not(src_s)


# Sobel边缘检测算子
x = cv2.Sobel(src, cv2.CV_16S, 1, 0)
y = cv2.Sobel(src, cv2.CV_16S, 0, 1)
# cv2.convertScaleAbs(src[, dst[, alpha[, beta]]])
# 可选参数alpha是伸缩系数,beta是加到结果上的一个值,结果返回uint类型的图像
Scale_absX = cv2.convertScaleAbs(x)  # convert 转换  scale 缩放
Scale_absY = cv2.convertScaleAbs(y)
edgesobel = cv2.addWeighted(Scale_absX, 0.5, Scale_absY, 0.5, 0)
edgesobel2 = cv2.bitwise_not(edgesobel)
cv2.putText(edgesobel2,"Sobel",(50,50),cv2.FONT_HERSHEY_SIMPLEX,1.5,(0,0,255),4)
#显示图片
cv2.imshow('src_s', src_s)
cv2.imshow('sobel', edgesobel2)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行效果:
在这里插入图片描述

2.rober检测算子

Robert算子,又称Roberts边缘检测算子,是一种利用局部差分算子寻找边缘的算子。Robert算子图像处理后结果边缘不是很平滑。经分析,由于Robert算子通常会在图像边缘附近的区域内 产生较宽的响应,故采用上述算子检测的边缘图像常需做细化处理,边缘定位的精度不是很高。

def roberts(I, _boundary='fill', _fillvalue=0):
    # 图像的高,宽
    H1, W1 = I.shape[0:2]
    # 卷积核的尺寸
    H2, W2 = 2, 2
    # 卷积核1 和 锚点的位置
    R1 = np.array([[1, 0], [0, -1]], np.float32)
    kr1, kc1 = 0, 0
    # 计算full卷积
    IconR1 = signal.convolve2d(I, R1, mode='full', boundary=_boundary, fillvalue=_fillvalue)
    IconR1 = IconR1[H2 - kr1 - 1:H1 + H2 - kr1 - 1, W2 - kc1 - 1:W1 + W2 - kc1 - 1]
    # 卷积核2 和 锚点的位置
    R2 = np.array([[0, 1], [-1, 0]], np.float32)
    kr2, kc2 = 0, 1
    # 再计算full卷积
    IconR2 = signal.convolve2d(I, R2, mode='full', boundary=_boundary, fillvalue=_fillvalue)
    IconR2 = IconR2[H2 - kr2 - 1:H1 + H2 - kr2 - 1, W2 - kc2 - 1:W1 + W2 - kc2 - 1]
    return (IconR1, IconR2)
IconR1, IconR2 = roberts(src, 'symm')
# 45度方向上的边缘强度的灰度级显示
IconR1 = np.abs(IconR1)
edge45 = IconR1.astype(np.uint8)
# 135度方向上的边缘强度的灰度级显示
IconR2 = np.abs(IconR2)
edge135 = IconR2.astype(np.uint8)
# 用平方和的开方来衡量最后输出的边缘
edge = np.sqrt(np.power(IconR1, 2.0) + np.power(IconR2, 2.0))
edge = np.round(edge)
edge[edge > 255] = 255
edge = edge.astype(np.uint8)
edge2 = cv2.bitwise_not(edge)
cv2.putText(edge2,"robert",(50,50),cv2.FONT_HERSHEY_SIMPLEX,1.5,(0,0,255),4)

运行效果:
在这里插入图片描述

3.高斯拉普拉斯算子

高斯拉普拉斯算子又称为LOG(Laplacian of Gaussian)算子,是在高斯函数的基础上再利用拉普拉斯算子提取边缘得出的一个算子。
拉普拉斯算子是一种高通滤波器,是影像灰度函数在两个垂直方向二阶偏导数之和。在离散数字影像的情况下,直接用影像灰度级的二阶差分代替连续情形下的二阶偏导数,对噪声很敏感,在提取边缘时往往会出现伪边缘响应。为克服拉普拉斯算子的不足,宜先对数字影像进行低通滤波,抑制噪声。高斯函数是一种很好的归一化低通滤波器,可用于对数字影像进行低通滤波以减少噪声的影响,在此基础上再利用拉普拉斯算子提取边缘,这就是高斯-拉普拉斯算子,又称为LOG(Laplacian of Gaussian)算子。

#拉普拉斯算子(高斯)
laplacian = cv2.Laplacian(src, cv2.CV_16S, ksize=5)
dst = cv2.convertScaleAbs(laplacian)
lap = cv2.bitwise_not(dst)
cv2.putText(lap,"guass",(50,50),cv2.FONT_HERSHEY_SIMPLEX,1.5,(0,100,255),4)

运行效果:
在这里插入图片描述

使用OpenCV读取图片边缘,可以使用Canny边缘检测算法。以下是一个基本的示例代码: ```python import cv2 # 读取图片 img = cv2.imread('image.jpg') # 转换为灰度图像 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 进行边缘检测 edges = cv2.Canny(gray, 100, 200) # 显示原图和边缘检测结果 cv2.imshow('Original Image', img) cv2.imshow('Canny Edges', edges) cv2.waitKey(0) cv2.destroyAllWindows() ``` 要进行视频边缘匹配,您需要首先使用OpenCV读取视频文件,并使用Canny算法提取每个帧的边缘。然后,您可以将这些边缘与目标图像的边缘进行匹配,以检测视频中是否存在目标图像。 以下是一个基本的示例代码: ```python import cv2 # 读取目标图像 target_img = cv2.imread('target_image.jpg') target_gray = cv2.cvtColor(target_img, cv2.COLOR_BGR2GRAY) target_edges = cv2.Canny(target_gray, 100, 200) # 读取视频文件 cap = cv2.VideoCapture('video.mp4') while True: # 读取一帧 ret, frame = cap.read() if not ret: break # 将帧转换为灰度图像并进行边缘检测 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) edges = cv2.Canny(gray, 100, 200) # 进行边缘匹配 # 这里省略具体的匹配算法 # 如果找到了目标图像的边缘,就在帧上标记出来 # 如果没有找到,就继续读取下一帧 cv2.imshow('Video', frame) if cv2.waitKey(1) == ord('q'): break cap.release() cv2.destroyAllWindows() ``` 请注意,这只是一个基本的示例代码,您需要根据具体的应用场景和匹配算法进行修改和完善。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

键盘歌唱家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值