基于opencv的边缘检测方法

article/2025/9/15 3:52:07

1、梯度运算

用OpenCV的形态变换( 膨胀、腐蚀、开运算和闭运算)函数morphologyEx
梯度运算即膨胀结果-腐蚀结果:
在这里插入图片描述
【注意】对于二值图像来说,必须是前景图像为白色,背景为黑色,否则需要进行反二值化处理

import cv2
import matplotlib.pyplot as plt
import numpy as np##读入图片
im1 = cv2.imread(r"fiction\xiaozhu.jpg", cv2.IMREAD_GRAYSCALE)
#创建一个5行5列的值全为1 的卷积核
k = np.ones((5,5),np.uint8)
##进行梯度运算
r = cv2.morphologyEx(im1, cv2.MORPH_GRADIENT, k)##图像展示
plt.subplot(1,2,1)
plt.imshow(im1, cmap="gray")
plt.axis("off")
plt.subplot(1,2,2)
plt.imshow(r, cmap= "gray")
plt.axis("off")
plt.show()

在这里插入图片描述

2、sobel算子

可以计算不同方向的梯度,梯度运算如下图所示:
在这里插入图片描述
得出x方向的梯度值和y方向的梯度值后,通过G = sqr(GX2 + GY2)或G = |GX|+G|Y|得到整幅图像的梯度。

cv2.Sobel参数:
在这里插入图片描述
【注意】
1、如果梯度为负数,会无法显示,所以计算完梯度之后需要进行取绝对值处理。
2、同时计算x方向和y方向的梯度,通常没有分别计算两个方向梯度后,进行后处理效果好,通常用cv2.addWeighted(src1, alpha, src2, beta, gamma)进行修正。
3、卷积核大小只能为奇数。

import cv2
import numpy as npim1 = cv2.imread(r"fiction\xiaozhu1.jpg",cv2.IMREAD_GRAYSCALE)
##默认卷积核为3*3,如果写cv2.Sobel(im1, 0, 1, 0)的话,只能取到一侧边界,另一侧边界值为负,会被规整成0
sobelx = cv2.Sobel(im1, cv2.CV_64F, 1, 0,ksize=3)
sobely = cv2.Sobel(im1, cv2.CV_64F, 0, 1,ksize=3)
##取绝对值
cv2.convertScaleAbs(sobelx)sobelxy = cv2.addWeighted(sobelx, 0.5, sobely, 0.5, 0)
##同时取x、y的sobel算子没有单独计算x、y然后相加的效果好
sobel_tmp = cv2.Sobel(im1, cv2.CV_64F, 1, 1)
cv2.convertScaleAbs(sobel_tmp)cv2.namedWindow("dx=1", 0)
cv2.namedWindow("dy=1", 0)
cv2.namedWindow("after addWeighted", 0)
cv2.namedWindow("dx=1,dy=1", 0)
cv2.imshow("dx=1", sobelx)
cv2.imshow("dy=1", sobely)
cv2.imshow("after addWeighted", sobelxy)
cv2.imshow("dx=1,dy=1", sobel_tmp)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述
在这里插入图片描述

3、scharr算子

类似sobel算子,但是卷积核系数不同,离目标点越近的像素权重越大,边缘提取的效果比sobel算子好
在这里插入图片描述
二者效果对比如下:

