【OpenCV_python】噪点消除(滤波) 边缘检测Canny算法 轮廓绘制

server/2024/11/13 0:31:46/

图片降噪

  1. 均值滤波blur
    中心点的像素值等于核值区域的平均值
python">
import cv2
img_gs = cv2.imread('./media/lvbo2.png') # 高斯噪声
img_jy = cv2.imread('./media/lvbo3.png') # 椒盐噪声def buler():img_jz1= cv2.blur(img_gs,(3,3))img_jz2= cv2.blur(img_jy,(3,3))cv2.imshow('img_jz1',img_jz1)cv2.imshow('img_jz2',img_jz2)buler()cv2.imshow('img_gs',img_gs)
cv2.imshow('img_jy',img_jy)cv2.waitKey(0)

高斯噪声,比较均匀的噪点
椒盐噪声
在这里插入图片描述

在这里插入图片描述

  1. 方框滤波boxFilter
  • normalize=False 中心点的像素值等于核区域像素的总和
  • normalize=True 默认为True 就是均值滤波
python">    img_jz1 = cv2.boxFilter(img_gs,-1,(3,3),normalize=False )  # [图像]  [输出图像的深度,-1是原图像的深度]  [核的大小]img_jz2 = cv2.boxFilter(img_jy,-1,(3,3))cv2.imshow('img_jz1',img_jz1)cv2.imshow('img_jz2',img_jz2)

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

  1. 高斯滤波GaussianBlur
    核的权重取决于高斯函数并取近似值,对应的像素乘以权重相加得到中心点的像素值
    sigma的值 模糊效果越明显 (中心点的权重变小)
    g ( x , y ) = 1 2 π σ 2 e − ( x 2 + y 2 ) 2 σ 2 g(x,y)=\frac{1}{2\pi\sigma^{2}}e^{-\frac{(x^{2}+y^{2})}{2\sigma^{2}}} g(x,y)=2πσ21e2σ2(x2+y2)
    如3*3的核权重矩阵是[[1/16,1/8,1/16],[1/8,1/4,1/8],[1/16,1/8,1/16]]
python">    img_jz1 = cv2.GaussianBlur(img_jy,(3,3),10) # 图像 核大小   sigma的值  值越大 模糊效果越明显 img_jz2 = cv2.GaussianBlur(img_gs,(3,3),10)

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

  1. 中值滤波
    对核值大小范围内像素值排序,取中位数,对椒盐噪声和斑点效果较好,效率较低
python">    img_jz1 = cv2.medianBlur(img_gs,3)    # 图像 核大小img_jz2 = cv2.medianBlur(img_jy,3)  # 均值滤波

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

  1. 双边滤波

同时考虑像素点周围的点和像素值的大小

核值范围内每个像素点的权重值由位置的权重和像素值的权重相乘得到

ω ( i , j , k , l ) = w s ∗ w r \omega(i,j,k,l)=w_{s}*w_{r} ω(i,j,k,l)=wswr
空间位置的权重值
ω s = e − ( i − k ) 2 + ( j − l ) 2 2 σ s 2 \omega_{s}=e^{-{\frac{(i-k)^{2}+(j-l)^{2}}{2\sigma_{s}{}^{2}}}} ωs=e2σs2(ik)2+(jl)2
像素值大小得到的权重
ω r = e − ∥ f ( i , j ) − f ( k , l ) ∥ 2 2 σ r 2 \omega_{r}=e^{-{\frac{\|f(i,j)-f(k,l)\|^{2}}{2\sigma_{r}{}^{2}}}} ωr=e2σr2f(i,j)f(k,l)2

python">    img_jz1 = cv2.bilateralFilter(img_gs,9,70,70)img_jz2 = cv2.bilateralFilter(img_jy,9,70,70)

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

