计算机视觉-OpenCV图像处理

1.Matplotlib数据可视化(绘制图像直方图、可视化矩阵)

# Matplotlib 数据可视化(绘制图像直方图、可视化矩阵)
# 本节主要讲解如何使用 Matplotlib 绘制图像直方图和可视化矩阵。
# 1. 绘制图像直方图
# 2. 可视化矩阵

# 1. 绘制图像直方图
import cv2
import matplotlib.pyplot as plt
import numpy as np

# 读取图像并转换为灰度图,读取后的 image 是一个二维数组,每个元素代表一个像素的灰度值。
image = cv2.imread('cat.jpg', cv2.IMREAD_GRAYSCALE)  #将图像转换为灰度图(像素值范围 0 到 255)

# 绘制图像和直方图
plt.figure(figsize=(12, 6))

plt.subplot(1, 2, 1) #创建一个1行2列的子图,当前激活第1个子图
plt.imshow(image, cmap='gray')  #将图像以矩阵形式可视化。cmap='gray' 指定使用灰度颜色。
plt.title('Grayscale Image')
plt.axis('off') #关闭坐标轴

plt.subplot(1, 2, 2) #创建一个1行2列的子图,当前激活第2个子图
# plt.hist 函数要求输入是一维数组,所以需要使用 ravel() 方法将二维或三维的图像数组转换为一维数组
plt.hist(image.ravel(), bins=256, range=[0, 256], color='r', alpha=0.5)  #绘制直方图
plt.title('Histogram')  #设置标题
plt.xlabel('Pixel Value')  #设置x轴标签
plt.ylabel('Frequency')  #设置y轴标签

plt.tight_layout()  #自动调整子图参数,使之填充整个图像区域
plt.show()  #显示图像和直方图

# 2. 可视化矩阵
import numpy as np
import matplotlib.pyplot as plt

# 创建一个包含3x3个元素的随机矩阵
arr = np.random.rand(3, 3)

# 可视化矩阵
# imshow 是 matplotlib.pyplot 中的一个函数,用于将数组(矩阵)以图像的形式显示出来。
# 在这个例子中,它将 arr 矩阵中的每个元素映射为图像中的一个像素,像素的颜色由元素的值决定。
# cmap='viridis':cmap 参数指定了颜色映射(colormap),即如何将数组中的数值映射为不同的颜色。
# 'viridis' 是 matplotlib 提供的一种颜色映射方案,它是一种连续的、感知均匀的颜色映射,从蓝色到黄色渐变,常用于可视化连续的数值数据。
plt.imshow(arr, cmap='viridis')  #将矩阵以矩阵形式可视化。cmap='viridis' 指定使用 viridis 颜色。
# 在图像旁边添加一个颜色条。颜色条用于显示颜色与数值之间的对应关系,通过颜色条可以直观地了解图像中不同颜色所代表的数值大小。
plt.colorbar()  #添加颜色条
plt.title('Matrix Visualization')  #设置标题
plt.show()  #显示图像


2.OpenCV图像处理

  • 滤波操作(去除噪声)
  • 边缘检测(提取图像中的边缘)
  • 特征点检测(检测图像中的关键点)

练习任务:写一个简单的OpenCV脚本,提取两个图像的ORB特征并进行匹配。

滤波操作

滤波用于平滑图像、去除噪声。常见的滤波器有 均值滤波、高斯滤波和中值滤波

# OpenCV 提供了丰富的图像处理功能,我们将重点介绍以下操作
# 滤波操作(去除噪声)
# 边缘检测(提取图像中的边缘)
# 特征点检测(检测图像中的关键点)

# 滤波用于平滑图像、去除噪声。常见的滤波器有 均值滤波、高斯滤波和中值滤波。
# 均值滤波:将图像中的每个像素替换为其周围像素的平均值。
# 高斯滤波:将图像中的每个像素替换为其周围像素的加权平均值。
# 中值滤波:将图像中的每个像素替换为其周围像素的中值。

import cv2
import matplotlib.pyplot as plt
import numpy as np

# 读取图像
image = cv2.imread('cat.jpg', cv2.IMREAD_GRAYSCALE)

# 均值滤波
# cv2.blur() 函数用于对图像进行均值滤波。第一个参数是输入图像,第二个参数是滤波核的大小。
# 滤波核的大小决定了滤波的效果,核的大小越大,滤波效果越明显。
# 例如,当核的大小为 (3, 3) 时,表示 3x3 的滤波核,对图像进行均值滤波。
blur_image = cv2.blur(image, (3, 3))

