《Opencv》基础操作详解(4)

server/2025/1/8 10:30:24/

目录

22、图像形态学操作

(1)、顶帽(原图-开运算)

公式:

应用场景:

代码示例:

(2)、黑帽(闭运算-原图)

公式:

应用场景:

代码示例:

23、边缘检测

(1)、Sobel算子边缘检测

用法说明:

代码示例:

(2)、Scharr算子边缘检测

用法说明:

代码示例:

(3)、Laplacian算子边缘检测

用法说明:

 代码示例:

(4)、 Canny边缘检测(常用)

24、图像轮廓检测

(1)、轮廓检测、绘制轮廓

## 查找轮廓

用法说明:

返回值:

## 绘制轮廓

用法说明:

代码示例:

(2)、轮廓特征


22、图像形态学操作

(1)、顶帽(原图-开运算)

顶帽操作是原始图像与开运算结果之间的差值。它可以用于提取比背景亮的微小细节。

cv2.morphologyEx(image, cv2.MORPH_TOPHAT, kernel)

公式:

                        Top Hat=原始图像−开运算结果 

应用场景:
  • 提取图像中比背景亮的微小区域(如文本、细胞、颗粒等)。

  • 去除不均匀光照的影响。

代码示例:
import cv2
import numpy as np
sun = cv2.imread('./images/sun.png')
cv2.imshow('sun',sun)
cv2.waitKey(0)
kernel = np.ones((2,2),np.uint8)
# 顶帽
tophat = cv2.morphologyEx(sun,cv2.MORPH_TOPHAT,kernel)
cv2.imshow('tophat',tophat)
cv2.waitKey(0)

(2)、黑帽(闭运算-原图)

黑帽操作是闭运算结果与原始图像之间的差值。它可以用于提取比背景暗的微小细节cv2.morphologyEx(image, cv2.MORPH_BLACKHAT, kernel)

公式:

                                Black Hat=闭运算结果−原始图像 

应用场景:
  • 提取图像中比背景暗的微小区域(如裂缝、孔洞等)。

  • 检测图像中的暗区域。

代码示例:
import cv2
import numpy as np
sun = cv2.imread('./images/sun.png')
cv2.imshow('sun',sun)
cv2.waitKey(0)
kernel = np.ones((2,2),np.uint8)
# 黑帽
blackhat = cv2.morphologyEx(sun,cv2.MORPH_BLACKHAT,kernel)
cv2.imshow('blackhat',blackhat)
cv2.waitKey(0)

 

23、边缘检测

(1)、Sobel算子边缘检测

Sobel 算子是一种离散的微分算子,该算子结合了高斯平滑和微分求导运算。该算子利用局部差分寻找边缘,计算所得的是一个梯度的近似值。

Sobel算子包含2组3×3的矩阵,分别为横向和纵向模板,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。 

用法说明:

cv2.Sobel(src, ddepth, dx, dy, ksize=None, scale=None, delta=None, borderType=None) 

  • src: 输入图像,通常是单通道灰度图像。

  • ddepth: 输出图像的深度(数据类型),例如 cv2.CV_8Ucv2.CV_16S 等。

  • dx: x 方向上的导数阶数。

  • dy: y 方向上的导数阶数。

  • ksize: Sobel 核的大小,必须是 1、3、5 或 7。默认值为 3。

  • scale: 可选的比例因子,应用于计算结果。

  • delta: 可选的增量值,添加到结果中。

  • borderType: 边界填充类型,默认值为 cv2.BORDER_DEFAULT

