基于opencv的边缘检测方法

news2025/2/26 15:10:53

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 np

im1 = 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 cv2

im1 = 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 cv2

im1 = 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 cv2

im1 = cv2.imread(r"fiction\xiaozhu.jpg", cv2.IMREAD_GRAYSCALE)

##向下取样,长、宽各变为1/2
im1Low = cv2.pyrDown(im1)

##向上取样,长、宽各变为原来2倍,会变模糊
im1High = cv2.pyrUp(im1Low)

##拉普拉斯金字塔结果
lapPyr = im1-im1High

cv2.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 cv2

o = 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 np

o = 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] = 0

ishift = 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://www.coloradmin.cn/o/427270.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mybatis【第一个 Mybatis 程序】

目录 一、Maven 环境配置 1、配置 pom.xml 1.1、依赖的 jar包 1.2、防止资源导出失败 2、在resources下编写 Mybatis核心配置文件 二、搭建结构 1、编写mybatis工具类(utils) 2、编写实体类(pojo) 3、Mybatis 的实现&…

【Vue3实践】(六)Vue3使用vite处理环境变量、打包部署、nginx配置

文章目录1.前言2.环境变量2.1.环境变量文件(.env)2.2.环境变量变量定义与使用3.打包部署3.1.nginx配置3.2.静态站点根路径配置4.总结1.前言 由于在日常开发中会有一部分前端的开发任务,会涉及到Vue的项目的搭建、迭代、构建发布等操作,所以想系统的学习…

Linux:主机USB设备驱动简析

文章目录1. 前言2. 分析背景3. USB 总线硬件拓扑4. USB 协议栈概览4.1 Linux USB 子系统概览4.2 USB外设(如U盘)固件基础5. Linux USB 子系统初始化6. Linux USB 主机控制器(HCD) 驱动6.1 USB 主机控制器驱动初始化6.2 USB 主机控制器设备对象注册和驱动加载7. Linux USB 设备驱…

Chatgpt接入Csdn:实现自动回复、评论、点赞

背景 起初,我只是想自己弄个工具,用来处理一下大佬们的三连支持,后面我发现大家都在讨论chatgpt,于是我将自动回复和评论消息接入到了Csdn中,不知道这篇文章能不能发出来,代码的话暂时不开源,后…

【从零开始】Docker Desktop:听说你小子要玩我

前言 🍊缘由 捡起遗忘的Docker知识 由于本狗近期项目紧任务重,高强度的搬砖导致摸鱼时间下降。在上线项目时,看到运维大神一系列骚操作,dockerk8s的知识如过眼云烟,忘得干净的很。所以想重新恶补一下docker知识&…

深度学习中的卷积神经网络

博主简介 博主是一名大二学生,主攻人工智能研究。感谢让我们在CSDN相遇,博主致力于在这里分享关于人工智能,c,Python,爬虫等方面知识的分享。 如果有需要的小伙伴可以关注博主,博主会继续更新的&#xff0c…

OpenCV实战(17)——FAST特征点检测

OpenCV实战(17)——FAST特征点检测0. 前言1. FAST 特征点检测2. 自适应特征检测3. 完整代码小结系列链接0. 前言 Harris 算子根据两个垂直方向上的强度变化率给出了角点(或更一般地说,兴趣点)的数学定义。但使用这种定义需要计算图像导数&am…

Android 14 新 API:直接监听截屏操作,不用再观察媒体文件了~

截屏可以说是手机设备最常用的功能了,Android 系统非常重视截屏方面的体验,近几年的更新都不忘去优化这方面的体验。 从一开始仅在通知栏提醒已截屏,到 Android 11 支持在左下角生成截屏缩略图供编辑或分享,再到 Android 12 支持…

计算机图形学 | 变换与观察

计算机图形学 | 变换与观察计算机图形学 | 变换与观察6.1 神奇的齐次坐标回顾几何阶段几何变换平移比例旋转对称错切齐次坐标的引入齐次坐标的概念和相关问题基于齐次坐标的变换6.2 三维模型,动起来!基本三维变换平移比例旋转对称错切整体比例变换逆变换…

