计算机视觉(一)OpenCV图像视频基础操作完全指南
基础掌握熟练使用imread/imshow基本函数理解图像在NumPy中的表示形式进阶技巧学习更多色彩空间转换(如HSV)掌握图像阈值处理(threshold)尝试边缘检测算法(Canny等)项目实践实现简单的人脸检测开发视频滤镜应用构建运动检测系统。
目录
引言
前文中讲解了计算机视觉的一些理论基础,今天我们在上一章对计算机视觉图像和视频的初步理解的基础之上,介绍一下python中如何用OpenCV库中,对图像或者视频有哪些基础的操作,如何操作.
一、图像读取与基本属性
1.1 图像读取与属性查看
import cv2
import numpy as np
# 读取图像(注意路径不能包含中文)
img = cv2.imread('img.png')
# 检查图像属性
print("Shape:", img.shape) # (高度, 宽度, 通道数)
print("Type:", img.dtype) # 数据类型,通常是uint8(0-255)
print("Size:", img.size) # 像素总数 = 高度×宽度×通道数
技术讲解:
cv2.imread()
是OpenCV读取图像的核心函数,支持多种格式(JPG/PNG/BMP等),注意这里路径尽量不要含有中文- 返回值
img
是一个NumPy数组,存储了图像的像素矩阵 shape
属性反映了图像的基本维度信息:- 彩色图像返回(高度, 宽度, 3)
- 灰度图像返回(高度, 宽度)
dtype
通常为uint8
,表示每个像素值范围是0-255
代码输出:
二、图像基本处理操作
2.1 色彩空间转换与模糊处理
# 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 高斯模糊处理(核大小为5×5)
blur = cv2.GaussianBlur(img, (5,5), 0)
技术讲解:
cv2.cvtColor()
用于色彩空间转换:- OpenCV默认使用BGR格式而非RGB
- 常用转换包括:BGR2GRAY、BGR2RGB、BGR2HSV
GaussianBlur()
是图像平滑处理的关键函数:- 参数(5,5)表示高斯核大小(必须为正奇数)
- 最后一个参数0表示自动计算标准差
三、图像显示与窗口控制
3.1 图像显示与交互控制
# 显示原始图像
cv2.imshow('Original', img)
cv2.imshow('Gray', gray)
cv2.imshow('Blurred', blur)
# 等待按键输入(0表示无限等待)
cv2.waitKey(0)
# 关闭所有窗口
cv2.destroyAllWindows()
技术讲解:
imshow()
函数显示图像窗口:- 第一个参数是窗口标题
- 第二个参数是图像矩阵
waitKey()
控制窗口显示时间:- 参数为毫秒数,0表示等待按键
- 返回值是按键的ASCII码
destroyAllWindows()
释放窗口资源
一~三 综合实例演示:trump.png的基础图像操作
trump.png:
图像处理代码:
import cv2
import numpy as np
# 读取图像
img = cv2.imread('img.png') # 或类似路径
# 可能的图像处理操作(示例)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转灰度图
blur = cv2.GaussianBlur(img, (5,5), 0) # 高斯模糊
# 显示图像(可能是报错的位置)
cv2.imshow('Original', img)
cv2.imshow('Gray', gray)
cv2.imshow('Blurred', blur)
cv2.waitKey(0)#0:按任何键都可以关闭窗口
cv2.destroyAllWindows()
代码运行结果展示:
四、通道操作与颜色处理
4.1 通道分离与合并
import cv2
# 读取图像
img = cv2.imread('trump.png')
# 方法一:直接切片分离通道
b = img[:,:,0] # 蓝色通道
g = img[:,:,1] # 绿色通道
r = img[:,:,2] # 红色通道
# 方法二:使用split函数
b, g, r = cv2.split(img)
# 通道合并
merged = cv2.merge((b, g, r))
# 显示各通道
cv2.imshow('Blue', b)
cv2.imshow('Green', g)
cv2.imshow('Red', r)
cv2.imshow('Merged', merged)
cv2.waitKey(0)
cv2.destroyAllWindows()
技术讲解:
- OpenCV存储顺序是BGR而非RGB
- 通道分离的两种方法:
- 直接数组切片(效率高)
split()
函数(代码更清晰)
- 通道合并使用
merge()
函数:- 参数是包含各通道的元组
- 顺序影响最终色彩表现
实例演示:trump.png的BGR通道分离与合并展示
案例需求/目的:展现trump.png的三个通道上(GBR)分别的图片内容
代码实现:
import cv2
# 读取图像
img = cv2.imread('trump.png')
# 方法一:直接切片分离通道
b = img[:,:,0] # 蓝色通道
g = img[:,:,1] # 绿色通道
r = img[:,:,2] # 红色通道
# 方法二:使用split函数
b, g, r = cv2.split(img)
# 通道合并
merged = cv2.merge((b, g, r))
# 显示各通道
cv2.imshow('Blue', b)
cv2.imshow('Green', g)
cv2.imshow('Red', r)
cv2.imshow('Merged', merged)
cv2.waitKey(0)
cv2.destroyAllWindows()
代码运行结果展示:
五、图像混合与特效
5.1 马赛克效果实现
# 读取图像
img = cv2.imread('trump.png')
# 在指定区域生成随机像素(马赛克效果)
img[100:200, 200:300] = np.random.randint(0, 256, (100, 100, 3))
cv2.imshow('Mosaic', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
技术讲解:
- 马赛克原理:
- 选择目标区域(如100:200, 200:300)
- 用随机像素值替换原像素
np.random.randint()
生成随机数:- 参数1:最小值(包含)
- 参数2:最大值(不包含)
- 参数3:生成数组形状
实例演示:trump.png图片的马塞克处理
案例需求/目的:实现对trump.png图片指定区域的马赛克处理
实现代码:
#打马赛克
import cv2
import numpy as np
a=cv2.imread('trump.png')
a[100:200,200:300]=np.random.randint(0,256,(100,100,3))
cv2.imshow('masaike',a)
cv2.waitKey(10000)
cv2.destroyAllWindows()
代码运行结果展示:
六、图像几何变换
6.1 图像缩放操作
# 读取图像
img = cv2.imread('xjy.png')
# 方法一:指定目标尺寸(宽×高)
resized1 = cv2.resize(img, (200, 600))
# 方法二:使用缩放因子(fx:宽度比例, fy:高度比例)
resized2 = cv2.resize(img, None, fx=0.6, fy=0.3)
cv2.imshow('Original', img)
cv2.imshow('Resized1', resized1)
cv2.imshow('Resized2', resized2)
cv2.waitKey(0)
cv2.destroyAllWindows()
技术讲解:
cv2.resize()
函数参数详解
函数原型
cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])
参数说明
参数 | 类型 | 说明 |
---|---|---|
src |
numpy.ndarray | 输入图像(必需) |
dsize |
tuple (w, h) | 输出图像尺寸(宽,高),设为 (0,0) 时使用 fx/fy 计算 |
fx |
float | 水平缩放因子(当 dsize=(0,0) 时生效) |
fy |
float | 垂直缩放因子(当 dsize=(0,0) 时生效) |
interpolation |
int (枚举标志) | 插值方法(默认 cv2.INTER_LINEAR ) |
插值方法常量
常量 | 说明 |
---|---|
cv2.INTER_NEAREST |
最近邻插值(最快) |
cv2.INTER_LINEAR |
双线性插值(默认) |
cv2.INTER_CUBIC |
双三次插值(质量更高) |
cv2.INTER_AREA |
区域插值(缩小图像最优) |
cv2.INTER_LANCZOS4 |
Lanczos插值(高质量放大) |
返回值
- 返回调整尺寸后的图像(numpy.ndarray)
resize()
的两种使用方式:- 直接指定目标尺寸(宽×高)
- 使用缩放因子(推荐保持宽高比)
- 插值方法:
- 默认使用线性插值
- 可通过
interpolation
参数指定其他方法(如cv2.INTER_CUBIC
)
实例演示:实例演示:xjy.png图片的图像缩放处理
xiy.png:
案例需求/目的:将xjy.png图片按一定比例缩放(宽*0.6,高*0.3)
代码实现:
#图片缩放
import cv2
a=cv2.imread('xjy.png')
#a_new=cv2.resize(a,(200,600))#宽、高
# print(a.shape)
a_new=cv2.resize(a,dsize=None,fx=0.6,fy=0.3)
cv2.imshow('a',a)
cv2.imshow('a_new',a_new)
cv2.waitKey(1000000)
cv2.destroyAllWindows()
代码运行效果展示:
七、图像合成技术
7.1 图像区域替换
# 读取两张图像
img1 = cv2.imread('img1.png')
img2 = cv2.imread('img2.png')
# 将img2的某区域替换为img1的对应区域
# 注意:两个区域尺寸必须完全相同
img2[200:350, 200:350] = img1[50:200, 100:250]
cv2.imshow('Combined', img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
技术讲解:
- 图像合成的核心是数组切片操作(可以翻看博主之前的作品,在讲解numpy的博客里有详细介绍)
- 关键注意事项:
- 源区域和目标区域尺寸必须匹配
- 坐标范围不能超出图像边界
- 建议先检查图像尺寸:
print(img1.shape, img2.shape)
案例演示:xjy.png与trump.png的图像区域替换
xjy.png和trump.png:同前文
案例需求/目的:将xjy.png图像部分区域替换为trump.png的图像内容
代码实现:
#图片组合
import cv2
a=cv2.imread('trump.png')
b=cv2.imread('xjy.png')
b[200:350,200:350]=a[50:200,100:250]#矩阵大小要一致
cv2.imshow('b',b)
cv2.imshow('a',a)
cv2.waitKey(1000000)
cv2.destroyAllWindows()
代码运行效果展示:
八、视频处理基础
8.1 视频读取与处理
# 创建视频捕获对象(文件或摄像头)
video_capture = cv2.VideoCapture('video.mp4') #参数为0时默认调用摄像头
# 检查是否成功打开
if not video_capture.isOpened():
print("无法打开视频")
exit()
while True:
# 读取帧(ret表示是否成功是布尔值,frame是图像帧)
ret, frame = video_capture.read()
if not ret:
break
# 转换为灰度帧
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('Video', gray_frame)
# 按ESC键退出(ASCII 27)
if cv2.waitKey(60) == 27:
break
# 释放资源
video_capture.release()
cv2.destroyAllWindows()
技术讲解:
VideoCapture
支持多种视频源:- 文件路径(如'video.mp4'),这里路径区别于图片,支持包含中文的路径,如('许家印.mp4')
- 摄像头索引(参数为0表示调用默认摄像头)
read()
方法返回两个值:ret
:布尔值,表示是否成功读取frame
:当前帧的图像数据
- 典型视频处理流程:
- 逐帧读取
- 帧处理(如色彩转换)
- 显示处理结果
- 设置退出条件
实例演示:许家印.mp4处理
许家印.mp4:
一段从某短视频网站合法爬取的MP4格式视频
处理代码:
#视频读取和处理
import cv2
viedo_caputure=cv2.VideoCapture('许家印.mp4')#摄像头:0
if not viedo_caputure.isOpened():
print("无法打开")
exit()
while True:
ret,frame=viedo_caputure.read()#.read函数返回两个值,第一个值赋值给ret,第二个值赋值给frame;ret是布尔值,frame是一个rbg的矩阵
#检测是否读到画面
if not ret:
break
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 图像处理
cv2.imshow('Viedo',frame)
if cv2.waitKey(60)==27: #每帧画面显示60ms,按键ASCII值为27(esc),关闭窗口(用指定的按键关闭视频)
break
viedo_caputure.release()
cv2.destroyAllWindow()
处理效果展示:
总结与进阶建议
学习路线建议
-
基础掌握:
- 熟练使用imread/imshow基本函数
- 理解图像在NumPy中的表示形式
-
进阶技巧:
- 学习更多色彩空间转换(如HSV)
- 掌握图像阈值处理(threshold)
- 尝试边缘检测算法(Canny等)
-
项目实践:
- 实现简单的人脸检测
- 开发视频滤镜应用
- 构建运动检测系统
常见问题解答
Q1:为什么imshow显示的图像颜色不对?
A:OpenCV使用BGR顺序,而其他库(如Matplotlib)使用RGB,需要进行转换:
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
Q2:如何处理大尺寸图像?
A:可以使用resize缩小显示尺寸,或采用金字塔方法(pyrDown)逐步降采样
Q3:视频处理时如何提高性能?
A:可以尝试:
- 降低处理帧率
- 缩小处理区域
- 使用多线程处理
更多推荐
所有评论(0)