opencv——(图像梯度处理、图像边缘化检测、图像轮廓查找和绘制、透视变换、举例轮廓的外接边界框)

ops/2024/12/29 5:21:51/

一、图像梯度处理

1 图像边缘提取

cv2.filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]])

功能:用于对图像进行卷积操作。卷积是图像处理中的一个基本操作,它通过一个称为卷积核(或滤波器)的小矩阵在图像上滑动,并对每个位置进行加权求和,从而得到新的图像。

参数:

src:输入图像,可以是灰度图像或彩色图像。

ddepth:输出图像的所需深度。对于输入图像和输出图像具有相同深度的情况,该值通常设置为 -1。否则,你可以选择一个特定的深度,如 cv2.CV_8U、cv2.CV_16U、cv2.CV_32F 等。

kernel:卷积核,一个二维数组或矩阵。卷积核的大小通常是奇数,如 3x3、5x5 等。卷积核中的每个元素都是一个权重,用于在卷积过程中与图像像素相乘。

dst:输出图像(可选)。

anchor:卷积核的锚点(可选)。

delta:一个可选的附加值,它将被加到卷积结果上。这可以用于调整结果的亮度或对比度。

borderType:边界填充。

 

import cv2
import numpy as np
img = cv2.imread('../1iamge/shudu.png')
#进行水平梯度处理
kernel_x = np.array([[-1,-2,-1],[0,0,0],[1,2,1]])
img_filterx = cv2.filter2D(img,-1,kernel_x)
cv2.imshow("img_filterx",img_filterx)#进行垂直梯度处理
kernel_y = np.array([[-1,0,1],[-2,0,2],[-1,0,1]])
img_filtery = cv2.filter2D(img,-1,kernel_y)
cv2.imshow("img_filtey",img_filtery)
cv2.imshow('img',img)
cv2.waitKey(0)

 

2 Sobel算子

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

功能:用于计算图像梯度(gradient)的函数

参数:

src: 输入图像,它应该是灰度图像。

ddepth: 输出图像的所需深度(数据类型)。通常,你可以使用 -1 来表示与输入图像相同的深度,或者使用如 cv2.CV_64F 等来指定特定的深度。由于梯度计算可能产生负值,因此建议使用能够包含负数的数据类型。

dx: x 方向上的导数阶数。如果你想要计算 x 方向上的梯度,设置这个参数为 1;如果你不关心 x 方向上的梯度,设置这个参数为 0。

dy: y 方向上的导数阶数。如果你想要计算 y 方向上的梯度,设置这个参数为 1;如果你不关心 y 方向上的梯度,设置这个参数为 0。通常,你不会同时设置 dx 和 dy 都为 0。

ksize: Sobel 核的大小。它必须是 1、3、5、7 或 9 之一。这个参数决定了用于计算梯度的滤波器的大小。大小为 1 时表示使用最小的滤波器,但通常你会使用更大的滤波器来平滑梯度计算。

scale: 可选参数,表示计算梯度时的缩放因子。默认值为 1,表示不进行缩放。你可以通过调整这个参数来放大或缩小梯度的结果。

delta: 可选参数,表示在将结果存储到目标图像之前要添加到结果中的可选增量值。默认值为 0,表示不添加增量。

borderType: 像素外推方法,例如 cv2.BORDER_DEFAULT、cv2.BORDER_REFLECT 等。这个参数决定了在图像边界处如何处理像素外推。

 

import cv2
import numpy as np
img = cv2.imread('../1iamge/shudu.png')
#进行水平梯度处理
img_Sobelx = cv2.Sobel(img,-1,0,1,2)
cv2.imshow("img_Sobelx",img_Sobelx)
#进行垂直梯度处理
img_Sobely = cv2.Sobel(img,-1,1,0,3)
cv2.imshow("img_Sobely",img_Sobely)
cv2.imshow('img',img)
cv2.waitKey(0)

3 Laplacian算子

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

功能:用于计算图像的拉普拉斯算子(Laplacian)

参数:

src: 输入图像,它应该是灰度图像。

ddepth: 输出图像的所需深度。这个参数决定了输出图像的深度(数据类型)。通常,你可以使用 -1 来表示与输入图像相同的深度,或者使用 cv2.CV_64F 等来指定特定的深度。由于拉普拉斯算子可能产生负值,因此通常建议使用能够包含负数的数据类型,如 cv2.CV_64F。

ksize: 算子的大小。它必须是 1、3、5 或 7 之一。这个参数决定了用于计算拉普拉斯算子的滤波器的大小。大小为 1 时表示使用 4 邻域拉普拉斯算子,其他大小则使用更大的滤波器。

scale: 可选参数,表示计算拉普拉斯算子时的缩放因子。默认值为 1,表示不进行缩放。你可以通过调整这个参数来放大或缩小拉普拉斯算子的结果。