代码示例:
import cv2
yuan = cv2.imread('./images/yuan.png')
cv2.imshow('yuan',yuan)
cv2.waitKey(0)
# x方向
yuan_x = cv2.Sobel(yuan,-1,dx=1,dy=0)
yuan_x_64 = cv2.Sobel(yuan,cv2.CV_64F,dx=1,dy=0)
yuan_x_abs = cv2.convertScaleAbs(yuan_x_64)
cv2.imshow('yuan_x',yuan_x_abs)
cv2.waitKey(0)
# y方向
yuan_y = cv2.Sobel(yuan,-1,dx=0,dy=1)
yuan_y_64 = cv2.Sobel(yuan,cv2.CV_64F,dx=0,dy=1)
yuan_y_abs = cv2.convertScaleAbs(yuan_y_64)
cv2.imshow('yuan_y',yuan_y_abs)
cv2.waitKey(0)
# x、y同时
yuan_xy = cv2.Sobel(yuan,-1,dx=1,dy=1)
cv2.imshow('yuan_xy',yuan_xy)
cv2.waitKey(0)
# x方向、y方向权重相加
yuan_xy_add = cv2.addWeighted(yuan_x_abs,1,yuan_y_abs,1,0)
cv2.imshow('yuan_xy_add',yuan_xy_add)
cv2.waitKey(0)

 

 

(2)、Scharr算子边缘检测

Scharr 算子是 Soble 算子在 ksize=3 时的优化,与 Soble 的速度相同,且精度更高。Scharr 算子与 Sobel 算子的不同点是在平滑部分,其中心元素占的权重更重,相当于使用较小标准差的高斯函数,也就是更瘦高的模板。


 

 

用法说明:

cv2.Scharr(src, ddepth, dx, dy, scale=None, delta=None, borderType=None)

  • src: 输入图像,通常是单通道灰度图像。

  • ddepth: 输出图像的深度(数据类型),例如 cv2.CV_8Ucv2.CV_16S 等。

  • dx: x 方向上的导数阶数(0 或 1)。

  • dy: y 方向上的导数阶数(0 或 1)。

  • scale: 可选的比例因子,应用于计算结果。

  • delta: 可选的增量值,添加到结果中。

  • borderType: 边界填充类型,默认值为 cv2.BORDER_DEFAULT

代码示例:
import cv2
cat = cv2.imread('./images/cat.jpg',0)
cat_x_64 = cv2.Scharr(cat,cv2.CV_64F,dx=1,dy=0)
cat_x_abs = cv2.convertScaleAbs(cat_x_64)
cat_y_64 = cv2.Scharr(cat,cv2.CV_64F,dx=0,dy=1)
cat_y_abs = cv2.convertScaleAbs(cat_y_64)
cat_xy = cv2.addWeighted(cat_x_abs,1,cat_y_abs,1,0)
cv2.imshow('cat_Scharr',cat_xy)
cv2.waitKey(0)

 

 

(3)、Laplacian算子边缘检测

不再以x和y的方向计算,而是以圆方向计算变化率。因此不需要Gx+Gy。

 

用法说明:

 cv2.Laplacian(src, ddepth, ksize=None, scale=None, delta=None, borderType=None)

  • src: 输入图像,通常是单通道灰度图像。

  • ddepth: 输出图像的深度(数据类型),例如 cv2.CV_8Ucv2.CV_16S 等。

  • ksize: 拉普拉斯核的大小,必须是正奇数(默认值为 1,表示使用最简单的 3x3 核)。

  • scale: 可选的比例因子,应用于计算结果。

  • delta: 可选的增量值,添加到结果中。

  • borderType: 边界填充类型,默认值为 cv2.BORDER_DEFAULT

 代码示例:
import cv2
cat = cv2.imread('./images/cat.jpg',0)
cat_lap = cv2.Laplacian(cat,cv2.CV_64F)
cat_lap_abs = cv2.convertScaleAbs(cat_lap)
cv2.imshow('cat_laplacian',cat_lap_abs)
cv2.waitKey(0)

 

(4)、 Canny边缘检测(常用)

canny边缘检测分为4个部分:图像降噪 、梯度计算 、非极大值抑制 、双阈值边界跟踪

  • 图像降噪:图像去噪是进行边缘检测的第一步,通过去噪可以去除图像中的一些噪点,从而使边缘检测时免受噪点干扰。高斯滤波。
  • 梯度计算:要进行边缘检测,就需要得到图像梯度信息,根据图像的梯度幅值和梯度方向来确定边缘,一般均采用sobel算子对图像进行梯度幅值与梯度方向计算。 
  • 非极大值抑制NMS:在梯度图像中寻找梯度方向上的最大值作为边缘,不是梯度方向上的最大值则抑制为0。因为梯度方向是灰度变化最大的方向。比较梯度图像中每一点的灰度值与梯度方向上至少两个梯度图像像素点灰度值的大小,根据上述大小关系来确定是否保留该点的灰度值。
  • 双阈值边界追踪:双阈值处理就是根据实际情况需要设置一个灰度高阈值和一个灰度低阈值对NMS后的图像进行过滤,使得得到的边缘尽可能是真实的边缘。

