资讯动态

学习日记 7.31

发布时间:2026/8/5 10:49:14 来源:尧图企业网站定制
这是一篇 OpenCV 入门学习笔记从基础操作开始逐步覆盖视频处理、图像像素操作最后用一个综合练习把各部分串起来。目录环境准备初识 OpenCV读取与显示图像理解图像的本质NumPy 数组图像的基本操作裁剪、灰度化与保存视频文件处理图像像素级操作通道分离、打码与拼接综合练习多步骤图像处理总结与下一步1. 环境准备环境搭建很简单装一下 opencv-python 和 numpy 就行pip install opencv-python numpy然后在 Python 里导入import cv2import numpy as np为什么还得装 NumPyOpenCV 里的图像在底层就是用 NumPy 数组ndarray存的所以 NumPy 的切片、索引、变形这些操作直接就能用在图像上。这个认知后面会反复用到。2. 初识 OpenCV读取与显示图像先从最简单的开始——读图、显示。import cv2# 读取图像a cv2.imread(1.jpg)# 缩放图像到指定尺寸img_resize cv2.resize(a, (100, 111))# 显示图像cv2.imshow(tu, a)# 等待按键返回按键的 ASCII 码b cv2.waitKey(0)print(b)# 销毁所有窗口cv2.destroyAllWindows()逐行解读函数作用关键参数cv2.imread(path)读取图像文件返回 NumPy 数组cv2.IMREAD_GRAYSCALE可以灰度模式读取cv2.resize(src, dsize)缩放图像dsize(宽, 高)cv2.imshow(winname, img)在窗口中显示图像窗口名 图像数组cv2.waitKey(0)等待键盘输入0表示无限等待正数表示等待毫秒数cv2.destroyAllWindows()关闭所有 OpenCV 窗口良好的资源释放习惯小贴士cv2.waitKey(0)返回的是按下按键的ASCII 码比如 ESC 键是 27可以用来做退出判断。OpenCV 默认的色彩空间是BGR蓝-绿-红不是 RGB。这是个历史遗留问题后面做颜色相关操作的时候注意一下。3. 理解图像的本质NumPy 数组在 OpenCV 里一张图就是个 NumPy 多维数组这点搞清楚了后面会顺手很多。c cv2.imread(3.png, cv2.IMREAD_GRAYSCALE)print(图像形状(shape):, c.shape) # 输出例如: (480, 640)print(图像数据类型(dtype):, c.dtype) # 输出例如: uint8print(图像大小(size):, c.size) # 输出例如: 307200 (480 × 640)三种图像模式的数组结构彩色图像 (BGR): shape (高, 宽, 3) → 3 表示 B、G、R 三个通道灰度图像 (Gray): shape (高, 宽) → 只有一个亮度通道带透明通道 (BGRA): shape (高, 宽, 4) → 4 表示 B、G、R、Alpha关键属性属性含义示例shape数组的形状高, 宽, 通道数(480, 640, 3)dtype数据类型uint8无符号 8 位整数范围 0-255size像素总数高 × 宽 × 通道数921600核心理解图像就是 NumPy 数组那数组切片语法自然可以直接拿来裁剪图像b a[30:230, 100:300] # 截取图像的一部分行30到230列100到300这行代码就是从原图里裁一个 200×200 的区域跟 NumPy 切片写法一模一样。4. 图像的基本操作裁剪、灰度化与保存4.1 灰度化读取c cv2.imread(3.png, cv2.IMREAD_GRAYSCALE)用cv2.IMREAD_GRAYSCALE标志位可以直接以灰度模式读取不用再额外转一次。4.2 保存图像cv2.imwrite(3_gray.jpg, c)保存到本地格式由文件名后缀决定.jpg,.png,.bmp都行。4.3 同时显示多个窗口a cv2.imread(3.png)b a[30:230, 100:300] # 裁剪 ROI 区域cv2.imshow(原图, a)cv2.imshow(裁剪区域, b)cv2.waitKey(0)cv2.destroyAllWindows()可以同时开多个cv2.imshow窗口对比原图和处理效果很方便。5. 视频文件处理视频就是一帧一帧图像连起来。处理流程打开视频 → 逐帧读取 → 每帧做点处理 → 显示/保存。import cv2# 打开视频文件video_capture cv2.VideoCapture(1.mp4)# 检查视频是否成功打开if not video_capture.isOpened():print(无法打开视频文件)exit()# 循环读取视频while True:# 逐帧读取视频ret, frame video_capture.read()# 检查是否读取成功视频播放完毕时 ret 为 Falseif not ret:break# 可选对每一帧做处理例如转为灰度# frame cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)# 显示当前帧cv2.imshow(Video, frame)# 每 60ms 刷新一帧按下 ESC 键退出if cv2.waitKey(60) 27:break# 释放资源video_capture.release()cv2.destroyAllWindows()关键知识点函数说明cv2.VideoCapture(path)打开视频文件也可以是摄像头索引比如0就是默认摄像头.isOpened()检查视频源是否成功打开.read()返回(ret, frame)元组——ret是布尔值表示是否成功frame是当前帧.release()释放视频资源别忘了调用不然可能资源泄漏cv2.waitKey(60)控制播放速度——帧之间等 60ms大概 16 FPS小贴士cv2.waitKey()的延迟时间直接决定播放速度。设太小会快进太大又卡顿。25 FPS 大概是waitKey(40)30 FPS 大概是waitKey(33)。6. 图像像素级操作通道分离、打码与拼接这一节开始直接用像素动手了。6.1 通道分离与合并a cv2.imread(3.png)# 方法一用 NumPy 切片a1 a[:, :, 0] # B 通道a2 a[:, :, 1] # G 通道a3 a[:, :, 2] # R 通道# 方法二用 OpenCV 的 split 函数b, g, r cv2.split(a)# 显示各个通道cv2.imshow(Blue Channel, b)cv2.imshow(Green Channel, g)cv2.imshow(Red Channel, r)# 合并通道img cv2.merge((a1, a2, a3))注意cv2.split()会产生三份数据拷贝比较吃内存。如果只处理单个通道直接用 NumPy 切片a[:, :, 0]更省。6.2 图片打码随机噪声马赛克打码是处理敏感信息常用的手段。这里介绍两种方式随机噪声马赛克和像素化马赛克。方法一随机噪声马赛克思路很简单选一块区域用随机颜色填上去。import cv2import numpy as np# 读取图像img cv2.imread(photo.jpg)# 定义打码区域左上角坐标 (x, y) 和宽高 (w, h)x, y, w, h 150, 100, 100, 100# 提取目标区域ROIroi img[y:yh, x:xw]# 生成跟 ROI 形状一样的随机噪声# np.random.randint(0, 256, ...) 生成 0~255 之间的随机整数noise np.random.randint(0, 256, roi.shape, dtypenp.uint8)# 把噪声覆盖到原图的打码区域img[y:yh, x:xw] noise# 显示结果cv2.imshow(Random Noise Mosaic, img)cv2.waitKey(0)cv2.destroyAllWindows()方法二像素化马赛克更像真实的马赛克传统马赛克的思路是先缩小再放大利用插值产生模糊的方块效果。import cv2img cv2.imread(photo.jpg)# 定义打码区域x, y, w, h 150, 100, 100, 100roi img[y:yh, x:xw]# 关键步骤先大幅缩小再放大回原尺寸# 缩小系数越大马赛克方块越大small cv2.resize(roi, (10, 10), interpolationcv2.INTER_LINEAR)mosaic cv2.resize(small, (w, h), interpolationcv2.INTER_NEAREST)# 覆盖回原图img[y:yh, x:xw] mosaiccv2.imshow(Pixelated Mosaic, img)cv2.waitKey(0)cv2.destroyAllWindows()两种方法对比方法效果原理适用场景随机噪声彩色雪花点用随机像素填充完全遮挡没法还原像素化马赛克大块色块缩放 最近邻插值视觉模糊打码效果更自然关键技巧像素化马赛克里cv2.INTER_NEAREST最近邻插值是关键——放大时不做平滑所以方块边界很清晰就是经典的马赛克效果。7. 综合练习多步骤图像处理把前面学的东西串一遍做个综合练习。任务描述读取一张人物照片 → 裁剪出人脸区域 → 对人脸做像素化马赛克 → 把打码人脸贴回原图 → 同时显示原图、灰度图和最终结果。完整代码如下import cv2import numpy as np# 1. 读取原始图像 img cv2.imread(portrait.jpg)if img is None:print(无法读取图像请检查文件路径)exit()print(f原始图像尺寸: {img.shape})# 2. 转换为灰度图用于对比展示gray_img cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 3. 裁剪人脸区域根据实际图片调整坐标# 假设人脸在图像中央偏上h, w img.shape[:2]face_x, face_y int(w * 0.3), int(h * 0.15)face_w, face_h int(w * 0.4), int(h * 0.5)# 提取人脸 ROIface_roi img[face_y:face_yface_h, face_x:face_xface_w]# 4. 对人脸区域做像素化马赛克 # 缩小到 8×8 的色块small_face cv2.resize(face_roi, (8, 8), interpolationcv2.INTER_LINEAR)# 放大回原始尺寸用最近邻插值保留方块感mosaic_face cv2.resize(small_face, (face_w, face_h), interpolationcv2.INTER_NEAREST)# 5. 将打码人脸贴回原图 result img.copy() # 保留原始图像result[face_y:face_yface_h, face_x:face_xface_w] mosaic_face# 6. 保存结果 cv2.imwrite(result_mosaic.jpg, result)print(处理完成结果已保存为 result_mosaic.jpg)# 7. 在三个窗口中并排显示 cv2.imshow(Original, img)cv2.imshow(Grayscale, gray_img)cv2.imshow(Result - Mosaic Face, result)print(按任意键关闭窗口...)cv2.waitKey(0)cv2.destroyAllWindows()练习要点回顾图像读取与校验用cv2.imread()读取后检查是否为None。色彩空间转换cv2.cvtColor()把 BGR 转成灰度图。ROI 裁剪用 NumPy 切片img[y:yh, x:xw]提取感兴趣区域。像素化马赛克缩小再放大 cv2.INTER_NEAREST做出经典打码效果。图像保存cv2.imwrite()存到本地。挑战题试试同时对人脸和姓名标签两个区域打码。思路分别对两个 ROI 做马赛克再分别贴回原图。8. 总结学习要点回顾一下今天接触到的关键内容知识点核心内容关键函数图像本质图像 NumPy 多维数组支持切片、索引等数组操作.shape/.dtype/.size图像读写读取文件、缩放、显示窗口、保存结果cv2.imread()/cv2.imshow()/cv2.imwrite()视频处理逐帧读取循环、资源释放cv2.VideoCapture()/.read()/.release()通道操作BGR 色彩空间、通道分离与合并cv2.split()/cv2.merge()像素级操作ROI 裁剪、随机噪声打码、像素化马赛克cv2.resize() NumPy 切片学习建议动手实践每一段代码都亲手跑一遍调调参数看看输出有什么变化。刻意练习改一改马赛克方块大小、视频播放速度观察效果怎么变的。建立肌肉记忆反复练cv2.imread()→ 处理 →cv2.imshow()→cv2.waitKey()→cv2.destroyAllWindows()这套标准流程。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价