边缘检测

  1. Sobel 算子
    k = [ − 1 0 1 − 1 0 1 − 1 0 1 ] k=\left[{\begin{array}{r r r}{-1}&{0}&{1}\\ {-1}&{0}&{1}\\ {-1}&{0}&{1}\end{array}}\right] k= 111000111
python">    boder_x = cv2.Sobel(img_nut,-1,1,0)  # x方向的梯度,就是y方向的边缘boder_y = cv2.Sobel(img_nut,-1,0,1)  # y方向的梯度cv2.imshow('boder_x',boder_x)cv2.imshow('boder+y',boder_y)

在这里插入图片描述

  1. Scharr算子
    k = [ − 3 0 3 − 10 0 10 − 3 0 3 ] k=\left[{\begin{array}{r r r}{-3}&{0}&{3}\\ {-10}&{0}&{10}\\ {-3}&{0}&{3}\end{array}}\right] k= 31030003103
python">    boder_x = cv2.Scharr(img_nut,-1,1,0)boder_y = cv2.Scharr(img_nut,-1,0,1)

在这里插入图片描述

  1. Laplacian算子
    k = [ 1 1 1 1 − 8 1 1 1 1 ] k=\left[\begin{array}{c c c}{1}&{1}&{1}\\ {1}&{-8}&{1}\\ {1}&{1}&{1}\end{array}\right] k= 111181111
python">boder = cv2.Laplacian(img_nut,-1)

在这里插入图片描述

  1. Canny边缘检测
    边缘的像素值和周围的像素值有着其差异,表现为较大的像素差值,通过这个特点找到图像的边缘
    Canny边缘检测步骤
    4.1 读取图像
    4.2 二值化图像
    4.3 高斯滤波
    4.4 计算图像的梯度和方向

    • 图像梯度
      • 通过算子也就是特定的核(矩阵)对图像进行运算,从而得到图像像素值的变化值。也就是对图像做差分,得到图像的梯度。梯度的大小,描述了图像像素值的变化程度
    • Canny中使用Subol算子对x反向和y方向进行求梯度
      • 两个方向的梯度相加取绝对值得到像素点的梯度
    • 通过反正弦函数求出梯度的方向
      • θ = arctan ⁡ ( G y G x ) \theta=\arctan\,({\frac{G_{\mathrm{y}}}{G_{x}}}) θ=arctan(GxGy)
      • 为了简化计算统一角度值,对角度进行插值,指定范围的角度统一到同一个角度
        在这里插入图片描述

    4.5 非极大值抑制

    • 得到图像每个像素点的梯度值和方向,通过在比较同方向的相邻像素点的梯度值,(梯度方向和边缘的方向垂直)保留最大的像素值,不是最大的就舍去,可以去掉一些不是边缘的像素点
      • 比较的像素点是梯度方向指向的领域内的像素点,确保得到的是局部最大值

    4.6 双阈值筛选

    • 通过指定两个阈值,去掉一些弱边缘
    • 大于高阈值,就是强边缘点
    • 小于低阈值就不是边缘点
    • 介于两者之间,弱边缘点
    • 根据连通性判断 是否保留,如果弱边缘点和强边缘有连通性,就保留弱边缘
python">    boder = cv2.Canny(img_nut,60,120) # 图像 低阈值  高阈值

在这里插入图片描述

绘制图像轮廓

  1. 寻找图像轮廓
    contours,hierarchy = cv2.findContours(image,mode,method)

contours 返回轮廓点的列表,子列表的格式就是轮廓的个数
hierarchy 轮廓的关系
mode:轮廓的搜索模式

  • RETR_LIST所有轮廓
  • RETE_EXTERNAL最外层轮廓
  • RETE_-CCOMP列出所有轮廓
  • RETR_TREE所有轮廓