# 高斯滤波
# cv2.GaussianBlur() 函数用于对图像进行高斯滤波。第一个参数是输入图像,第二个参数是高斯核的大小,第三个参数是高斯核的标准差。
# 高斯核的大小和标准差决定了滤波的效果,高斯核的大小越大,滤波效果越明显。
# 例如,当高斯核的大小为 (3, 3),标准差为 0 时,表示 3x3 的高斯核,对图像进行高斯滤波。
gaussian_image = cv2.GaussianBlur(image, (3, 3), 0)

# 中值滤波
# cv2.medianBlur() 函数用于对图像进行中值滤波。第一个参数是输入图像,第二个参数是滤波核的大小。
# 中值滤波适用于去除椒盐噪声,即图像中的黑白点噪声。
# 例如,当核的大小为 3 时,表示 3x3 的滤波核,对图像进行中值滤波。
median_image = cv2.medianBlur(image, 3)

# 显示图像和滤波结果
plt.figure(figsize=(12, 6))
plt.subplot(1, 3, 1), plt.imshow(blur_image, cmap='gray'), plt.title('Mean Blur')
plt.subplot(1, 3, 2), plt.imshow(gaussian_image, cmap='gray'), plt.title('Gaussian Blur')
plt.subplot(1, 3, 3), plt.imshow(median_image, cmap='gray'), plt.title('Median Blur')
plt.show()

边缘检测

边缘检测用于提取图像中的轮廓,Canny 边缘检测是最常用的方法。

# 边缘检测用于检测图像中的边缘。常见的边缘检测算法有 Sobel算子、Scharr算子、Laplacian算子和Canny算子。
# Canny算子:通过多步操作检测图像中的边缘。

# 读取图像
image = cv2.imread('cat.jpg', cv2.IMREAD_GRAYSCALE)

# Canny 边缘检测
# cv2.Canny() 函数用于对图像进行 Canny 边缘检测。第一个参数是输入图像,第二个参数是阈值1,第三个参数是阈值2。
# 阈值1 和阈值2 用于控制边缘检测的灵敏度,边缘检测结果取决于这两个阈值的选择。
edges = cv2.Canny(image, 100, 200)

# 显示原图和边缘检测结果
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)

# plt.subplot() 函数用于在当前图形窗口中创建一个子图布局。它接受三个整数参数,分别表示子图布局的行数、列数和当前子图的编号。
# (1, 2, 1) 表示将图形窗口划分为 1 行 2 列的子图布局,当前要操作的是第 1 个子图(从左到右、从上到下编号)。
plt.imshow(image, cmap='gray')
# plt.imshow() 用于显示图像。image 是要显示的图像数组,通常是一个 numpy 数组。
# cmap='gray' 指定使用灰度颜色映射来显示图像,适用于单通道的灰度图像。
plt.title('Original Image')
# 为当前子图设置标题,标题内容为 'Original Image',表明该子图显示的是原始图像。
plt.axis('off')
# 隐藏当前子图的坐标轴,使图像显示更加简洁。

plt.subplot(1, 2, 2), plt.imshow(edges, cmap='gray'), plt.title('Canny Edges')
plt.axis('off')
plt.show()

特征点检测

SIFT

https://medium.com/@deepanshut041/introduction-to-sift-scale-invariant-feature-transform-65d7f3a72d40

# SIFT特征点检测

# 读取图像
image = cv2.imread('cat.jpg', cv2.IMREAD_GRAYSCALE)

# 初始化 SIFT 特征检测器
sift = cv2.SIFT_create()

# 检测图像中的关键点和描述符
# sift.detectAndCompute() 是 SIFT 检测器对象的一个方法,用于同时检测图像中的关键点并计算这些关键点的描述子。

# 该方法接受两个参数:
# 第一个参数是输入的图像(这里是之前读取的灰度图像 image),
# 第二个参数是一个掩码图像,用于指定在哪些区域进行关键点检测,None 表示对整个图像进行检测。

# 该方法返回两个值:
# keypoints 是一个包含检测到的关键点信息的列表,每个关键点是一个 cv2.KeyPoint 对象,包含关键点的位置、尺度、方向等信息;
# descriptors 是一个 numpy 数组,包含每个关键点对应的描述子,描述子是一个用于表示关键点特征的向量,通常用于后续的特征匹配。
keypoints, descriptors = sift.detectAndCompute(image, None)

