OpenCV理论实践(基础)
OpenCV基础教程摘要 OpenCV是一个开源的计算机视觉库,包含2500+优化算法,支持C++/Python/Java等语言,跨平台运行。本教程涵盖: 基础操作 图像读取/显示/保存 摄像头连接与异常处理 色彩空间转换(BGR/GRAY/HSV) 图像属性获取 核心功能 图像滤波(均值/高斯/中值/双边滤波) 边缘检测(Sobel/Laplacian/Canny) 特征提取与轮廓绘制 颜色筛选
OpenCV 简介
OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习库,包含超过2500种优化算法,广泛应用于图像处理、物体检测、人脸识别、AR/VR等领域。支持C++、Python、Java等语言,跨平台(Windows、Linux、macOS、Android、iOS)。
核心功能
- 图像处理:滤波、边缘检测、色彩空间转换(如RGB转灰度)。
- 特征检测:SIFT、SURF、ORB等算法。
- 目标检测:Haar级联、YOLO、SSD等预训练模型。
- 视频分析:光流估计、背景减除。
- 机器学习:集成SVM、KNN等算法,支持模型训练与推理。
本节小编将带领大家步入OpenCV的学习,这在ROS学习的过程中也是必不可少的关键。
先别着急开始OpenCV的学习,小编先来讲述一下摄像头情况异常的处理方法。
摄像头情况异常的处理方法
前车之鉴,如果虚拟机上面的可连接设备没有显示摄像头,建议重新装一遍虚拟机,因为可能存在安装的文件丢失,小编在此处卡住了很久T▽T。
(正常情况)
先给出测试摄像头能否正常工作的操作流程,如下:
用终端编辑器(nano)创建代码文件
# 创建并编辑 camera_test.py 文件
nano camera_test.py
import cv2
# 核心:调用系统默认摄像头(0 对应 /dev/video0)
cap = cv2.VideoCapture(0)
# 优化参数:适配大多数摄像头
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) # 宽度
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) # 高度
cap.set(cv2.CAP_PROP_FPS, 30) # 帧率
cap.set(cv2.CAP_PROP_BUFFERSIZE, 1) # 减少卡顿
# 检查摄像头是否成功打开
if not cap.isOpened():
print("错误:无法连接摄像头!请检查硬件/权限")
exit()
print("摄像头连接成功 → 按 ESC 键退出")
# 循环读取并显示画面
while True:
# 读取一帧画面:ret=是否成功,frame=画面数据
ret, frame = cap.read()
if ret:
# 显示画面窗口(窗口名:Camera (OpenCV))
cv2.imshow("Camera (OpenCV)", frame)
# 关键:按 ESC 键(键码 27)退出循环
if cv2.waitKey(1) & 0xFF == 27:
break
# 释放摄像头资源 + 关闭所有窗口(必须执行)
cap.release()
cv2.destroyAllWindows()
粘贴完成后,按 Ctrl+O 保存 → 按 Enter 确认文件名 → 按 Ctrl+X 退出 nano。
# 执行 Python 代码
python3 camera_test.py
执行完成后即可看到正常的画面。
(异常情况)
1. 摄像头被占用?查占用进程并结束
# 查看占用 /dev/video0 的进程 ID
fuser /dev/video0
# 结束占用进程(替换 <PID> 为上一步输出的数字)
sudo kill -9 <PID>
2. 画面黑屏 / 读取失败?测试摄像头硬件
# 安装摄像头测试工具 Cheese
sudo apt install cheese -y
# 打开 Cheese 测试摄像头
cheese
- 若 Cheese 能显示画面,说明硬件正常,问题出在代码 / OpenCV 参数;
- 若 Cheese 也黑屏,说明摄像头未正确识别,需重新检查硬件 / VMware 直通。
3.多摄像头切换?指定设备编号
# 先查所有摄像头设备
ls /dev/video*
# 比如输出 /dev/video0 /dev/video1 → 调用第二个摄像头:
python3 -c "import cv2; cap=cv2.VideoCapture(1); print(cap.isOpened())"
关键指令:
- 验证硬件:
ls /dev/video*