import cv2im1 = cv2.imread(r"fiction\xiaozhu.jpg", cv2.IMREAD_GRAYSCALE)
##Scharr算子提取边缘,scharr相较于sobel算子,靠近核心部分的权值较大,边缘提取的效果更好,x与y不能同时为1
im1x = cv2.Scharr(im1, cv2.CV_64F, 1, 0)
im1y = cv2.Scharr(im1, cv2.CV_64F, 0, 1)
im1x = cv2.convertScaleAbs(im1x)
im1y = cv2.convertScaleAbs(im1y)
im1ScharryXY = cv2.addWeighted(im1x, 0.5, im1y, 0.5, 0)##拉普拉斯算子
imLap = cv2.Laplacian(im1,cv2.CV_64F)
imLap = cv2.convertScaleAbs(imLap)##对比sobel算子提取边缘的效果
im1SobelX = cv2.Sobel(im1, cv2.CV_64F, 1, 0)
im1SobelY = cv2.Sobel(im1, cv2.CV_64F, 0, 1)
im1SobelX = cv2.convertScaleAbs(im1SobelX)
im1SobelY = cv2.convertScaleAbs(im1SobelY)
im1SobelXY = cv2.addWeighted(im1SobelX, 0.5, im1SobelY, 0.5, 0)##sobel算子模拟scharr算子进行边缘提取
im1So_SC_X = cv2.Sobel(im1, cv2.CV_64F, 1, 0, -1)
im1So_SC_Y = cv2.Sobel(im1, cv2.CV_64F, 0, 1, -1)
im1So_SC_X = cv2.convertScaleAbs(im1So_SC_X)
im1So_SC_Y = cv2.convertScaleAbs(im1So_SC_Y)
im1So_SC_XY = cv2.addWeighted(im1So_SC_X, 0.5, im1So_SC_Y, 0.5, 0)cv2.namedWindow("im1ScharryXY", 0)
cv2.namedWindow("im1SobelXY", 0)
cv2.namedWindow("im1So_SC_XY", 0)
cv2.namedWindow("imLap", 0)
cv2.imshow("im1ScharryXY", im1ScharryXY)
cv2.imshow("im1SobelXY", im1SobelXY)
cv2.imshow("im1So_SC_XY", im1So_SC_XY)
cv2.imshow("imLap", imLap)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述依次为scharry算子、sobel算子、sobel仿scharry、拉普拉斯算子结果

4、canny边缘检测

原理:
1、高斯滤波去噪声
2、平滑后的图像用sobel算子计算梯度,梯度方向如下图所示:
在这里插入图片描述
梯度方向一般都与边界垂直,
一般归类为四个方向:垂直、水平,两个对角线

在这里插入图片描述

3、去除所有非边界点
在这里插入图片描述
在这里插入图片描述
4、滞后阈值
选取两个阈值,maxVal和minVal
在这里插入图片描述

5、用法,其实就一个函数,cv2.Canny()
在这里插入图片描述

import cv2im1 = cv2.imread(r"fiction\pig2.jpg", cv2.IMREAD_UNCHANGED)
im1 = cv2.Canny(im1, 128, 256)
im2 = cv2.Canny(im1, 0, 256)
im3 = cv2.Canny(im1, 0, 128)
im4 = cv2.Canny(im1, 0, 10)cv2.namedWindow("128_256",0)
cv2.namedWindow("0_256",0)
cv2.namedWindow("0_128",0)
cv2.namedWindow("0_10",0)
cv2.imshow("128_256",im1)
cv2.imshow("0_256",im2)
cv2.imshow("0_128",im3)
cv2.imshow("0_10",im4)
cv2.waitKey(0)

在这里插入图片描述
在这里插入图片描述

5、拉普拉斯金字塔

原图像减去(原图->向下采样->向上采样)
两次采样后图像会被平滑
在这里插入图片描述
在这里插入图片描述

import cv2im1 = cv2.imread(r"fiction\xiaozhu.jpg", cv2.IMREAD_GRAYSCALE)##向下取样,长、宽各变为1/2
im1Low = cv2.pyrDown(im1)##向上取样,长、宽各变为原来2倍,会变模糊
im1High = cv2.pyrUp(im1Low)##拉普拉斯金字塔结果
lapPyr = im1-im1Highcv2.namedWindow("im1Low",0)
cv2.namedWindow("im1High",0)
cv2.namedWindow("im1",0)
cv2.namedWindow("lapPyr",0)cv2.imshow("im1",im1)
cv2.imshow("im1Low",im1Low)
cv2.imshow("lapPyr",lapPyr)
cv2.imshow("im1High",im1High)cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述依次为原图、向下取样一次、向上取样、原图-向上取样结果
可多层构造拉普拉斯金字塔

5、findContours

这是个轮廓检测的方法,注意,边缘和轮廓是不一样的,边缘不一定连续,但是轮廓是连续的。

在这里插入图片描述
在这里插入图片描述

import cv2o = cv2.imread(r"fiction\xiaozhu.jpg", cv2.IMREAD_GRAYSCALE)
co = cv2.imread(r"fiction\xiaozhu.jpg", cv2.IMREAD_UNCHANGED)
cco = co.copy()
max_threshold,img = cv2.threshold(o,127,255,cv2.THRESH_BINARY)
##findcounters:原始图像、轮廓检测方式(只检测外轮廓、等级树形式等)、轮廓近似方式
##查找、绘制过程中会改变原图像
counters, hieraichy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
r = cv2.drawContours(co, counters, -1, (255,0,0),6)cv2.namedWindow("o", 0)
cv2.namedWindow("r", 0)
cv2.imshow("o", cco)
cv2.imshow("r", r)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