# 绘制关键点
# cv2.drawKeypoints() 是 OpenCV 中用于在图像上绘制关键点的函数。
# 它接受四个参数:
# 第一个参数是输入的图像(这里是原始的灰度图像 image),
# 第二个参数是关键点列表(keypoints),
# 第三个参数是输出图像,如果为 None 则表示在输入图像上直接绘制关键点;
# 第四个参数 color 用于指定绘制关键点的颜色,这里 (0, 255, 0) 表示绿色。
# 该函数返回一个绘制了关键点的图像 sift_image。
image_with_keypoints = cv2.drawKeypoints(image, keypoints, None, color=(0, 255, 0))

# 显示原图和绘制了关键点的图像
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1), plt.imshow(image, cmap='gray'), plt.title('Original Image'), plt.axis('off')
plt.subplot(1, 2, 2), plt.imshow(image_with_keypoints), plt.title('Image with Keypoints'), plt.axis('off')
plt.show()

ORB

# ORB特征检测
import cv2
import matplotlib.pyplot as plt

# 读取图像并转换为灰度图
image = cv2.imread('cat.jpg', cv2.IMREAD_GRAYSCALE)

# 初始化 ORB 检测器
orb = cv2.ORB_create()

# 检测关键点和计算描述子
keypoints, descriptors = orb.detectAndCompute(image, None)

# 在图像上绘制关键点
orb_image = cv2.drawKeypoints(image, keypoints, None, color=(0, 255, 0))

# 显示结果
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1), plt.imshow(image, cmap='gray'), plt.title('Original Image'), plt.axis('off')
plt.subplot(1, 2, 2), plt.imshow(orb_image), plt.title('Image with ORB Keypoints'), plt.axis('off')
plt.show()

Harris 角点检测

# Harris 角点检测
# Harris 角点检测是一种用于检测图像中角点的方法,角点是图像中两条边缘交汇的点。

import cv2
import numpy as np
import matplotlib.pyplot as plt

# 读取图像
image = cv2.imread('cat.jpg', cv2.IMREAD_GRAYSCALE)

# np.float32():将图像数据类型转换为 32 位浮点型。因为 cv2.cornerHarris() 函数要求输入的图像数据类型为浮点型,所以需要进行类型转换。
gray = np.float32(image)

# OpenCV 提供了 cv2.cornerHarris() 函数用于进行 Harris 角点检测。
# gray:输入的灰度图像(已转换为浮点型)。
# 2:角点检测中使用的邻域大小,即每个像素周围考虑的邻域范围。这里表示使用 2x2 的邻域。
# 3:Sobel 算子的孔径大小,用于计算图像的梯度。
# 0.04:Harris 角点检测的自由参数,用于控制角点响应函数的计算,通常取值在 0.04 到 0.06 之间。
# 该函数返回一个与输入图像大小相同的数组 dst,数组中的每个元素表示对应像素的角点响应值。
dst = cv2.cornerHarris(gray, 2, 3, 0.04)
# 对 dst 数组进行膨胀操作。膨胀操作可以扩大角点响应值的区域,使角点更加明显,方便后续的角点筛选。
dst = cv2.dilate(dst, None)

# dst > 0.01 * dst.max():这是一个布尔数组,用于筛选出角点响应值大于 0.01 * dst.max() 的像素位置。
# dst.max() 表示 dst 数组中的最大值,0.01 * dst.max() 是一个阈值,只有角点响应值大于该阈值的像素才被认为是角点。
image[dst > 0.01 * dst.max()] = 255

# 显示结果原图像和 Harris 角点检测结果
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1), plt.imshow(image, cmap='gray'), plt.title('Original Image'), plt.axis('off')
plt.subplot(1, 2, 2), plt.imshow(dst, cmap='gray'), plt.title('Harris Corners'), plt.axis('off')
plt.show()


写一个简单的OpenCV脚本,提取两个图像的ORB特征并进行匹配

# 写一个简单的OpenCV脚本,提取两个图像的ORB特征并进行匹配。

import cv2
import numpy as np
import matplotlib.pyplot as plt