- 临时赋权:
sudo chmod 777 /dev/video0(777满权) - 运行代码:
python3 camera_test.py
案例1(读取彩色图像+改成灰度图)
读取彩色图像
因为OpenCV的使用不需要创建工作空间,所有我们可以直接在一个文件夹中开始编辑python文件。
# 导入OpenCV库,用于图像处理相关操作
import cv2
# 读取指定路径的图片,以彩色模式读取,将图片数据存储到img变量中
img = cv2.imread("cat.png", cv2.IMREAD_COLOR)
# 创建名为'image'的窗口,并显示img对应的图片内容
cv2.imshow('image', img)
# 等待用户按下任意按键,参数0表示无限等待直到按键触发
cv2.waitKey(0)
# 关闭OpenCV创建的所有窗口
cv2.destroyAllWindows()
# 将img对应的图片数据,以new_image.jpg为文件名保存到当前目录
cv2.imwrite('new_image.jpg', img)
注意,要自己找到一张图片并命名为cat.png放到存python文件的文件夹中。
(小编在源码中直接调用cat.png,故而放入平行结构),运行python文件结果如图:
改成灰度图
只需将python文件中的代码修改一行,
# 读取指定路径的图片,以灰度图模式读取,将图片数据存储到img变量中
img = cv2.imread("cat.png", cv2.IMREAD_GRAYSCALE)
运行python文件结果如图:

案例2(查看图片属性)
# 导入numpy库,用于数值计算和数组操作
import numpy as np
# 导入OpenCV库,用于图像处理
import cv2
# 读取图片
img = cv2.imread('cat.png', cv2.IMREAD_COLOR)
print("===============打印一下图像的属性====================")
print("图像对象的类型:", type(img))
print("图像形状(高度, 宽度, 通道数):", img.shape)
print("图像宽度:{} pixels".format(img.shape[1]))
print("图像高度:{} pixels".format(img.shape[0]))
print("通道数:{}".format(img.shape[2]))
print("图像分辨率:{} 像素".format(img.shape[0] * img.shape[1]))
print("数据类型:{}".format(img.dtype))
# 打印图像分辨率(总像素数 = 高度×宽度)
运行python文件结果如图:

案例3(可调节的 HSV 轨迹条)
通过 OpenCV实时读取摄像头画面,搭配可调节的 HSV 轨迹条,可视化筛选画面中指定颜色的区域
import cv2
import numpy as np
# 定义空回调函数(轨迹条必须绑定回调函数,此处无实际操作)
def nothing(x):
pass # 补全函数体,避免语法错误
# 打开摄像头(0表示默认摄像头)
cap = cv2.VideoCapture(0)
# 创建名为"HsvBars"的窗口,用于放置HSV阈值调节轨迹条
cv2.namedWindow("HsvBars")
# 创建6个轨迹条,分别对应:低H、低S、低V、高H、高S、高V
cv2.createTrackbar("LH","HsvBars",0,179, nothing)
cv2.createTrackbar("LS","HsvBars",0,255, nothing)
cv2.createTrackbar("LV","HsvBars",0,255, nothing)
cv2.createTrackbar("UH","HsvBars",179,179, nothing)
cv2.createTrackbar("US","HsvBars",255,255, nothing)
cv2.createTrackbar("UV","HsvBars",255,255, nothing)
# 补全实时读取摄像头、处理图像的核心逻辑
while True:
# 逐帧读取摄像头画面
ret, frame = cap.read()
if not ret:
print("摄像头读取失败!")
break
# 将BGR格式转为HSV格式(便于颜色筛选)
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# 获取轨迹条当前的数值
lh = cv2.getTrackbarPos("LH", "HsvBars")
ls = cv2.getTrackbarPos("LS", "HsvBars")
lv = cv2.getTrackbarPos("LV", "HsvBars")
uh = cv2.getTrackbarPos("UH", "HsvBars")
uv = cv2.getTrackbarPos("UV", "HsvBars")
us = cv2.getTrackbarPos("US", "HsvBars")
# 定义HSV颜色范围(低阈值和高阈值)
lower_hsv = np.array([lh, ls, lv])
upper_hsv = np.array([uh, us, uv])
# 生成掩膜(筛选指定颜色区域)
mask = cv2.inRange(hsv, lower_hsv, upper_hsv)
# 按位与操作,提取原图像中对应颜色的区域
res = cv2.bitwise_and(frame, frame, mask=mask)
# 显示原画面、掩膜、结果画面
cv2.imshow("frame", frame)
cv2.imshow("mask", mask)
cv2.imshow("res", res)
# 按ESC键退出(ESC键码为27)
k = cv2.waitKey(1) & 0xFF
if k == 27:
break
# 释放摄像头资源,关闭所有窗口
cap.release()
cv2.destroyAllWindows()
运行python文件结果如图:

调节HSV轨迹条,结果如图:

案例4(色彩空间转换)
这段代码的核心作用是:读取本地一张名为cat.png的图片,将其分别转换成灰度图、HSV 色彩空间格式,然后在三个独立窗口中分别显示原图、灰度图、HSV 图。简单来说,就是对单张图片做「色彩空间转换」并可视化展示,是 OpenCV 图像处理的基础操作。
# 导入OpenCV库(计算机视觉处理的核心库)
import cv2
# 读取本地图片文件"cat.png",返回的img是BGR格式的图像矩阵
# 注意:图片文件需放在代码同级目录,否则需填写完整路径(如"/home/abot/Desktop/cat.png")
img = cv2.imread('cat.png')
# 将BGR格式的原图转换为灰度图(单通道)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 将BGR格式的原图转换为HSV色彩空间(常用于颜色筛选)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# 创建名为"image"的窗口,显示原始BGR图片
cv2.imshow('image', img)
# 创建名为"gray"的窗口,显示灰度图
cv2.imshow('gray', gray)
# 创建名为"hsv"的窗口,显示HSV格式图片
cv2.imshow('hsv', hsv)
# 等待用户按下任意按键后关闭窗口(参数0表示无限等待)
cv2.waitKey(0)
# 关闭所有由OpenCV创建的显示窗口,释放资源
cv2.destroyAllWindows()