6、高通滤波

利用傅里叶变换,将o转化为频域
低频为内部信息,高频为边缘信息
通过高通滤波器得到边缘信息

#低频为内部信息,高频为边缘信息import cv2
import matplotlib.pyplot as plt
import numpy as npo = cv2.imread(r"fiction\xiaozhu.jpg", cv2.IMREAD_GRAYSCALE)
##利用傅里叶变换,将o转化为频域,cv2.DFT_COMPLEX_OUTPUT返回双通道的结果,包含幅度和频率,第一个通道是实数部分,第二个通道为虚数部分
#dft = cv2.dft(np.float32(o), flags=cv2.DFT_COMPLEX_OUTPUT)dft = np.fft.fft2(o)#将频域0点移动到中心
dft1 = np.fft.fftshift(dft)# result = 20*np.log(cv2.magnitude(dft1[:,:,0], dft1[:,:,1]))
#
# plt.subplot(2,2,1)
# plt.imshow(o, cmap="gray")
#
# plt.subplot(2,2,2)
# plt.imshow(result,cmap="gray")
#
# plt.show()##通过高通滤波器得到边缘信息
rows,cols = o.shape
crow,ccols = int(rows/2),int(cols/2)dft1[crow-3:crow+30,ccols-30:ccols+30] = 0ishift = np.fft.ifftshift(dft1)iimg = np.fft.ifft2(ishift)iimg = np.abs(iimg)plt.subplot(1,2,1)
plt.imshow(o,cmap="gray")plt.subplot(1,2,2)
plt.imshow(iimg,cmap="gray")plt.show()

在这里插入图片描述


http://chatgpt.dhexx.cn/article/vRFBttry.shtml

相关文章

OpenCV——Canny边缘检测

目录 简介 实现步骤 代码 原图 效果图 简介 Canny边缘检测是一种使用多级边缘检测算法检测边缘的方法。 实现步骤 step1:去噪。噪声会影响边缘检测的准确性,因此首先要将噪声过滤掉。 方法:图像边缘容易受到噪声的干扰,因此…

OpenCV——边缘检测原理

边缘检测原理 图像的边缘指的是图像中像素灰度值突然发生变化的区域,如果将图像的每一行像素和每一列像素都描述成一个关于灰度值的函数,那么图像的边缘对应在灰度值函数中是函数值突然变大的区域。函数值的变化趋势可以用函数的导数描述。当函数值突然…

OpenCV 边缘检测之Canny算法(代码应用)

Canny算法 Canny是边缘检测算法,在1986年提出的。 是一个很好的边缘检测器 很常用也很实用的图像处理方法 Canny算法步骤 消除噪声:高斯模糊 - GaussianBlur灰度转换 - cvtColor计算梯度 – Sobel/Scharr非最大信号抑制高低阈值输出二值图像 API&…

opencv边缘检测加提取(圆形和矩形)

因为加密了的原因,不好直接复制,大家看一下代码就好。

OpenCV之边缘检测

1.图片的高斯模糊 import cv2 import matplotlib.pyplot as pltimg cv2.imread(r"C:\Users\Curry\Desktop\goutou.png") gray cv2.cvtColor(img, codecv2.COLOR_BGR2GRAY) gray2 cv2.GaussianBlur(gray,(19,19),0) #高斯模糊 # canny cv2.Canny()cv2.imshow(gra…

OpenCV如何进行图像的边缘检测?OpenCV边缘检测操作流程

OpenCV提供了几种常见的图像边缘检测算法,包括Sobel算子、Scharr算子、Laplacian算子和Canny边缘检测算法。下面分别介绍这些算法及其实现方法。 Sobel算子 Sobel算子是一种常见的图像边缘检测算法,其原理是通过对图像进行卷积操作,计算出图像…

opencv-边缘检测

文章目录 一、Canny边缘检测1.1高斯滤波器2.1梯度和方向3.1非极大值抑制4.1双阈值检测 一、Canny边缘检测 Canny边缘检测器是一种被广泛使用的算法,并被认为是边缘检测最优的算法,该方法使用了比高斯差分算法更复杂的技巧,如多向灰度梯度和滞…

opencv边缘检测算子