# 读取图像
img1 = cv2.imread('ORB1.jpg',cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread('ORB2.jpg',cv2.IMREAD_GRAYSCALE)

# 创建ORB特征检测器,nfeatures=500 设定ORB检测的最大特征点数为500,数值越大,提取的特征点越多。
orb = cv2.ORB_create(nfeatures=500)

# 检测特征点并计算描述符
# detectAndCompute() 方法同时检测特征点 (keypoints) 和计算它们的描述符 (descriptors)。
# kp1, des1 是 img1 的特征点和描述符,kp2, des2 是 img2 的特征点和描述符。
# keypoints 包含特征点的位置、大小、方向等信息,descriptors 是描述这些特征点的向量。
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)

# 创建BF匹配器
# cv2.BFMatcher 创建一个暴力匹配器 (BFMatcher)。
# cv2.NORM_HAMMING 表示使用 汉明距离(适用于二进制特征描述符,如 ORB、BRIEF)。
# crossCheck=True 使匹配更加严格:只有当 A 的最佳匹配是 B,同时 B 的最佳匹配也是 A 时,它们才会被视为匹配。
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)

# 匹配描述符,bf.match(des1, des2) 在两幅图像的特征描述符之间进行匹配,返回 matches(匹配点对列表)。
matches = bf.match(des1, des2)

# 按距离排序
# sorted() 函数对所有匹配点对按照它们之间的距离进行排序。
# key=lambda x: x.distance 表示按照匹配点对的距离进行排序。
matches = sorted(matches, key=lambda x: x.distance)

# 绘制匹配结果
# drawMatches() 方法绘制匹配结果。
# matches[:60] 表示只绘制前60个匹配点对。
# matchColor=(0, 255, 0) 表示匹配点对的颜色为绿色。
# singlePointColor=(0, 0, 255) 表示特征点的颜色为红色。
img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:60], None, matchColor=(0, 255, 0),singlePointColor=(0, 0, 255))

# 显示结果
plt.figure(figsize=(16, 8))
plt.axis('off')
plt.imshow(img3)
plt.show()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/971734.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

golangAPI调用deepseek

目录 1.deepseek官方API调用文档1.访问格式2.curl组装 2.go代码1. config 配置2.模型相关3.错误处理4.deepseekAPI接口实现5. 调用使用 3.响应实例 1.deepseek官方API调用文档 1.访问格式 现在我们来解析这个curl 2.curl组装 // 这是请求头要加的参数-H "Content-Type:…

闭源大语言模型的怎么增强:提示工程 检索增强生成 智能体

闭源大语言模型的怎么增强 提示工程 检索增强生成 智能体 核心原理 提示工程:通过设计和优化提示词,引导大语言模型进行上下文学习和分解式思考,激发模型自身的思维和推理能力,使模型更好地理解和生成文本,增强其泛用性和解决问题的能力。检索增强生成:结合检索的准确…

《计算机视觉》——角点检测和特征提取sift

角点检测 角点的定义: 从直观上理解,角点是图像中两条或多条边缘的交点,在图像中表现为局部区域内的灰度变化较为剧烈的点。在数学和计算机视觉中,角点可以被定义为在两个或多个方向上具有显著变化的点。比如在一幅建筑物的图像…

具身智能在智能巡检机器人中的应用——以开关柜带电操作机器人为例

随着机器人技术和人工智能的迅速发展,具身智能在各行业的应用日益广泛,尤其是在电力行业中的智能巡检领域。传统的电力巡检和维护工作通常需要人工操作,存在着高温、高压、强电磁场等危险环境,且效率较低。开关柜带电操作机器人作…

基于SpringBoot实现的大学社团平台系统实现功能八

一、前言介绍: 1.1 项目摘要 随着高校社团活动的日益丰富和多样化,学生对于社团管理和参与的需求也在不断增加。传统的社团管理方式往往存在效率低下、信息不透明等问题,无法满足现代学生对于便捷、高效社团管理的需求。因此,利…

Unity使用反射进行Protobuf(CS/SC)协议,json格式

protobuf生成的协议,有挺多协议的.利用反射生成dto进行伪协议的响应 和 发送请求 应用场景: 请求(CS)_后端先写完了(有proto接口了),前端还没搞完时(暂还没接入proto),后端可使用此请求,可自测 响应(SC)_可自行构建一个响应(有些特殊数据后端下发不了的),对数据进行测试 // 请…

使用synchronized解决高并发场景

synchronized能很好的解决高并发所带来的超卖等问题,但是synchronized也有属于它的缺陷,就是只适合单机模式,如果同时开启多个实例,那么还是会出现超卖的情况,下面就介绍一下synchronized使用方法,十分的简…

【Pytorch 库】自定义数据集相关的类