《计算机网络——自顶向下方法》精炼——1.4到1.7

三更灯火五更鸡,努力学习永不止。无惧困难与挑战,砥砺前行向成功。 文章目录引言正文时延排队时延吞吐量协议层次,服务模型(重点)封装(重点)网络安全(选看)恶意软件的分类…

【数据分析与挖掘】数据预处理

目录概述一、数据清洗1.1 缺失值处理1.1.1 拉格朗日插值法1.1.2 牛顿插值法1.2 异常值处理二、数据集成2.1 实体识别2.2 冗余属性识别三、数据变换3.1 简单函数变换3.2 规范化3.3 连续属性离散化3.4 属性构造3.5 小波变换四、数据规约4.1 属性规约4.2 数值规约概述 数据挖掘过…

Spring Boot中使用Redis

目录 1.依赖 2.依赖关系 3.配置 4.RedisTemplate 5.基础操作 6.事务 1.依赖 maven依赖如下,需要说明的是,spring-boot-starter-data-redis里默认是使用lettuce作为redis客户端的驱动,但是lettuce其实用的比较少,我们常用的…

如何在 Web 实现支持虚拟背景的视频会议

前言 众所周知,市面上有比如飞书会议、腾讯会议等实现视频会议功能的应用,而且随着这几年大环境的影响,远程协作办公越来越成为常态,关于视频会议的应用也会越来越多,且在远程办公的沟通协作中对沟通软件的使用要求会…

ARMv8-A非对齐数据访问支持(Alignment support)

目录 1,对齐传输和非对齐传输 2,AArch32 Alignment support 2.1 Instruction alignment 指令对齐 2.2 Unaligned data access 非对齐数据访问 2.3 SCTLR.A Alignment check enable 3,AArch64 Alignment support 3.1 Instruction align…

Text to image论文精读GigaGAN: 生成对抗网络仍然是文本生成图像的可行选择

GigaGAN是Adobe和卡内基梅隆大学学者们提出的一种新的GAN架构,作者设计了一种新的GAN架构,推理速度、合成高分辨率、扩展性都极其有优势,其证明GAN仍然是文本生成图像的可行选择之一。 文章链接:https://arxiv.org/abs/2303.0551…

大数据周会-本周学习内容总结07

目录 01【hadoop】 1.1【编写集群分发脚本xsync】 1.2【集群部署规划】 1.3【Hadoop集群启停脚本】 02【HDFS】 2.1【HDFS的API操作】 03【MapReduce】 3.1【P077- WordCount案例】 3.2【P097-自定义分区案例】 历史总结 01【hadoop】 1.1【编写集群分发脚本xsync】…

【vue3】关于ref、toRef、toRefs那些事

😉博主:初映CY的前说(前端领域) 📒本文核心:ref、toRef、toRefs的使用方法 【前言】我们在上一节的学习当中,使用了reactive()函数将vue3中的数据变成响应式的数据,本文中所讲的三个方法也能实现将数据转化…

安全防御之IPsec VPN篇

目录 1.什么是数据认证,有什么用,有哪些实现的技术手段? 2.什么是身份认证,有什么用,有哪些实现的技术手段? 3.什么是VPN技术? 4.VPN技术有哪些分类? 5.IPsec技术能够提供哪些安…

走进小程序【八】微信小程序中使用【Vant组件库】

文章目录🌟前言🌟Vant介绍🌟Vant安装🌟npm 支持🌟使用Vant🌟引入组件🌟页面使用组件🌟样式覆盖🌟介绍🌟解除样式隔离🌟使用外部样式类&#x1f31…

基于冯洛伊曼拓扑的鲸鱼算法用于滚动轴承的故障诊断研究(Matlab代码实现)

👨‍🎓个人主页:研学社的博客💥💥💞💞欢迎来到本博客❤️❤️💥💥🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密…