method:对轮廓点的存储方式

  • CHAIN_APPROX_NONE表示将所有的轮廓点都进行存储;

  • CHAIN_APPROX_SIMPLE只存储有用的点 默认使用这个方法;

  • CHAIN_APPROX_TC89_L1减少轮廓中的冗余点,更加准确地表示轮廓的形状。

  • CHAIN_APPROX_TC89_L1是一种较为精确的轮廓逼近方法,适用于需要较高精度的轮廓表示的情况。

  1. 绘制轮廓
    cv2.drawContours(image, contours, contourIdx, color, thickness)
    图片,轮廓点,要绘制哪些轮廓,颜色,线条粗细
python">def contours():img_nut = cv2.imread('./media/nut.png')img_nut_gray = cv2.cvtColor(img_nut,cv2.COLOR_BGR2GRAY)nut_erzhi = cv2.adaptiveThreshold(img_nut_gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY_INV,25,10)cv2.imshow('nut_erzhi',nut_erzhi)contours,h = cv2.findContours(nut_erzhi,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)cv2.drawContours(img_nut,contours,-1,(255,0,0))cv2.imshow('nut',img_nut)contours()
cv2.waitKey(0)

在这里插入图片描述


http://www.ppmy.cn/server/102278.html

相关文章

SQL 调优最佳实践笔记

定义与重要性 SQL 调优:提高SQL性能,减少查询时间和资源消耗。目标:减少查询时间和扫描的数据行数。 基本原则 减少扫描行数:只扫描所需数据。使用合适索引:确保WHERE条件命中最优索引。合适的Join类型:…

javaweb_09:Mybatis基础操作

javaweb_09:Mybatis基础操作 一、环境准备二、删除三、插入四、更新(修改)五、查询六、实践 一、环境准备 1、准备数据库表emp -- 部门管理 create table dept(id int unsigned primary key auto_increment comment 主键ID,name varchar(10…

TreeSet的排序方式

一.TreeSet的特点: 二.TreeSet对象排序练习题: 需求:利用TreeSet存储整数并进行排序 package com.itheima.a06mySet; ​ import java.util.TreeSet; ​ public class A05_TreeSetDemo1 {public static void main(String[] args) {//1.创建T…

Eureka原理与实践:构建高效的微服务架构

Eureka原理与实践:构建高效的微服务架构 Eureka的核心原理Eureka Server:服务注册中心Eureka Client:服务提供者与服务消费者 Eureka的实践应用集成Eureka到Spring Cloud项目中创建Eureka Server创建Eureka Client(服务提供者&…

LabVIEW滚动轴承故障诊断系统

滚动轴承是多种机械设备中的关键组件,其性能直接影响整个机械系统的稳定性和安全性。由于轴承在运行过程中可能会遇到多种复杂的工作条件和环境因素影响,这就需要一种高效、准确的故障诊断方法来确保机械系统的可靠运行。利用LabVIEW开发的故障诊断系统&…

React使用useRef ts 报错

最近在写自己的React项目&#xff0c;我在使用useRef钩子函数的时候发现 TS2322: Type MutableRefObject<HTMLDivElement | undefined> is not assignable to type LegacyRef<HTMLDivElement> | undefined Type MutableRefObject<HTMLDivElement | undefined&g…

SDL库自适应窗口大小及遇到的坑

一、窗口尺寸改变大小时&#xff0c;视频卡住不动 网上介绍的方法有&#xff1a; 1&#xff1a;修改源码中的代码&#xff01; SDL_OnWindowResized中的SDL_WINDOWEVENT_SIZE_CHANGED更改为SDL_WINDOWEVENT_RESIZED 2&#xff1a;SDL_EventState(SDL_WINDOWEVENT, SDL_IGNORE…

Golang | Leetcode Golang题解之第343题整数拆分

题目&#xff1a; 题解&#xff1a; func integerBreak(n int) int {if n < 3 {return n - 1}quotient : n / 3remainder : n % 3if remainder 0 {return int(math.Pow(3, float64(quotient)))} else if remainder 1 {return int(math.Pow(3, float64(quotient - 1))) * …