torch.utils.data.Dataset 类torch.utils.data.DataLoader 类自定义数据集示例1. 自定义 Dataset 类2. 在其他 .py 文件中引用和使用该自定义 Dataset torch_geometric.data.Dataset 类torch_geometric.data.Dataset VS torch.utils.data.Dataset 详细信息,参阅 tor…

Softing线上研讨会 | 自研还是购买——用于自动化产品的工业以太网

| 线上研讨会时间:2025年1月27日 16:00~16:30 / 23:00~23:30 基于以太网的通信在工业自动化网络中的重要性日益增加。设备制造商正面临着一大挑战——如何快速、有效且经济地将工业以太网协议集成到其产品中。其中的关键问题包括:是否只需集成单一的工…

Wireshark 输出 数据包列表本身的值

在 Wireshark 中,如果你想输出数据包列表本身的值(例如,将数据包的摘要信息、时间戳、源地址、目的地址等导出为文本格式),可以使用 导出为纯文本文件 的功能。以下是详细步骤: 步骤 1:打开 Wir…

解压rar格式的软件有哪些?8种方法(Win/Mac/手机/网页端)

RAR 文件是一种常见的压缩文件格式,由尤金・罗谢尔(Eugene Roshal)开发,因其扩展名 “rar” 而得名。它通过特定算法将一个或多个文件、文件夹进行压缩,大幅减小存储空间,方便数据传输与备份。然而&#xf…

java实现不带哨兵节点的双向链表(二)

概述 todo 扩展:实现链表节点的删除(根据索引删除节点、删除第一个元素)、添加的元素为数组最后一个元素(addLast)等 实现上一篇博客中提到的 根据索引删除节点。删除第一个元素。添加的元素为数组最后一个元素。 根…

AcWing 798. 差分矩阵

题目来源: 找不到页面 - AcWing 题目内容: 输入一个 n 行 m 列的整数矩阵,再输入 q 个操作,每个操作包含五个整数 x1,y1,x2,y2,c,其中 (x1,y1) 和 (x2,y2)表示一个子矩阵的左上角坐标和右下角坐标。 每个操作都要将…

【kafka系列】消费者

目录 获取消息 1. 消费者获取消息的流程逻辑分析 阶段一:消费者初始化 阶段二:分区分配与重平衡(Rebalance) 阶段三:消息拉取与处理 阶段四:偏移量提交 核心设计思想 2. 流程 关键点总结 常见参数…

游戏引擎学习第105天

仓库:https://gitee.com/mrxiao_com/2d_game_2 查看当前进度 今天的工作重点是继续进行渲染系统的清理。昨天已经完成了一次渲染清理,现在还有一些内容需要继续处理。首先,已经解决了坐标系统的问题,其中世界坐标基本上是正确的&#xff0c…

重新求职刷题力扣DAY15

1.[226. 翻转二叉树](https://leetcode.cn/problems/symmetric-tree/) 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 示例 1: 输入:root [4,2,7,1,3,6,9] 输出:[4,7,2,9,6,3,1]示例 2&#xff1a…

OpenGL ES -> 投影变换矩阵完美解决绘制GLSurfaceView绘制图形拉伸问题

GLSurfaceView绘制图形拉伸问题 假如在XML文件中声明GLSurfaceView的宽高为 android:layout_width"match_parent"android:layout_height"match_parent GLSurfaceView绘制的图形在Open GL ES坐标系中,而Open GL ES坐标系会根据GLSurfaceView的宽高将…

Java并发编程8--线程

1.什么是线程? 现代操作系统调度的最小单元是线程,也叫轻量级进程(Light Weight Process),在一个进程里可以创建多个线程,这些线程都拥有各自的计数器、堆栈和局部变量等属性,并且能够访问共享的…

java八股文-mysql

1. 索引 1.1 什么是索引 索引(index)是帮助Mysql高效获取数据的数据结构(有序).提高数据的检索效率,降低数据库的IO成本(不需要全表扫描).通过索引列对数据进行排序,降低数据排序成本,降低了CPU的消耗. 1.2 mysql索引使用的B树? 1. 没有使用二叉树,最坏情况o&…

开启蓝耘之旅:DeepSeek R1 模型在智算平台的起步教程

----------------------------------------------------------我的个人主页-------------------- 动动你的手指----------------------------------------点赞👍 收藏❤--------------------------------------------------------------- 引言 在深度学习的广袤领…