实验三 边缘检测算子 一、 实验目的 利用opencv或其他工具编写实现下图的sobel算子和robert算子边缘检测 二、 实验过程 利用opencv python实现sobel算子和robert算子边缘检测 (1)在python安装opencv库 这个步骤我在第二个实验,图像滤波里写过了,就不…

OpenCV:边缘检测算法

边缘检测(英语:Edge detection)是图像处理和计算机视觉中的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点。图像属性中的显著变化通常反映了属性的重要事件和变化。这些包括(i)深度上的不连续、…

opencv边缘检测 roberts算子

定义roberts两个算子 分别为135度 和45度。 [1,0, 0,-1] [0,1 -1,0] 这里展示在c实现的过程。先展示下效果图 分别是45度角 135度角和边缘效果图。 #include<opencv2/opencv.hpp> #include<opencv2/core/core.hpp> #include<opencv2/imgproc/imgproc.hpp> #…

基于QT+OpenCV边缘检测、面积检测

没什么好说的就是调库&#xff0c;直接看下效果图&#xff0c;&#xff0c;基于OPENC4.5.1&#xff0c;如需要请 原图&#xff1a; 对图形进行描边并进行标号 面积检测

【学习OpenCV4】OpenCV边缘检测算法总结

本文分享内容来自图书《学习OpenCV 4&#xff1a;基于Python的算法实战》&#xff0c;该书内容如下&#xff1a; 第1章 OpenCV快速入门&#xff1b; 第2章 图像读写模块imgcodecs&#xff1b; 第3章 核心库模块core&#xff1b; 第4章 图像处理模块imgproc&#xff08;一&…

Opencv边缘检测、轮廓发现、绘制轮廓

Opencv边缘检测、轮廓发现、绘制轮廓 提取图像轮廓的2个步骤 1、 findContours函数找轮廓&#xff0c; 2、 drawContours函数画轮廓 轮廓的查找——cv::findContours() 函数cv::findContour是从二值图像中来计算轮廓的&#xff0c;它可以使用cv::Canny()函数处理的图像&am…

基于Python的Opencv边缘检测

边缘检测实际上就是对图像进行系统的梯度计算&#xff0c;包含了图像的噪声处理&#xff0c;非极大值抑制&#xff0c;双阈值检测等一系列图像处理方式&#xff0c;通过这些方式处理图像后得到图像的轮廓。这些方式在之前的博客都已经提到过i了&#xff0c;而Opencv提供了一个非…

OpenCV 边缘检测

一. 实验内容 用OpenCV对图片进行边缘检测。 二. 实验代码 //边缘检测 class Task17 { public:void deal() {Mat src_img imread("img\\1.jpg");imshow("边缘检测[原图]", src_img);Mat gray_img;cvtColor(src_img, gray_img, COLOR_BGR2GRAY);Mat out…

java-opencv边缘检测

安装opencv 导入jar包需要dll jar包在opencv\build\java目录里&#xff0c;dll文件在opencv\build\java\64x目录里 边缘检测 package opencv;import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc…

python opencv边缘检测

通过Opencv进行边缘检测可以说是十分常见了&#xff0c;接下来让我们聊一聊如何通过python opencv一步一步实现边缘检测 重要函数讲解 图片读取函数: pic cv2.imread(file_path, flagNone) 参数&#xff1a; file_path:读取的图片的路径。这里要注意如果图像不能读取(由于…

python-opencv边缘检测

9.python-opencv边缘检测 第一章 python-opencv-图片导入和显示 第二章 python-opencv图像简单处理 第三章 python-opencv图像mask掩膜处理 第四章 python-opencv图像马赛克 第五章 python-opencv人脸马赛克 第六章 python-opencv人脸检测 第七章 python-opencv图像张贴 第八章…

opencv边缘检测

边缘检测的一般步骤 滤波 边缘检测的算法对噪声很敏感&#xff0c;所以采用滤波器来改善边缘检测器的性能。 增强 增强边缘的基础是确定图像各点邻域强度的变化值。增强算法可以将图像灰度点邻域强度值有显著变化的点凸显出来。在具体编程实现时&#xff0c;可通过计算梯度…

14---OpenCV:图像检测之边缘检测

一、图像边缘 边缘(edge)是指图像局部强度变化最显著的部分。主要存在于目标与目标、目标与背景、区域与区域(包括不同色彩)之间&#xff0c;是图像分割、纹理特征和形状特征等图像分析的重要基础。图像强度的显著变化可分为&#xff1a; 阶跃变化函数&#xff0c;即图像强度在…