delta: 可选参数,表示在将结果存储到目标图像之前要添加到结果中的可选增量值。默认值为 0,表示不添加增量。

borderType: 像素外推方法,例如 cv2.BORDER_DEFAULT、cv2.BORDER_REFLECT 等。这个参数决定了在图像边界处如何处理像素外推。当 ksize 大于 1 时,这个参数才有意义。

 

import cv2
img = cv2.imread('../1iamge/shudu.png')
img_laplacian = cv2.Laplacian(img,-1,ksize = 5)
cv2.imshow("img_laplacian",img_laplacian)
cv2.imshow('img',img)
cv2.waitKey(0)

二、图像边缘化检测

步骤:

  1. 1、灰度化
  2. 2、二值化
  3. 3、滤波
  4. 4、边缘检测

cv2.Canny(image, threshold1, threshold2, edges, apertureSize, L2gradient)

功能:用于边缘检测的函数

参数:

‌image‌: 输入图像,它应该是一个灰度图像(单通道)。

‌threshold1‌: 第一个阈值,用于边缘检测的滞后过程。这个值较低,用于确定边缘的初始点。

‌threshold2‌: 第二个阈值,用于边缘检测的滞后过程。这个值较高,用于确定边缘的最终点。如果某个像素点的梯度值高于这个阈值,它被认为是边缘;如果低于这个值但高于threshold1,并且与高于threshold2的像素点相连,它也被认为是边缘。

‌edges‌: 输出图像,与输入图像大小相同,但通常是二值图像(即只包含边缘和非边缘的像素)。

‌apertureSize‌(可选,默认为3): Sobel算子的大小,它决定了梯度计算的邻域大小。它必须是1、3、5或7之一。

‌L2gradient‌(可选,默认为False): 一个布尔值,指示是否使用更精确的L2范数进行梯度计算。如果为True,则使用L2范数(即欧几里得距离);如果为False,则使用L1范数(即曼哈顿距离)。L2范数通常更精确,但计算成本也更高。

 

