OpenCV 保姆级入门:从图像本质到代码实现的核心操作全解

OpenCV 保姆级入门:从图像本质到代码实现的核心操作全解 一、前置基础图像在计算机里到底是什么在写代码之前先搞懂最核心的底层概念后面所有操作都基于这个灰度图本质是一个二维数组行数 图像高度列数 图像宽度。每个元素是一个像素值范围 0~2550 代表纯黑255 代表纯白中间值是不同深浅的灰色。彩色图本质是三维数组形状为(高度, 宽度, 通道数)。OpenCV 默认通道顺序是BGR蓝 - 绿 - 红和我们常说的 RGB 顺序相反这是新手最容易踩的坑。数据类型像素默认是uint8无符号 8 位整数刚好对应 0~255 的取值范围节省存储空间。我们后面做的裁剪、打码、通道分离本质全都是对这个 numpy 数组做增删改查。二、环境安装OpenCV 开发只需要两个核心库直接 pip 安装即可下载慢可以加清华源#numpy的安装 pip install numpy2.4.6 -i https://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com #opencv的安装 pip install opencv-python -i https://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com pip install opencv-contrib-python -i https://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.comopencv-pythonOpenCV 的 Python 封装所有图像处理 API 都在这里numpy图像处理的底层依赖所有像素运算、数组切片都靠它三、Demo1彩色图像读取与属性查看核心知识点cv2.imread()图像读取函数默认模式cv2.IMREAD_COLOR可简写为 1彩色模式读取忽略透明通道路径错误不会报错只会返回 None所以运行后没画面先检查路径cv2.imshow()创建窗口显示图像第一个参数是窗口名同名窗口会被覆盖cv2.waitKey()键盘绑定函数单位毫秒参数为 0无限等待直到按下任意键才继续执行参数为正数等待对应毫秒数超时自动往下走返回值是按下按键的 ASCII 码ESC 键对应值为 27必须和imshow配合使用否则窗口会一闪而过、无响应图像三大属性shape返回(高度, 宽度, 通道数)彩色图通道数为 3灰度图只有前两个值dtype像素数据类型默认uint8size总像素数 高 × 宽 × 通道数import cv2 import numpy as np # 读取彩色图片默认BGR模式文件要和代码同目录否则写完整路径 img cv2.imread(test.jpg) # 创建窗口显示图片第一个参数是窗口名称 cv2.imshow(彩色原图, img) # 等待键盘输入0代表无限等待接收按键的ASCII码 key_code cv2.waitKey(0) print(按下的按键编码, key_code) # 销毁所有窗口释放内存养成随手写的好习惯 cv2.destroyAllWindows() # 打印图像基础属性 print(f图像形状(高度, 宽度, 通道数){img.shape}) print(f像素数据类型{img.dtype}) print(f图像总像素数量{img.size})四、Demo2灰度图读取、ROI 裁剪与图像保存核心知识点灰度图读取imread第二个参数传cv2.IMREAD_GRAYSCALE可简写为 0直接读取为单通道灰度图比 “读彩色再转灰度” 效率更高。ROI感兴趣区域图像处理中只需要处理的局部区域通过 numpy 数组切片实现格式为[行起始:行结束, 列起始:列结束]对应图像的「高度范围、宽度范围」。cv2.imwrite()图像保存函数根据文件名后缀自动判断格式支持 jpg、png 等常见格式。原始字符串r路径前加 r可以避免路径中反斜杠的转义问题Windows 路径推荐加上。import cv2 import numpy as np # 1. 灰度图读取与保存 # 第二个参数设为灰度模式直接读取单通道灰度图 gray_img cv2.imread(rtest.png, cv2.IMREAD_GRAYSCALE) cv2.imshow(灰度图, gray_img) cv2.waitKey(0) cv2.destroyAllWindows() # 将灰度图保存到本地后缀名决定保存格式 cv2.imwrite(test_gray.png, gray_img) # 2. 图片切片裁剪ROI提取 # 读取彩色原图 origin_img cv2.imread(rtest.png) # 数组切片[行范围, 列范围] [高度方向, 宽度方向] # 截取行30到230、列100到300的矩形区域 cut_img origin_img[30:230, 100:300] # 同时显示原图和裁剪后的区域 cv2.imshow(原图, origin_img) cv2.imshow(裁剪区域, cut_img) cv2.waitKey(0) cv2.destroyAllWindows()五、Demo3视频文件读取与播放核心知识点视频本质由一帧一帧的静态图像组成按固定帧率连续播放形成动态画面。处理视频本质就是循环处理每一帧图像。cv2.VideoCapture()视频捕获对象传文件路径读取本地视频传数字 0调用电脑默认摄像头isOpened()判断视频 / 摄像头是否成功打开是必加的异常判断避免程序崩溃。read()方法逐帧读取视频返回两个值ret布尔值读取成功返回 True视频结束或读取失败返回 Falseframe当前帧的图像数组和普通图片格式完全一致可以直接用所有图片处理 API播放速度控制通过cv2.waitKey()的参数控制数值越大每帧间隔越长播放越慢。通常 25~30ms 对应正常播放速度。import cv2 # 创建视频捕获对象传入本地视频路径 video cv2.VideoCapture(test.mp4) # 判断视频是否成功打开失败直接退出 if not video.isOpened(): print(视频读取失败请检查文件路径) exit() # 循环逐帧读取视频 while True: # 读取一帧画面ret为是否读取成功frame为当前帧图像 ret, frame video.read() # 视频读取完毕ret为False跳出循环 if not ret: break # 取消注释可将视频转为灰度播放 # frame cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 显示当前帧 cv2.imshow(视频播放, frame) # 每20ms刷新一帧按下ESC键ASCII码27退出播放 if cv2.waitKey(20) 27: break # 释放视频资源销毁窗口 video.release() cv2.destroyAllWindows()六、Demo4图像缩放 resize核心知识点两种常用缩放方式固定尺寸缩放直接指定目标(宽度, 高度)简单粗暴但比例不对会导致图像变形比例缩放通过fx宽度缩放比例、fy高度缩放比例控制dsize传 None等比例缩放不会变形高频踩坑resize的尺寸参数顺序是(宽度, 高度)而img.shape返回的是(高度, 宽度)顺序完全相反新手 90% 会在这里踩坑。插值算法resize 默认使用双线性插值缩放时自动填充 / 减少像素保证画面平滑普通场景不用手动修改import cv2 import numpy as np img cv2.imread(test.jpg) # 方式1固定尺寸缩放参数顺序是(宽度, 高度) resize_fixed cv2.resize(img, (300, 300)) # 方式2按比例缩放宽高都缩小为原来的0.5倍不会变形 resize_scale cv2.resize(img, None, fx0.5, fy0.5) # 同时显示对比 cv2.imshow(原图, img) cv2.imshow(等比例缩放后, resize_scale) cv2.waitKey(0) cv2.destroyAllWindows()七、Demo5BGR 通道分离与合并核心知识点颜色通道原理彩色图像由蓝 (B)、绿 (G)、红 (R) 三个独立的单通道叠加而成。每个通道本身都是灰度图代表对应颜色的亮度分布。通道索引OpenCV 中第 0 维是 B 通道第 1 维是 G 通道第 2 维是 R 通道。cv2.split()自动分离三个通道返回顺序为b, g, r。cv2.merge()将多个单通道合并为彩色图像传入顺序必须是 B、G、R否则颜色会完全错乱。应用场景单独调整某一颜色分量、颜色识别、图像调色等是所有颜色处理的基础操作。import cv2 img cv2.imread(test.jpg) # 通道分离 # 方法1数组切片手动提取通道 b_channel img[:, :, 0] # 所有行、所有列、第0个通道蓝色 g_channel img[:, :, 1] # 绿色通道 r_channel img[:, :, 2] # 红色通道 # 方法2split函数一次性分离更简洁返回顺序b, g, r b, g, r cv2.split(img) # 单通道显示出来都是灰度效果代表对应颜色的亮度 cv2.imshow(蓝色通道, b) cv2.imshow(绿色通道, g) cv2.imshow(红色通道, r) cv2.waitKey(0) cv2.destroyAllWindows() # 通道合并 # 按BGR顺序合并三个单通道还原彩色图 merge_img cv2.merge((b, g, r)) cv2.imshow(通道合并结果, merge_img) cv2.waitKey(0) cv2.destroyAllWindows()八、Demo6像素级修改 —— 马赛克打码与区域粘贴核心知识点像素级操作原理图像是 numpy 数组直接对数组切片赋值就能批量修改对应区域的所有像素。随机马赛克原理用np.random.randint生成 0~255 范围内的随机整数数组替换掉原图指定区域的像素破坏原有图像信息达到打码效果。区域粘贴原理把源图像的切片区域直接赋值给目标图像的切片区域。硬性前提源区域和目标区域的尺寸必须完全一致否则会报形状不匹配错误。注意np.random.randint(0,256, size)是左闭右开区间上限写 256 才能取到 255 这个像素最大值。import cv2 import numpy as np # 1. 随机噪声马赛克打码 img cv2.imread(test.jpg) # 给行100-200、列200-300的矩形区域填充随机像素 # 生成形状为(100,100,3)的随机数组值范围0~255 img[100:200, 200:300] np.random.randint(0, 256, (100, 100, 3)) cv2.imshow(马赛克打码效果, img) cv2.waitKey(0) cv2.destroyAllWindows() # 2. 图片区域复制粘贴 img1 cv2.imread(test.jpg) img2 cv2.imread(test2.jpg) # 将img1的局部区域复制粘贴到img2的指定位置 # 两边区域尺寸必须完全一致都是300行×300列 img2[200:500, 300:600] img1[150:450, 100:400] cv2.imshow(原图1, img1) cv2.imshow(粘贴后的图2, img2) cv2.waitKey(0) cv2.destroyAllWindows()九、综合实战作业所有知识点串联作业要求读取彩色原图统一缩放为 500×500 尺寸截取左上角 ROI 区域行范围 0:250列范围 100:250将截取的 ROI 精准粘贴到右下角行 250:500列 250:400在图像右上角区域做随机噪声马赛克打码将最终处理后的彩色图转成灰度图并保存到本地同时显示处理后的彩色图和灰度图思路拆解用到的知识点依次是图像读取 → resize 缩放 → 数组切片裁剪 → 区域粘贴赋值 → 随机像素马赛克 → 色彩空间转换 → 图像保存 → 多窗口显示。import cv2 import numpy as np # 1. 读取原图统一缩放到500×500注意参数是宽,高 img cv2.imread(bird.png) img cv2.resize(img, (500, 500)) # 2. 截取左上角ROI区域粘贴到右下角对应位置 # 截取行0-250列100-250尺寸为250行×150列 roi img[0:250, 100:250] # 粘贴行250-500列250-400和截取区域尺寸完全一致 img[250:500, 250:400] roi # 3. 右上角区域马赛克打码行50-150列350-450100×100区域 img[50:150, 350:450] np.random.randint(0, 256, (100, 100, 3)) # 4. 彩色图转灰度图并保存到本地 gray_result cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) cv2.imwrite(bird_gray_result.png, gray_result) # 5. 同时显示处理后的彩色图和灰度图 cv2.imshow(处理后彩色图, img) cv2.imshow(最终灰度图, gray_result) cv2.waitKey(0) cv2.destroyAllWindows()十、入门核心知识点汇总