案例5(video)
这是一个功能完整、注释详细、开箱即用的 OpenCV 视频处理脚本,涵盖了「读取摄像头 / 视频文件、实时显示、保存视频、按键控制」等核心功能,新手也能轻松理解和使用。
# 导入OpenCV库(核心图像处理)和numpy库(数值计算)
import cv2
import numpy as np
def main():
"""
核心功能:
1. 可切换读取「摄像头」或「本地视频文件」
2. 实时显示视频画面
3. 支持按键控制(保存视频、退出、暂停/继续)
4. 释放资源,避免内存泄漏
"""
# ===================== 配置参数(可根据需求修改) =====================
# 选择输入源:0=默认摄像头,也可填视频文件路径(如"test.mp4")
INPUT_SOURCE = 0 # 改为"your_video.mp4"可读取本地视频
# 保存视频的参数(编码格式、帧率、分辨率)
SAVE_VIDEO = False # 是否保存视频(True=保存,False=不保存)
OUTPUT_VIDEO_NAME = "output_video.mp4" # 保存的视频文件名
FPS = 30 # 视频帧率(匹配摄像头/原视频帧率)
WIDTH = 640 # 视频宽度
HEIGHT = 480 # 视频高度
# ===================== 初始化视频读取/写入 =====================
# 打开视频源(摄像头/文件)
cap = cv2.VideoCapture(INPUT_SOURCE)
# 检查视频源是否打开成功
if not cap.isOpened():
print(f"错误:无法打开视频源 {INPUT_SOURCE}!")
return
# 如果需要保存视频,初始化视频写入器
if SAVE_VIDEO:
# 视频编码格式(MP4格式推荐使用mp4v)
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(OUTPUT_VIDEO_NAME, fourcc, FPS, (WIDTH, HEIGHT))
# 检查视频写入器是否初始化成功
if not out.isOpened():
print("错误:无法创建视频写入器!")
cap.release()
return
# ===================== 实时处理视频帧 =====================
print("视频已启动!按键说明:")
print(" ESC键 → 退出程序")
print(" S键 → 保存当前帧为图片")
print(" 空格 → 暂停/继续播放")
print(" Q键 → 停止保存视频(仅开启保存时有效)")
pause = False # 暂停标志
save_frame_count = 0 # 保存图片的计数(避免重名)
while True:
# 如果未暂停,读取一帧画面
if not pause:
ret, frame = cap.read()
# 检查是否读取到画面(摄像头断开/视频播放完毕则ret=False)
if not ret:
print("提示:视频流已结束!")
break
# 调整画面分辨率(统一尺寸)
frame = cv2.resize(frame, (WIDTH, HEIGHT))
# 如果开启保存视频,写入当前帧
if SAVE_VIDEO:
out.write(frame)
# 显示实时画面(窗口名:Video Player)
cv2.imshow("Video Player", frame)
# 按键控制(1ms等待,保证实时性)
key = cv2.waitKey(1) & 0xFF
# 按ESC键退出
if key == 27:
print("程序退出中...")
break
# 按S键保存当前帧为图片
elif key == ord('s'):
img_name = f"saved_frame_{save_frame_count}.png"
cv2.imwrite(img_name, frame)
print(f"已保存当前帧:{img_name}")
save_frame_count += 1
# 按空格键暂停/继续
elif key == 32:
pause = not pause
status = "暂停" if pause else "继续"
print(f"视频{status}播放")
# 按Q键停止保存视频
elif key == ord('q') and SAVE_VIDEO:
SAVE_VIDEO = False
out.release()
print("已停止保存视频!")
# ===================== 释放资源 =====================
# 释放视频读取器
cap.release()
# 如果开启了保存视频,释放视频写入器
if SAVE_VIDEO:
out.release()
# 关闭所有OpenCV窗口
cv2.destroyAllWindows()
print("资源已释放,程序结束!")
# 程序入口
if __name__ == "__main__":
main()
核心功能说明
-
灵活的输入源:
- 默认读取「摄像头」(
INPUT_SOURCE = 0),改为视频文件路径(如"test.mp4")即可读取本地视频; - 自动检查输入源是否有效,避免程序崩溃。
- 默认读取「摄像头」(

|
ESC |
退出程序 |
| S | 保存当前帧为图片(自动编号,避免重名) |
| 空格 | 暂停 / 继续播放视频 |
| Q |
停止保存视频(仅开启保存时有效) |
案例6(图像滤波)
图像滤波本质是「对图像像素值进行邻域计算」:把每个像素的取值,替换成它和周围像素的加权平均值(或其他计算结果),从而达到去噪、平滑、增强的效果。
- 噪声:图像中的随机干扰点(比如照片上的雪花点、摄像头的杂色);
- 核(Kernel):滤波的「计算模板」(比如 3×3 的矩阵),决定了滤波的规则。
OpenCV 常用滤波算法(附代码)
以下是最常用的 6 种滤波算法,小编会逐一说明原理 + 代码 + 适用场景,最后提供整合版代码。
1. 均值滤波(平均滤波)
- 原理:用像素邻域的平均值替换当前像素,简单粗暴去噪,但会模糊边缘。
- 核心函数:
cv2.blur() - 适用场景:去除均匀分布的噪声(如高斯噪声),对边缘模糊不敏感的场景。
2. 高斯滤波
- 原理:用高斯核(中心像素权重高、周围像素权重低)加权平均,去噪的同时保留更多边缘细节。
- 核心函数:
cv2.GaussianBlur() - 适用场景:去除高斯噪声(摄像头常见噪声),是最常用的平滑滤波。
3. 中值滤波
- 原理:用像素邻域的中值替换当前像素,能有效去除椒盐噪声(黑白斑点)。
- 核心函数:
cv2.medianBlur() - 适用场景:去除椒盐噪声(如老照片的斑点、扫描件的杂点)。
4. 双边滤波
- 原理:同时考虑空间距离和像素值相似度,去噪的同时保留边缘(不会模糊边缘)。
- 核心函数:
cv2.bilateralFilter() - 适用场景:人像磨皮、保留边缘的去噪(如证件照优化)
5. 方框滤波
- 原理:类似均值滤波,可选择是否归一化,不归一化时易出现像素值溢出(亮斑)。
- 核心函数:
cv2.boxFilter() - 适用场景:特殊的亮度增强场景(较少用)。
6. 拉普拉斯滤波(边缘增强)
- 原理:二阶导数计算,突出图像边缘(属于高通滤波,和上述低通滤波相反)。
- 核心函数:
cv2.Laplacian() - 适用场景:边缘检测、图像锐化。
整合版代码:filter_demo.py
# 导入OpenCV和numpy库
import cv2
import numpy as np
def image_filter_demo():
"""
图像滤波演示:
1. 读取图片并添加噪声(模拟真实场景)
2. 分别应用6种滤波算法
3. 对比显示原图、噪声图、各滤波结果
"""
img = cv2.imread("cat.png")
if img is None:
print("错误:无法读取图片,请检查路径!")
return
# 2. 添加模拟噪声(高斯噪声+椒盐噪声,模拟真实场景)
def add_noise(image):
# 添加高斯噪声
gauss = np.random.normal(0, 20, image.shape).astype(np.uint8)
noisy_img = cv2.add(image, gauss)
# 添加椒盐噪声
s_vs_p = 0.5
amount = 0.005
out = np.copy(noisy_img)
# 椒盐噪声:白色点
num_salt = np.ceil(amount * image.size * s_vs_p)
coords = [np.random.randint(0, i - 1, int(num_salt)) for i in image.shape]
out[coords[0], coords[1], :] = 255
# 椒盐噪声:黑色点
num_pepper = np.ceil(amount * image.size * (1. - s_vs_p))
coords = [np.random.randint(0, i - 1, int(num_pepper)) for i in image.shape]
out[coords[0], coords[1], :] = 0
return out
noisy_img = add_noise(img)
# 3. 应用各种滤波算法
# 均值滤波(核大小3×3)
blur = cv2.blur(noisy_img, (3, 3))
# 高斯滤波(核3×3,σX=0自动计算)
gaussian = cv2.GaussianBlur(noisy_img, (3, 3), 0)
# 中值滤波(核大小3)
median = cv2.medianBlur(noisy_img, 3)
# 双边滤波(d=9,颜色相似度σ=75,空间距离σ=75)
bilateral = cv2.bilateralFilter(noisy_img, 9, 75, 75)
# 方框滤波(核3×3,归一化)
box = cv2.boxFilter(noisy_img, -1, (3, 3), normalize=True)
# 拉普拉斯滤波(边缘增强)
laplacian = cv2.Laplacian(img, cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian) # 转换为uint8格式
# 4. 显示所有结果(排版为2行4列)
cv2.imshow("1. Original", img)
cv2.imshow("2. Noisy Image", noisy_img)
cv2.imshow("3. Mean Filter", blur)
cv2.imshow("4. Gaussian Filter", gaussian)
cv2.imshow("5. Median Filter", median)
cv2.imshow("6. Bilateral Filter", bilateral)
cv2.imshow("7. Box Filter", box)
cv2.imshow("8. Laplacian (Edge)", laplacian)
# 5. 按键控制(按ESC退出)
print("所有窗口已打开,按ESC键退出!")
cv2.waitKey(0)
# 释放资源
cv2.destroyAllWindows()
# 程序入口
if __name__ == "__main__":
image_filter_demo()


案例7(边缘检测)
边缘检测核心概念
边缘是图像中像素值突变的区域(比如物体轮廓、明暗交界),边缘检测的本质是通过算法识别这些像素突变点,是目标检测、轮廓提取、图像分割的基础。
核心思路:先滤波去噪(避免噪声被误判为边缘)→ 计算像素梯度(识别突变)→ 非极大值抑制(细化边缘)→ 阈值筛选(保留有效边缘)。
以下是最实用的 3 类边缘检测算法,从简单到进阶,附带完整演示代码。
1. 基础梯度算子(Sobel、Scharr、Laplacian)
- Sobel:分 X/Y 方向计算梯度,抗噪性好,最常用;
- Scharr:Sobel 的升级版,对小尺寸核更精准;
- Laplacian:二阶导数,对边缘更敏感,但易放大噪声。
2. Canny 边缘检测(最优算法)
OpenCV 中最经典、效果最好的边缘检测算法,包含 4 步:高斯滤波→梯度计算→非极大值抑制→双阈值筛选,边缘最清晰、完整。
3. 轮廓提取(边缘检测的延伸应用)
基于边缘检测结果,提取物体的轮廓,可用于目标定位、面积计算等。
edge_detection.py
# 导入核心库
import cv2
import numpy as np
def edge_detection_demo():
"""
边缘检测演示:
1. 读取图片并预处理(灰度化、去噪)
2. 分别实现Sobel、Laplacian、Canny边缘检测
3. 提取轮廓并绘制
4. 对比显示所有结果
"""
# 1. 读取图片(替换为你的图片路径)
img = cv2.imread("cat.png")
if img is None:
print("错误:无法读取图片,请检查路径!")
return
# 2. 预处理:灰度化 + 高斯滤波(去噪,避免边缘检测误判)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3, 3), 0) # 高斯滤波去噪
# 3. 各类边缘检测算法实现
# --------------------- Sobel边缘检测 ---------------------
# 计算X方向梯度(左→右边缘)
sobel_x = cv2.Sobel(blur, cv2.CV_64F, 1, 0, ksize=3)
sobel_x = cv2.convertScaleAbs(sobel_x) # 转换为uint8格式
# 计算Y方向梯度(上→下边缘)
sobel_y = cv2.Sobel(blur, cv2.CV_64F, 0, 1, ksize=3)
sobel_y = cv2.convertScaleAbs(sobel_y)
# 合并X/Y方向边缘
sobel_xy = cv2.addWeighted(sobel_x, 0.5, sobel_y, 0.5, 0)
# --------------------- Laplacian边缘检测 ---------------------
laplacian = cv2.Laplacian(blur, cv2.CV_64F, ksize=3)
laplacian = cv2.convertScaleAbs(laplacian)
# --------------------- Canny边缘检测(最优) ---------------------
# 双阈值:低阈值(50)、高阈值(150),可根据图片调整
canny = cv2.Canny(blur, 50, 150)
# --------------------- 轮廓提取(基于Canny结果) ---------------------
# 查找轮廓:RETR_EXTERNAL=只找最外层轮廓,CHAIN_APPROX_SIMPLE=压缩轮廓点
contours, hierarchy = cv2.findContours(canny.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 在原图上绘制轮廓(绿色,线宽2)
contour_img = img.copy()
cv2.drawContours(contour_img, contours, -1, (0, 255, 0), 2)
# 4. 显示所有结果(排版为2行4列)
cv2.imshow("1. Original", img)
cv2.imshow("2. Sobel X", sobel_x)
cv2.imshow("3. Sobel Y", sobel_y)
cv2.imshow("4. Sobel XY", sobel_xy)
cv2.imshow("5. Laplacian", laplacian)
cv2.imshow("6. Canny(最优)", canny)
cv2.imshow("7. Contours(轮廓)", contour_img)
# 5. 按键控制(按ESC退出)
print("所有窗口已打开,按ESC键退出!")
print("提示:Canny的双阈值(50/150)可根据图片调整,以获得最佳边缘效果")
cv2.waitKey(0)
cv2.destroyAllWindows()
# 视频实时边缘检测(可选拓展)
def video_edge_detection():
"""实时处理摄像头/视频的边缘检测"""
cap = cv2.VideoCapture(0) # 0=摄像头,也可填视频路径
if not cap.isOpened():
print("错误:无法打开摄像头!")
return
print("实时边缘检测已启动,按ESC退出!")
while True:
ret, frame = cap.read()
if not ret:
break
# 预处理+Canny边缘检测
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3, 3), 0)
canny = cv2.Canny(blur, 50, 150)
# 显示原图和边缘检测结果
cv2.imshow("Original Video", frame)
cv2.imshow("Canny Edge (Real-time)", canny)
if cv2.waitKey(1) & 0xFF == 27:
break
cap.release()
cv2.destroyAllWindows()
# 程序入口
if __name__ == "__main__":
# 先运行图片边缘检测
edge_detection_demo()
# 如需实时视频检测,取消注释:
# video_edge_detection()