import cv2
img = cv2.imread('../1iamge/picture.png')
#灰度化
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#二值化
_,img_binary = cv2.threshold(img_gray,127,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
#高斯滤波
img_blur = cv2.GaussianBlur(img_binary,(3,3),150)
#边缘检测
img_canny= cv2.Canny(img_blur,10,70)
cv2.imshow('img',img)
cv2.imshow("img_canny",img_canny)
cv2.waitKey(0)

三、图像轮廓查找和绘制

步骤:

  1. 灰度
  2. 二值化
  3. 寻找轮廓
  4. 绘制轮廓

cv2.findContours(image, mode, method, contour, hierarchy, offset.)

功能:用于检测图像轮廓的函数

参数:

‌image‌ (必需): 输入图像,通常是一个二值图像(即只包含黑白两种颜色的图像),其中白色部分代表要检测的对象,黑色部分代表背景。也可以是非二值图像,但通常需要先进行某种形式的预处理,如阈值分割或边缘检测。

‌mode‌ (可选,某些版本中必需): 轮廓检索模式。它决定了函数如何检测轮廓。常见的模式有:

cv2.RETR_EXTERNAL:(external)只检索最外层轮廓。

cv2.RETR_LIST:检索所有轮廓,但不创建任何父子关系。

cv2.RETR_CCOMP:(ccomp)检索所有轮廓,并将它们组织为两层结构,其中顶层是连通域的外边界,底层是孔的内边界。

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

‌method‌ (可选,某些版本中必需): 轮廓近似方法。它决定了轮廓的近似程度。常见的方法有:

cv2.CHAIN_APPROX_NONE:存储所有的轮廓点,不进行任何近似。

cv2.CHAIN_APPROX_SIMPLE:压缩水平、垂直和对角线段,只保留它们的终点。

cv2.CHAIN_APPROX_TC89_L1、cv2.CHAIN_APPROX_TC89_KCOS:应用 Teh-Chin 链式近似算法的一种变体。

‌contours‌ (某些版本中作为返回值): 在某些 OpenCV 版本中,这个参数是用来存储检测到的轮廓的。它是一个 Python 列表,其中每个元素都是一个轮廓,轮廓是由点组成的 NumPy 数组。

‌hierarchy‌ (某些版本中作为返回值): 轮廓的层次结构信息。这是一个 NumPy 数组,包含了关于轮廓之间关系的信息(例如,哪个轮廓是另一个轮廓的父轮廓或子轮廓)。

‌offset‌ (可选,默认为 (0, 0)): 轮廓点的偏移量。这个参数允许你在原始图像坐标系的基础上对轮廓点进行平移。

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

功能:用于在图像上绘制轮廓的函数

参数:

image‌ (必需): 这是要在其上绘制轮廓的输入图像。它应该是一个三通道图像(例如,彩色图像)或单通道图像(例如,灰度图像),但通常是三通道图像,以便可以使用不同的颜色来绘制轮廓。

‌contours‌ (必需): 这是一个 Python 列表,包含要绘制的所有轮廓。每个轮廓都是一个点集,通常是由 cv2.findContours() 函数返回的 NumPy 数组。

‌contourIdx‌ (可选,默认为 -1): 指定要绘制的轮廓的索引。如果为 -1,则绘制所有轮廓。否则,只绘制指定索引处的轮廓。

‌color‌ (可选,默认为 (0, 255, 0)): 轮廓的颜色。它是一个三元组,表示 BGR(蓝、绿、红)颜色空间中的颜色。例如,(0, 255, 0) 表示绿色。

‌thickness‌ (可选,默认为 1): 轮廓的厚度。如果为正数,则轮廓将被绘制为指定厚度的线条。如果为负数(例如 -1),则轮廓内部将被填充。

‌lineType‌ (可选,默认为 cv2.LINE_8): 线条的类型。它决定了轮廓线条的平滑度。cv2.LINE_8 表示 8-连通线,cv2.LINE_4 表示 4-连通线,cv2.LINE_AA 表示抗锯齿线。

‌hierarchy‌ (可选,默认为 None): 轮廓的层次结构信息。这是一个 NumPy 数组,通常由 cv2.findContours() 函数返回。它包含了关于轮廓之间关系的信息,例如哪个轮廓是另一个轮廓的父轮廓或子轮廓。在绘制所有轮廓时,这个参数通常不需要。

‌maxLevel‌ (可选,默认为 INT_MAX): 用于控制绘制轮廓的层次深度。当 contourIdx 参数为 -1 时,这个参数才有效。它决定了要绘制的轮廓的最大层次深度。

‌offset‌ (可选,默认为 (0, 0)): 轮廓点的偏移量。这个参数允许你在原始图像坐标系的基础上对轮廓点进行平移。

 

 

import cv2
img = cv2.imread('../1iamge/outline.png')
img = cv2.resize(img,(0,0),fx=0.5,fy=0.5)
#灰度化
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#二值化
_,img_binary = cv2.threshold(img_gray,127,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
#寻找轮廓
contours,_ = cv2.findContours(img_binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
#绘制轮廓
img_copy = img.copy()
img_draw = cv2.drawContours(img_copy,contours,-1,(255,255,0),3)cv2.imshow("img",img)
cv2.imshow("img_canny",img_draw)
cv2.waitKey(0)

三、透视变换

import cv2
import numpy as np# 1、输入数据
img = cv2.imread("../1iamge/4.png")
img_copy = img.copy()# 2、高斯滤波
img_blur = cv2.GaussianBlur(img, (3, 3), 1)# 3、灰度化
img_gray = cv2.cvtColor(img_blur, cv2.COLOR_BGR2GRAY)# 4、二值化 —— 阈值的选择 和 二值化类型的选择都对寻找轮廓有影响
_, img_binary = cv2.threshold(img_gray,127,255,cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)# 5、寻找轮廓
contours, _ = cv2.findContours(img_binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)cnt = sorted(contours, key=cv2.contourArea, reverse=True)[0]arc_len = cv2.arcLength(cnt,  # 轮廓True  # 是否闭合)
approx = cv2.approxPolyDP(cnt,   # 轮廓float(0.04)*arc_len,   # 这是从原始轮廓到近似多边形的最大距离,它决定了逼近的精度。True   # 是否闭合)  # 返回逼近的多边形的 坐标点集if len(approx) == 4:# 绘制轮廓img_draw = cv2.drawContours(img_copy,  # 要绘制轮廓的图像[approx],  # 轮廓的顶点坐标集 列表-1,  # 轮廓列表的索引值,-1表示绘制所有轮廓(0, 0, 255),  # 颜色3  # 轮廓线条粗细)# 获取透视矩阵# 找到原图中的四个点 —— 可以手动设置,也可以在后面学完轮廓之后筛选自动获取points1 = np.float32(approx).reshape(-1, 2)# 设置原图中的四个点 在 目标图中 的四个位置points2 = np.float32([[min(points1[:, 0]), min(points1[:, 1])],  # 左上角[min(points1[:, 0]), max(points1[:, 1])],  # 左下角[max(points1[:, 0]), max(points1[:, 1])],  # 右下角[max(points1[:, 0]), min(points1[:, 1])]   # 右上角])# 获取矩阵M = cv2.getPerspectiveTransform(points1, points2)# 进行透视变换img_Perspective = cv2.warpPerspective(img, M, (img.shape[1], img.shape[0]))cv2.imshow('image', img)cv2.imshow('image_draw', img_draw)cv2.imshow('img_Perspective', img_Perspective)cv2.waitKey(0)

 

举例轮廓的外接边界框

import cv2
import numpy as npimg = cv2.imread("../1iamge/outline.png")
img = cv2.resize(img,(0,0),fx=0.5,fy=0.5)
# 灰度化
img_gray = cv2.cvtColor(img, cv2.COLOR_BGRA2GRAY)
# 二值化
_, img_binary = cv2.threshold(img_gray,127,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
# 寻找轮廓
contours, _ = cv2.findContours(img_binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 绘制轮廓
img_draw = img.copy()
cv2.drawContours(img_draw, contours, -1, (0, 0, 255), 2)# 给所有轮廓都绘制 外接
for i in contours:# 第一种:调用外接矩形函数,获取当前轮廓点的左上角的坐标(x, y) 宽w 高hx, y, w, h = cv2.boundingRect(i)# 画矩形cv2.rectangle(img_draw, [x, y], [x+w, y+h], (0, 255, 0), 2)# 第二种:调用最小面积外接矩形函数,获取包含三个元素的元组(中心点坐标、长宽、旋转角度)# ((center_x, center_y), (width, height), angle)ret = cv2.minAreaRect(i)# 调用cv2.boxPoints(ret)可以获取旋转矩阵的四个顶点box = np.int32(cv2.boxPoints(ret))# 绘制轮廓cv2.drawContours(img_draw, [box], -1, (255, 255, 0), 3)# 第三种:调用最小外接圆函数,获取圆心坐标 和 半径(x, y), radius = cv2.minEnclosingCircle(i)(x, y, radius) = np.int32((x, y, radius))# 画圆cv2.circle(img_draw, (x, y), radius, (255, 0, 255), 3)cv2.imshow('image', img)
cv2.imshow('image_draw', img_draw)
cv2.waitKey(0)

 


http://www.ppmy.cn/ops/143355.html

相关文章

数据版本管理和迁移工具Flyway用法最简说明

简介 数据库迁移及版本控制工具, 用于维护不同环境下数据库的一致性 使用 引入依赖 implementation(“org.flywaydb:flyway-core:7.1.1”) 配置 spring:flyway:enabled: truelocations: classpath:sqlbaseline-on-migrate: trueclean-disabled: trueenabled: true # 开启Fl…

2024最新qrcode.min.js生成二维码Demo

找了一堆代码一堆GPT&#xff0c;终于给写对了&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><…

31.攻防世界php_rce

进入场景 不是&#xff0c;这是个啥啊 index.php?sindex/think\app/invokefunction&functioncall_user_func_array&vars[0]system&vars[1][]whoami index.php?sindex/think\app/invokefunction&functioncall_user_func_array&vars[0]system&vars[1]…

什么是大语言模型(LLM)

1. 什么是大语言模型&#xff08;LLM&#xff09;&#xff1f; LLM 是一种基础模型&#xff08;Foundation Model&#xff09;的实例。 基础模型的特点&#xff1a; 使用大量未标注的自监督数据进行预训练。通过学习数据中的模式&#xff0c;生成具有普适性和可适应性的输出…

风力与太阳能发电波动预测与模型研究(2024认证杯D题)

文章目录 数据形式模型假设数据清洗 &#xff08;缺失值补齐以及异常值处理&#xff09;1.1 问题一&#xff08;风电场功率预测&#xff09;图表一&#xff08;功率随时间的变化&#xff09;图表二&#xff08;波动强度随时间的变化&#xff09;预测展示&#xff08;只展示部分…

Java+FreeSWITCH 开源呼叫系统详解

JavaFreeSWITCH 开源呼叫系统详解 原作者&#xff1a;开源呼叫中心FreeIPCC&#xff0c;其Github&#xff1a;https://github.com/lihaiya/freeipcc 引言 随着通信技术的不断发展&#xff0c;企业对于高效、灵活且成本效益高的呼叫解决方案的需求日益增长。JavaFreeSWITCH 开…

Dcoker Redis哨兵模式集群介绍与搭建 故障转移 分布式 Java客户端连接

介绍 Redis 哨兵模式&#xff08;Sentinel&#xff09;是 Redis 集群的高可用解决方案&#xff0c;它主要用于监控 Redis 主从复制架构中的主节点和从节点的状态&#xff0c;并提供故障转移和通知功能。通过 Redis 哨兵模式&#xff0c;可以保证 Redis 服务的高可用性和自动故…

jmeter中的prev对象

在jmeter中通过beanshell、JSR223的各种处理器编写脚本时&#xff0c;都会看到页面上有这样的说明 这些ctx、vars、props、OUT、sampler、prev等等都是可以直接在脚本中使用的对象&#xff0c;由jmeter抛出 今天主要讲一下prev的使用 SampleResult prev jmctx.getPreviousRe…