计算机视觉(opencv)实战一——图像本质、数字矩阵、RGB + 图片基本操作(灰度、裁剪、替换等)
OpenCV 入门教程:
OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉库,广泛应用于图像处理、视频分析、机器学习等地方。
在 Python 中,cv2
是 OpenCV 的主要接口模块。本文将带你一步步掌握 cv2
库的安装与基本图像处理功能。
图像的本质:像素的数字矩阵
任何数字图像(如照片、截图、手写数字图片)都是由无数个微小的 “像素点”(Pixel)组成的
-
每个像素点的数值含义:
- 对于灰度图(如代码中的手写数字),每个像素用一个 0-255 的整数表示亮度:0 代表纯黑,255 代表纯白,中间值表示不同深浅的灰色。
- 对于彩色图(如 RGB 格式),每个像素由三个数值(R、G、B)组成,分别对应红、绿、蓝三种颜色的亮度,组合后呈现出各种颜色。
彩色图的单个像素点:[0-255,0-255,0-255]:
如: [123, 85, 34] ↑ ↑ ↑ B G R在 OpenCV 中默认是 BGR,而不是 RGB
灰度图示例:
什么是RGB(Red, Green, Blue):
光学三原色(RGB):红、绿、蓝
通过将红色(R)、绿色(G)、蓝色(B)三种颜色以不同强度组合,形成各种颜色。
百度搜索 “RGB调色板” ,我们通过调色来具体对比来看看:
将第一个像素对应的R、G、B输入调色板后得到的颜色 与 像素切片篇左上角的像素颜色 相同:
注意:这里的三个数组并不是直接 print(image) 打印出来的结果。
print打印出来的结果是
而是分离通道:(本文章第七节会教,此处有印象即可)
B = img1[:, :, 0] # 蓝色B通道
G = img1[:, :, 1] # 绿色G通道
R = img1[:, :, 2] # 红色R通道或者:
B, G, R = cv2.split(img1)得到被分开的R、G、B的单独的颜色数据,同时数据的位置对应每个像素的位置。
一、安装 OpenCV 并查看版本
安装命令
pip install opencv-python
pip install opencv-contrib-python
⚠️ 注意:
opencv-contrib-python
是包含更多实验性模块和扩展功能的版本,如果你需要 SIFT、SURF 等模块,可安装:
安装完成后,可以通过如下方式验证 OpenCV 是否成功安装:
import cv2print(\"OpenCV 版本:\", cv2.__version__)
二、读取与显示图像(解析图像的矩阵)
完整图片(可保存):(或者直接百度搜索企鹅,在点开图片栏,应该第一个或第二个就是)
该图片的第一行的数字矩阵:
可以看到数字矩阵有1600行,3列
1600表示这个图片一行有1600个像素点
3表示每个像素点的BGR的数字组成
import cv2img = cv2.imread(\"penguin.jpg\")# print(img) #打印图片的数字矩阵(设置断点,调试时可以更直观)cv2.imshow(\'qie\',img)a = cv2.waitKey(5000) # 展示5秒时间(参数为0:一直执行,需要按键关闭)print(a) # 如果按下按键,获取按键的ascll码值cv2.destroyAllWindows() # 关闭所有打开的窗口并释放所有相关内存。print(\"图像形状(shape):\",img.shape)print(\"图像数据类型(dtype)\",img.dtype)print(\"图像大小(size)\",img.size)
说明:
-
cv2.imread()
:读取图像。 -
cv2.imshow()
:展示图像窗口。单引号‘’内为标题 -
cv2.waitKey(ms)
:等待键盘事件,单位为毫秒。若为0
,表示一直等待。 -
cv2.destroyAllWindows()
:关闭所有窗口。 -
img.shape
:返回图像的尺寸(高度, 宽度, 通道数)
。
结果:
图像形状(shape):(1200, 1600, 3)
1200
1600
3
该图像是一个 彩色图像(3通道),大小为 1600(列)×1200(行) 像素,使用的是 BGR 色彩空间(在 OpenCV 中默认是 BGR,而不是 RGB)。
图像数据类型(dtype): uint8
-
uint8
是 无符号 8 位整数(unsigned int 8)。 -
每个像素的每个通道用一个字节(8 位)来表示。
-
取值范围是 0 ~ 255。
图像大小(size) 5760000
-
shape
为(1200, 1600, 3)
:-
高度(行数):1200 像素
-
宽度(列数):1600 像素
-
每个像素有 3 个颜色通道(B、G、R)
-
-
dtype
为uint8
(每个通道值占 1 字节)
那么:
size = 1200 × 1600 × 3 = 5760000
所以,这个图像共有 5760000 个像素值(也可以理解为字节数)。
三、图像缩放
import cv2img = cv2.imread(\'penguin.jpg\')img_resize = cv2.resize(img, (400, 400))cv2.imshow(\'img\',img)cv2.imshow(\'img_resize\',img_resize)cv2.waitKey(0)cv2.destroyAllWindows()
说明:
-
cv2.resize()
支持调整图像分辨率,常用于适配模型或显示需求。
四、读取灰度图像并保存
读取图片时直接处理成灰度
import cv2img = cv2.imread(r\'./penguin.jpg\', cv2.IMREAD_GRAYSCALE)cv2.imshow(\'penguin_gray\',img)a = cv2.waitKey(0)print(a)cv2.destroyAllWindows()print(\"图像形状(shape):\",img.shape)print(\"图像数据类型(dtype)\",img.dtype)print(\"图像大小(size)\",img.size)cv2.imwrite(\'penguin_gray.jpg\', img) #保存灰度图片
或:
读取彩色图片后,cv2.cvtColor()进行颜色空间转换
img = cv2.imread(\'penguin.jpg\')img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
说明:
-
使用
cv2.IMREAD_GRAYSCALE
可将图像读取为灰度格式。 -
cv2.cvtColor()
进行颜色空间转换。 -
cv2.imwrite()
用于保存图像。
五、图像裁剪
import cv2img1 = cv2.imread(\'penguin.jpg\')img2 = img1[150:350,500:700]cv2.imshow(\'penguin\',img1)cv2.imshow(\'penguin_head\',img2)cv2.waitKey(0)cv2.destroyAllWindows()
说明:
-
图像裁剪可通过 NumPy 的数组切片完成。
六、读取视频文件或摄像头
import cv2video_capture = cv2.VideoCapture(\'video1.mp4\') # 若参数为0,则为摄像头if not video_capture.isOpened(): print(\"无法打开\") exit()while True: ret, frame = video_capture.read() if not ret: break frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) cv2.imshow(\'Video\', frame) if cv2.waitKey(1) == 27: # 数字为每一帧的间隔 breakvideo_capture.release()cv2.destroyAllWindows()
摄像头读帧:video_capture = cv2.VideoCapture(0)
说明:
-
cv2.VideoCapture()
可打开视频文件或0摄像头。 -
video_capture.isOpened()
:检查摄像头是否成功打开,返回True
(成功)或False
(失败)。 -
cv2.cvtColor()
进行颜色空间转换。 -
ret, frame = video_capture.read()
video_capture.read()
:从摄像头读取一帧图像。- 返回两个值:
ret
是布尔值(True
表示读取成功,False
表示失败,如摄像头断开);frame
是读取到的图像帧(numpy 数组格式)。
七、分离与合并颜色通道
分离通道指的是将一个三通道彩色图像拆成 三个单通道灰度图
所以每个图只表示一个颜色成分的强度(所有颜色都由红蓝绿三原色组成)
import cv2img1 = cv2.imread(\'penguin.jpg\')# =====分离颜色通道=====# 两种分离方式:# B = img1[:, :, 0] # 蓝色B通道# G = img1[:, :, 1] # 绿色G通道# R = img1[:, :, 2] # 红色R通道B, G, R = cv2.split(img1)cv2.imshow(\'B\', B)cv2.imshow(\'G\', G)cv2.imshow(\'R\', R)cv2.waitKey(0)# =====合并颜色通道=====img2 = cv2.merge([B, G, R])cv2.imshow(\'RGB\', img2)cv2.waitKey(0)cv2.destroyAllWindows()
说明:
-
cv2.split()
分离 B、G、R 通道。 -
cv2.merge()
合并通道生成彩色图像。
通过调试观察数据组成:
可以看到数据的上面是
八、区域像素替换与图像合成
7.1 用随机像素填充图像区域(打码):
import cv2import numpy as npimg = cv2.imread(\'penguin.jpg\')img[150:350,500:700] = np.random.randint(0,256,(200,200,3))cv2.imshow(\'penguin_head\',img)cv2.waitKey(0)cv2.destroyAllWindows()
7.2 图像区域拷贝与粘贴(换头):
import cv2img1 = cv2.imread(\'penguin.jpg\')img2 = cv2.imread(\'penguin.jpg\')# head = img1[150:350,500:700]# img2[250:450,1000:1200] = headhead = img1[250:450,1000:1200]img2[150:350,500:700] = headcv2.imshow(\'img1\',img1)cv2.imshow(\'img2\',img2)cv2.waitKey(0)cv2.destroyAllWindows()
说明:
-
通过数组操作,可轻松实现区域复制与图像拼接。
总结
通过本教程,我们学习了 OpenCV 的以下基础内容:
cv2.imread()
cv2.imshow()
cv2.IMREAD_GRAYSCALE
、cv2.cvtColor()
cv2.VideoCapture()
cv2.split()
、cv2.merge()
cv2.resize()
cv2.imwrite()