用法说明:

cv2.Canny(image, threshold1, threshold2, apertureSize=None, L2gradient=None) 

  • image: 输入图像,通常是单通道灰度图像。

  • threshold1: 低阈值,用于边缘连接。

  • threshold2: 高阈值,用于强边缘检测。

  • apertureSize: Sobel 算子的核大小,默认值为 3。

  • L2gradient: 是否使用 L2 范数计算梯度幅值。如果为 True,则使用更精确的 L2 范数;如果为 False,则使用 L1 范数(默认值为 False)。

代码示例:

import cv2
cat = cv2.imread('./images/cat.jpg',0)
cv2.imshow('cat',cat)
cv2.waitKey(0)
cat_canny = cv2.Canny(cat,100,200)
cv2.imshow('cat_canny',cat_canny)
cv2.waitKey(0)

24、图像轮廓检测

使用轮廓检测可以获得物体的边界,方便在图像中对他们进行定位。通常在一些有趣的应用中轮廓检测是第一处理环节。比如图像前景提取,简单的图像分割,检测以及识别等。

 

(1)、轮廓检测、绘制轮廓

## 查找轮廓
用法说明:

cv2.findContours(image, mode, method, contours=None, hierarchy=None, offset=None)

  • image: 输入的二值图像(通常是经过边缘检测或阈值处理后的图像)。注意:findContours() 会修改输入图像,因此建议使用副本。

  • mode: 轮廓检索模式,决定如何提取轮廓。常用的模式包括:

    • cv2.RETR_EXTERNAL: 只检测外部轮廓。

    • cv2.RETR_LIST: 检测所有轮廓,但不建立轮廓之间的层次关系。

    • cv2.RETR_TREE: 检测所有轮廓,并建立完整的层次结构。

  • method: 轮廓近似方法,决定如何存储轮廓点。常用的方法包括:

    • cv2.CHAIN_APPROX_NONE: 存储所有轮廓点。

    • cv2.CHAIN_APPROX_SIMPLE: 压缩水平、垂直和对角方向的轮廓点,只保留端点。

  • contours: 输出的轮廓列表,每个轮廓是一个点集。

  • hierarchy: 输出的轮廓层次结构,描述轮廓之间的关系。

  • offset: 可选的偏移量,应用于所有轮廓点。

返回值:
  • contours: 检测到的轮廓列表。每个轮廓是一个点集(通常是一个 NumPy 数组)。

  • hierarchy: 轮廓的层次结构。它是一个 NumPy 数组,形状为 (N, 4),其中 N 是轮廓的数量。每个轮廓的层次信息由 4 个值表示:

    • [next, previous, first_child, parent]

      • next: 同一层级的下一个轮廓索引。

      • previous: 同一层级的上一个轮廓索引。

      • first_child: 第一个子轮廓索引。

      • parent: 父轮廓索引。

## 绘制轮廓
用法说明:

cv2.drawContours(image, contours, contourIdx, color, thickness=None, lineType=None, hierarchy=None, maxLevel=None, offset=None)

  • image: 目标图像,轮廓将绘制在这张图像上。

  • contours: 轮廓列表,通常是通过 findContours() 函数得到的。

  • contourIdx: 要绘制的轮廓索引。如果为 -1,则绘制所有轮廓。

  • color: 轮廓的颜色,格式为 (B, G, R)

  • thickness: 轮廓线的宽度。如果为 -1,则填充轮廓内部。

  • lineType: 线条类型,默认为 cv2.LINE_8(8-connected line)。

  • hierarchy: 轮廓的层次结构(可选),通常由 findContours() 返回。

  • maxLevel: 绘制轮廓的最大层级(可选)。如果为 0,则只绘制指定的轮廓;如果为 1,则绘制指定轮廓及其嵌套轮廓。

  • offset: 可选的偏移量,应用于所有轮廓点。