案例8(色彩空间)
色彩空间核心概念
色彩空间是用一组数值描述颜色的标准化体系,不同色彩空间适用于不同场景:

OpenCV 色彩空间转换核心函数
OpenCV 中所有色彩空间转换都依赖 cv2.cvtColor() 函数,语法
dst = cv2.cvtColor(src, code)
# src:输入图像;code:转换码(如cv2.COLOR_BGR2GRAY);dst:转换后图像
常用转换码(OpenCV 内置):
- BGR ↔ RGB:
cv2.COLOR_BGR2RGB/cv2.COLOR_RGB2BGR - BGR ↔ GRAY:
cv2.COLOR_BGR2GRAY/cv2.COLOR_GRAY2BGR - BGR ↔ HSV:
cv2.COLOR_BGR2HSV/cv2.COLOR_HSV2BGR - BGR ↔ YCrCb:
cv2.COLOR_BGR2YCrCb/cv2.COLOR_YCrCb2BGR - BGR ↔ HLS:
cv2.COLOR_BGR2HLS/cv2.COLOR_HLS2BGR
color_space_demo.py
# 导入核心库
import cv2
import numpy as np
import matplotlib.pyplot as plt # 用于RGB对比显示
def color_space_conversion():
"""
色彩空间转换演示:
1. 读取图片并展示原始BGR格式
2. 转换为常用色彩空间(GRAY/HSV/YCrCb/HLS/RGB)
3. 可视化对比各色彩空间效果
4. 实战:基于HSV筛选指定颜色(如红色)
"""
# 1. 读取图片(OpenCV默认BGR格式)
img = cv2.imread("cat.png")
if img is None:
print("错误:无法读取图片,请检查路径!")
return
# 2. 各类色彩空间转换
# 灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# HSV(颜色筛选核心)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# YCrCb(肤色识别)
ycrcb = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)
# HLS
hls = cv2.cvtColor(img, cv2.COLOR_BGR2HLS)
# BGR转RGB(适配matplotlib显示)
rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 3. 可视化显示(OpenCV窗口)
cv2.imshow("1. Original (BGR)", img)
cv2.imshow("2. Grayscale (GRAY)", gray)
cv2.imshow("3. Hue-Saturation-Value (HSV)", hsv)
cv2.imshow("4. YCrCb (Skin Detection)", ycrcb)
cv2.imshow("5. HLS (Outdoor Scene)", hls)
# 补充:matplotlib显示RGB(对比OpenCV的BGR)
plt.subplot(121)
plt.imshow(img) # 直接显示BGR(会偏色)
plt.title("OpenCV Default (BGR)")
plt.axis("off")
plt.subplot(122)
plt.imshow(rgb) # 正确RGB显示
plt.title("Converted RGB")
plt.axis("off")
plt.show(block=False) # 非阻塞显示
# 4. 实战:基于HSV筛选红色区域(监控/目标识别常用)
# 红色HSV范围(分两段,因为Hue=0/180是同一种红色)
lower_red1 = np.array([0, 43, 46])
upper_red1 = np.array([10, 255, 255])
lower_red2 = np.array([156, 43, 46])
upper_red2 = np.array([180, 255, 255])
# 生成红色掩膜(白色=红色区域,黑色=其他)
mask_red1 = cv2.inRange(hsv, lower_red1, upper_red1)
mask_red2 = cv2.inRange(hsv, lower_red2, upper_red2)
mask_red = cv2.bitwise_or(mask_red1, mask_red2)
# 提取红色区域
red_area = cv2.bitwise_and(img, img, mask=mask_red)
cv2.imshow("6. Red Mask (HSV筛选)", mask_red)
cv2.imshow("7. Red Area (提取结果)", red_area)
# 按键控制退出
print("所有窗口已打开,按ESC键退出!")
print("关键提示:HSV是颜色筛选的首选,需根据实际场景调整颜色阈值")
cv2.waitKey(0)
cv2.destroyAllWindows()
plt.close()
def video_color_space():
"""实时视频色彩空间转换(监控场景)"""
cap = cv2.VideoCapture(0) # 0=摄像头,可替换为监控视频路径
if not cap.isOpened():
print("错误:无法打开摄像头/视频!")
return
print("实时色彩空间转换已启动,按ESC退出!")
print("按键说明:1=原图 2=灰度 3=HSV 4=红色筛选")
mode = 1 # 默认显示原图
while True:
ret, frame = cap.read()
if not ret:
break
# 根据模式切换色彩空间
if mode == 1:
show_frame = frame
title = "Original (BGR)"
elif mode == 2:
show_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
title = "Grayscale"
elif mode == 3:
show_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
title = "HSV"
elif mode == 4:
# 实时筛选红色
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
lower_red = np.array([0, 43, 46])
upper_red = np.array([10, 255, 255])
mask = cv2.inRange(hsv, lower_red, upper_red)
show_frame = cv2.bitwise_and(frame, frame, mask=mask)
title = "Red Detection (HSV)"
# 显示结果
cv2.imshow(title, show_frame)
# 按键控制
key = cv2.waitKey(1) & 0xFF
if key == 27: # ESC退出
break
elif key == ord('1'):
mode = 1
elif key == ord('2'):
mode = 2
elif key == ord('3'):
mode = 3
elif key == ord('4'):
mode = 4
cap.release()
cv2.destroyAllWindows()
# 程序入口
if __name__ == "__main__":
# 先运行图片色彩空间转换
color_space_conversion()
# 如需实时视频/监控处理,取消注释:
# video_color_space()


昇腾计算产业是基于昇腾系列(HUAWEI Ascend)处理器和基础软件构建的全栈 AI计算基础设施、行业应用及服务,https://devpress.csdn.net/organization/setting/general/146749包括昇腾系列处理器、系列硬件、CANN、AI计算框架、应用使能、开发工具链、管理运维工具、行业应用及服务等全产业链
更多推荐


所有评论(0)