刚接触 OpenCV 时可能会觉得各种函数和参数眼花缭乱。这篇文章我会用最通俗的语言,结合实战代码,带你快速掌握 OpenCV 最常用的图片和视频处理技巧,看完就能上手操作!
一、准备工作
首先确保你已经安装了 OpenCV 和 numpy:
bash
运行
pip install opencv-python numpy
OpenCV 读取图片默认是BGR 格式(不是常见的 RGB),图片数据会以 NumPy 数组的形式存储,这是我们后续所有操作的基础。
二、图片基础操作
1. 读取、显示、保存图片
这是最基础的三步操作,先看完整代码:
python
运行
import cv2
# 1. 读取图片(BGR格式)
img = cv2.imread('ENDFIELD_SHARE_1771487612.png') # 替换成你的图片路径
# 打印图片基本信息
print("图像形状 (高, 宽, 通道数):", img.shape)
print("图像数据类型:", img.dtype) # 通常是uint8,像素值0-255
print("总像素数:", img.size)
# 2. 显示图片
cv2.imshow('我的第一张图片', img) # 窗口名称 + 图片数据
key = cv2.waitKey(0) # 0表示永久显示,按任意键继续
print(f"按下的按键ASCII码: {key}") # 可以用来判断按了哪个键
cv2.destroyAllWindows() # 关闭所有窗口
# 3. 读取并保存灰度图
gray_img = cv2.imread('ENDFIELD_SHARE_1771487612.png', cv2.IMREAD_GRAYSCALE)
cv2.imshow('灰度图', gray_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 保存处理后的图片
cv2.imwrite('灰度图_保存版.png', gray_img)
解读:
cv2.imread():括号里填图片路径,加cv2.IMREAD_GRAYSCALE就能读成黑白的灰度图cv2.imshow():第一个参数是窗口名字(随便取),第二个是要显示的图片数据cv2.waitKey(0):千万不能少!没有它图片窗口会一闪而过cv2.imwrite():第一个参数是保存的文件名,第二个是要保存的图片数据
2. 截取图片的指定区域(ROI)
ROI 就是 "感兴趣区域",比如只想截取图片中某一块,直接对 NumPy 数组切片就行:
python
运行
import cv2
# 读取图片
img = cv2.imread('ENDFIELD_SHARE_1771487612.png')
# 截取区域:[起始行:结束行, 起始列:结束列]
roi = img[30:230, 100:300] # 行范围30-229,列范围100-299
# 显示原图和截取的区域
cv2.imshow('原图', img)
cv2.imshow('截取的区域', roi)
cv2.waitKey(0)
cv2.destroyAllWindows()
解读:
- OpenCV 中图片的坐标是:先行(高) 后列(宽),和我们平时说的 "宽 x 高" 相反
- 切片是 "左闭右开",比如
30:230实际取的是 30 到 229 行,总共 200 行
3. 提取和合并 RGB 颜色通道
OpenCV 读取的图片是 BGR 格式(蓝 - 绿 - 红),我们可以单独提取某个颜色通道,也能合并通道:
python
运行
import cv2
# 读取图片
img = cv2.imread('ENDFIELD_SHARE_1771487612.png')
# 方法1:直接切片提取通道
b_channel = img[:, :, 0] # 蓝色通道(第0层)
g_channel = img[:, :, 1] # 绿色通道(第1层)
r_channel = img[:, :, 2] # 红色通道(第2层)
# 方法2:用cv2.split()提取
b, g, r = cv2.split(img)
# 显示单个通道(显示为灰度图,因为只有一个通道)
cv2.imshow('蓝色通道', b_channel)
cv2.imshow('绿色通道', g_channel)
cv2.imshow('红色通道', r_channel)
cv2.waitKey(0)
# 只保留蓝色通道(把绿、红通道设为0)
img_blue = img.copy() # 复制原图,避免修改原数据
img_blue[:, :, 1] = 0 # 绿色通道置0
img_blue[:, :, 2] = 0 # 红色通道置0
cv2.imshow('只显示蓝色', img_blue)
cv2.waitKey(0)
# 合并通道(必须按B-G-R顺序)
img_merge = cv2.merge((b, g, r))
cv2.imshow('合并后的图片', img_merge)
cv2.waitKey(0)
cv2.destroyAllWindows()
解读:
- 单个通道显示是灰色的,因为只有亮度信息,没有颜色信息
- 想显示纯蓝色 / 绿色 / 红色,需要把另外两个通道置 0
- 合并通道时顺序必须是 B-G-R,和 OpenCV 的读取格式对应
三、图片进阶操作
1. 图片打码(马赛克效果)
本质是给指定区域的像素赋值随机数,实现马赛克效果:
python
运行
import cv2
import numpy as np
# 读取图片
img = cv2.imread('ENDFIELD_SHARE_1771487612.png')
# 给100x100的区域打码(行100-199,列200-299)
# 生成和区域大小一致的随机像素值(0-255)
img[100:200, 200:300] = np.random.randint(0, 256, (100, 100, 3))
# 显示打码后的图片
cv2.imshow('马赛克效果', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
解读:
np.random.randint(0, 256, (100, 100, 3)):生成 100 行 100 列 3 通道的随机数(像素值范围)- 赋值时两边的形状必须完全一致,否则会报错
2. 图片拼接 / 替换
把一张图片的部分区域替换成另一张图片的内容:
python
运行
import cv2
# 读取两张图片
img1 = cv2.imread('ENDFIELD_SHARE_1771487612.png')
img2 = cv2.imread('zl.png')
# 把img2的200:350行、200:350列区域,替换成img1的50:200行、100:250列区域
# 注意:350-200=150,200-50=150;350-200=150,250-100=150,大小必须一致
img2[200:350, 200:350] = img1[50:200, 100:250]
# 显示结果
cv2.imshow('原图1', img1)
cv2.imshow('替换后的图2', img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
3. 图片缩放
调整图片的大小,两种常用方式:
python
运行
import cv2
# 读取图片
img = cv2.imread('ENDFIELD_SHARE_1771487612.png')
# 方式1:指定目标大小(宽, 高)
img_resize1 = cv2.resize(img, dsize=(200, 200))
# 方式2:按比例缩放(fx=横向比例,fy=纵向比例)
# img_resize2 = cv2.resize(img, None, fx=1.5, fy=0.5) # 宽放大1.5倍,高缩小0.5倍
# 显示对比
cv2.imshow('原图', img)
cv2.imshow('缩放后的图', img_resize1)
cv2.waitKey(0)
cv2.destroyAllWindows()
解读:
dsize=(宽, 高):注意顺序是宽在前,高在后,和 img.shape(高,宽)相反- 按比例缩放时,
dsize要设为 None
四、视频处理基础
读取视频文件并逐帧处理(比如转灰度):
python
运行
import cv2
# 打开视频文件(换成你的视频路径,摄像头用0)
cap = cv2.VideoCapture('转场.mp4')
# 检查视频是否打开成功
if not cap.isOpened():
print("无法打开视频文件!")
exit()
# 逐帧读取视频
while True:
# ret=是否读取成功,frame=当前帧的图片数据
ret, frame = cap.read()
# 没有帧了就退出循环(视频播放完)
if not ret:
break
# 对每一帧进行处理(转灰度)
frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 显示当前帧
cv2.imshow('视频播放', frame_gray)
# 按ESC键(ASCII码27)退出,60是每帧间隔毫秒(控制播放速度)
if cv2.waitKey(60) == 27:
break
# 释放资源(必须做!)
cap.release()
cv2.destroyAllWindows()
解读:
- 视频本质是一张张图片(帧)的连续播放
cap.read():每次读一帧,读完返回 Falsecv2.waitKey(60):控制播放速度,值越小播放越快- 最后一定要用
cap.release()释放视频资源
五、新手避坑指南
- 路径问题:图片 / 视频路径写错会导致读取失败,建议用绝对路径(比如
C:/test/1.png),或把文件放在代码同目录 - 窗口关闭:
cv2.imshow()后必须加cv2.waitKey(),否则窗口会卡死 - 形状匹配:数组赋值时两边形状必须一致,比如 100x100 的区域不能赋值 200x200 的数据
- 通道顺序:OpenCV 是 BGR,不是 RGB,合并通道时别搞反
总结
- OpenCV 的核心是把图片当成 NumPy 数组处理,切片、赋值等操作和 NumPy 完全一致;
- 图片操作的核心流程:读取 (
imread)→处理→显示 (imshow)→保存 (imwrite),注意waitKey和窗口关闭; - 视频处理就是逐帧读取 + 图片处理,记得最后释放视频资源。
跟着上面的代码一步步跑一遍,你就能快速掌握 OpenCV 的基础用法。刚开始不用死记函数,多用几次自然就熟了!