代码示例:
img = cv2.imread('./images/img_2.png')
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
cv2.imshow('img_gray',img_gray)
cv2.waitKey(0)
_,img_binary = cv2.threshold(img_gray,100,255,cv2.THRESH_BINARY)
cv2.imshow('img_bin',img_binary)
cv2.waitKey(0)
_,contours,hierarchy = cv2.findContours(img_binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
print(hierarchy)
print(len(contours))
img_copy = img.copy()
img_copy = cv2.drawContours(image=img_copy,contours=contours,contourIdx=-1,color=(255,255,0),thickness=2)
cv2.imshow('Contous',img_copy)
cv2.waitKey(0)

 

(2)、轮廓特征

 获取轮廓后,通常基于轮廓的特征进行筛选、识别和处理。例如,基于轮廓的周长和面积对轮廓进行筛选,然后绘制筛选的目标轮廓或其最小外接矩形。

  • 轮廓面积:cv2.contourArea()
  • 轮廓周长: cv2.arcLength()
# 获取索引为0的轮廓的面积
area_0 = cv2.contourArea(contours[0])
print(area_0)
# 获取索引为0的轮廓的周长
Length = cv2.arcLength(contours[0],closed=True)
print(Length)
# 筛选面积大于10000像素的轮廓并绘制
a_list = []
for i in contours:if cv2.contourArea(i)>10000:a_list.append(i)
img_copy1 = img.copy()
img_copy1 = cv2.drawContours(image=img_copy1,contours=a_list,contourIdx=-1,color=(0,255,255),thickness=2)
cv2.imshow('Contours_10000',img_copy1)
cv2.waitKey(0)

 持续更新中。。。


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

相关文章

人工智能知识分享第八天-机器学习_泰坦尼克生存预估线性回归和决策树回归对比案例

泰坦尼克生存预估案例 import pandas as pd from sklearn.model_selection import train_test_split from sklearn.tree import DecisionTreeClassifier from sklearn.metrics import classification_report import matplotlib.pyplot as plt from sklearn.tree import plot_t…

每天40分玩转Django:Django Celery

Django Celery 一、知识要点概览表 模块知识点掌握程度要求Celery基础配置、任务定义、任务执行深入理解异步任务任务状态、结果存储、错误处理熟练应用周期任务定时任务、Crontab、任务调度熟练应用监控管理Flower、任务监控、性能优化理解应用 二、基础配置实现 1. 安装和…

深入Android架构(从线程到AIDL)_09 认识Android的主线程

目录 UI线程的诞生 練習: 绑定(Bind)远程的Service UI线程的诞生 当我们启动某一支AP时, Android就会诞生新进程(Process),并且将该AP程序加载这新诞生的进程里。每个进程在其诞生时刻,都会诞生一个主线程,又称为UI…

芯片引脚缺陷检测数据集VOC+YOLO格式203张2类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):203 标注数量(xml文件个数):203 标注数量(txt文件个数):203 标注…

STM32 软件I2C读写

单片机学习! 目录 前言 一、软件I2C读写代码框架 二、I2C初始化 三、六个时序基本单元 3.1 引脚操作的封装和改名 3.2 起始条件执行逻辑 3.3 终止条件执行逻辑 3.4 发送一个字节 3.5 接收一个字节 3.5 发送应答&接收应答 3.5.1 发送应答 3.5.2 接…

Tesseract5.4.0自定义LSTM训练

准备jTessBoxEditor,然后配置环境变量。 1、将图片转换成tif格式的,这里需要用画图工具另存为; 2、生成box文件 执行命令: tesseract agv.normal.exp1.tif agv.normal.exp1 -l eng --psm 6 batch.nochop makebox 关于box文件…

内部类 --- (寄生的哲学)

内部类总共有 4 种(静态内部类、非静态内部类、局部内部类、匿名内部类) 作用: 一:内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类。 二:内部类可以…

数据结构:循环单链表

循环单链表(Circular Singly Linked List) 循环单链表是单链表的一种变体,其特点是链表的尾节点指向头节点,形成一个闭环。这种结构允许在链表中进行无缝的遍历,并且可以从任何节点开始遍历整个链表。循环单链表通常用…