OpenCV 图像操作六件套:读取、裁剪、缩放、旋转、通道分割与保存
OpenCV 图像处理课程 · 第 2 章「Image Operation」学习笔记
环境:Python 3.10 + opencv-python 4.5.5.64 + PyCharm Community
包含 6 课:读取 / 裁剪 / 缩放 / 旋转 / 通道分割 / 保存
章节总览
| 课 | 主题 | 核心函数 | 时长 |
|---|---|---|---|
| 01 | 图像读取 | cv2.imread() / cv2.imshow() / cv2.waitKey() |
11:32 |
| 02 | 图像裁剪 | 数组切片 img[y1:y2, x1:x2] |
09:02 |
| 03 | 图像缩放 | cv2.resize() |
05:35 |
| 04 | 图像旋转 | cv2.rotate() |
05:25 |
| 05 | 通道分割 | cv2.split() |
04:25 |
| 06 | 图像保存 | cv2.imwrite() |
03:48 |
六种操作的完整链路:
#mermaid-svg-to9tQJxzKBkAM1YD{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-to9tQJxzKBkAM1YD .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-to9tQJxzKBkAM1YD .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-to9tQJxzKBkAM1YD .error-icon{fill:#552222;}#mermaid-svg-to9tQJxzKBkAM1YD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-to9tQJxzKBkAM1YD .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-to9tQJxzKBkAM1YD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-to9tQJxzKBkAM1YD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-to9tQJxzKBkAM1YD .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-to9tQJxzKBkAM1YD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-to9tQJxzKBkAM1YD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-to9tQJxzKBkAM1YD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-to9tQJxzKBkAM1YD .marker.cross{stroke:#333333;}#mermaid-svg-to9tQJxzKBkAM1YD svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-to9tQJxzKBkAM1YD p{margin:0;}#mermaid-svg-to9tQJxzKBkAM1YD .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-to9tQJxzKBkAM1YD .cluster-label text{fill:#333;}#mermaid-svg-to9tQJxzKBkAM1YD .cluster-label span{color:#333;}#mermaid-svg-to9tQJxzKBkAM1YD .cluster-label span p{background-color:transparent;}#mermaid-svg-to9tQJxzKBkAM1YD .label text,#mermaid-svg-to9tQJxzKBkAM1YD span{fill:#333;color:#333;}#mermaid-svg-to9tQJxzKBkAM1YD .node rect,#mermaid-svg-to9tQJxzKBkAM1YD .node circle,#mermaid-svg-to9tQJxzKBkAM1YD .node ellipse,#mermaid-svg-to9tQJxzKBkAM1YD .node polygon,#mermaid-svg-to9tQJxzKBkAM1YD .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-to9tQJxzKBkAM1YD .rough-node .label text,#mermaid-svg-to9tQJxzKBkAM1YD .node .label text,#mermaid-svg-to9tQJxzKBkAM1YD .image-shape .label,#mermaid-svg-to9tQJxzKBkAM1YD .icon-shape .label{text-anchor:middle;}#mermaid-svg-to9tQJxzKBkAM1YD .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-to9tQJxzKBkAM1YD .rough-node .label,#mermaid-svg-to9tQJxzKBkAM1YD .node .label,#mermaid-svg-to9tQJxzKBkAM1YD .image-shape .label,#mermaid-svg-to9tQJxzKBkAM1YD .icon-shape .label{text-align:center;}#mermaid-svg-to9tQJxzKBkAM1YD .node.clickable{cursor:pointer;}#mermaid-svg-to9tQJxzKBkAM1YD .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-to9tQJxzKBkAM1YD .arrowheadPath{fill:#333333;}#mermaid-svg-to9tQJxzKBkAM1YD .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-to9tQJxzKBkAM1YD .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-to9tQJxzKBkAM1YD .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-to9tQJxzKBkAM1YD .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-to9tQJxzKBkAM1YD .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-to9tQJxzKBkAM1YD .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-to9tQJxzKBkAM1YD .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-to9tQJxzKBkAM1YD .cluster text{fill:#333;}#mermaid-svg-to9tQJxzKBkAM1YD .cluster span{color:#333;}#mermaid-svg-to9tQJxzKBkAM1YD div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-to9tQJxzKBkAM1YD .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-to9tQJxzKBkAM1YD rect.text{fill:none;stroke-width:0;}#mermaid-svg-to9tQJxzKBkAM1YD .icon-shape,#mermaid-svg-to9tQJxzKBkAM1YD .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-to9tQJxzKBkAM1YD .icon-shape p,#mermaid-svg-to9tQJxzKBkAM1YD .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-to9tQJxzKBkAM1YD .icon-shape .label rect,#mermaid-svg-to9tQJxzKBkAM1YD .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-to9tQJxzKBkAM1YD .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-to9tQJxzKBkAM1YD .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-to9tQJxzKBkAM1YD :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 图像文件
horse.jpg
cv2.imread()
读入为数组
裁剪 imgy1:y2, x1:x2
数组切片
缩放 cv2.resize()
(宽, 高)
旋转 cv2.rotate()
90°倍数
通道分割 cv2.split()
B/G/R 三通道
cv2.imwrite()
保存到磁盘
cv2.imshow() 显示
- waitKey() 保持
共同代码模板:每个文件开头都是
pythonimport cv2 image_path = "../data/horse.jpg" image = cv2.imread(image_path)本文示例图像为
horse.jpg,shape(360, 540, 3)。
第 1 课 · 图像读取(Image Read)
目标
从电脑读取一张图像文件,并在 OpenCV 窗口(named window)中显示。
支持的文件格式
.jpg、.png、.bmp 等(OpenCV 支持多种图像格式)。
读取流程
图像路径 → cv2.imread() → 图像数组 → cv2.imshow() → 窗口显示
完整代码
python
import cv2
image_path = "D:/opencv_tutorial/data/horse.jpg"
image = cv2.imread(image_path)
print(image) # 打印图像数组
print(image.shape) # (360, 540, 3)
cv2.imshow("display image", image) # 窗口显示图像
cv2.waitKey(0) # 保持窗口
cv2.destroyAllWindows() # 关闭窗口
要点
- 图像存为数组 :
print(image)输出的是多层嵌套的像素数组(BGR 值) - shape :
(高度, 宽度, 通道数)=(360, 540, 3),3 通道即 BGR 彩色- 与 Windows 文件属性核对:宽 540 像素、高 360 像素,一致
- 窗口显示 :
cv2.imshow("窗口名", 图像) - 让窗口停留 :
cv2.waitKey(毫秒)- 传
5000→ 显示 5 秒后自动关闭 - 传
0→ 无限期等待,直到手动点窗口关闭按钮
- 传
- 关闭窗口 :
cv2.destroyAllWindows()(销毁内存中所有打开窗口)
imread 的 flags 参数(可选)
| 参数 | 效果 | shape |
|---|---|---|
| 默认(ImreadColor=1) | 读为彩色图(BGR 3 通道) | (360, 540, 3) |
0(ImreadGrayScale) |
读为灰度图(无通道信息) | (360, 540) |
灰度模式下 shape 只有 2 维,无通道维度。
第 2 课 · 图像裁剪(Image Crop)
什么是裁剪
从原图中截取一个矩形区域。
完整代码
python
import cv2
image_path = "../data/horse.jpg"
image = cv2.imread(image_path)
x1 = 174
x2 = 474
y1 = 47
y2 = 313
img2_crop = image[y1:y2, x1:x2] # 按行(高度y)、列(宽度x)切片
cv2.imshow("original image", image)
cv2.imshow("display image", img2_crop)
cv2.waitKey(0)
cv2.destroyAllWindows()
要点
- 裁剪 = 数组切片 :
image[y1:y2, x1:x2]- 第一维
y(行/高度),第二维x(列/宽度)
- 第一维
- 切片区间遵循 Python:
[start, end),即包含y1不包含y2 - 本课裁出马匹区域:
y 47~313、x 174~474
#mermaid-svg-Stz1vGklJdXloPxb{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Stz1vGklJdXloPxb .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Stz1vGklJdXloPxb .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Stz1vGklJdXloPxb .error-icon{fill:#552222;}#mermaid-svg-Stz1vGklJdXloPxb .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Stz1vGklJdXloPxb .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Stz1vGklJdXloPxb .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Stz1vGklJdXloPxb .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Stz1vGklJdXloPxb .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Stz1vGklJdXloPxb .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Stz1vGklJdXloPxb .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Stz1vGklJdXloPxb .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Stz1vGklJdXloPxb .marker.cross{stroke:#333333;}#mermaid-svg-Stz1vGklJdXloPxb svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Stz1vGklJdXloPxb p{margin:0;}#mermaid-svg-Stz1vGklJdXloPxb .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Stz1vGklJdXloPxb .cluster-label text{fill:#333;}#mermaid-svg-Stz1vGklJdXloPxb .cluster-label span{color:#333;}#mermaid-svg-Stz1vGklJdXloPxb .cluster-label span p{background-color:transparent;}#mermaid-svg-Stz1vGklJdXloPxb .label text,#mermaid-svg-Stz1vGklJdXloPxb span{fill:#333;color:#333;}#mermaid-svg-Stz1vGklJdXloPxb .node rect,#mermaid-svg-Stz1vGklJdXloPxb .node circle,#mermaid-svg-Stz1vGklJdXloPxb .node ellipse,#mermaid-svg-Stz1vGklJdXloPxb .node polygon,#mermaid-svg-Stz1vGklJdXloPxb .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Stz1vGklJdXloPxb .rough-node .label text,#mermaid-svg-Stz1vGklJdXloPxb .node .label text,#mermaid-svg-Stz1vGklJdXloPxb .image-shape .label,#mermaid-svg-Stz1vGklJdXloPxb .icon-shape .label{text-anchor:middle;}#mermaid-svg-Stz1vGklJdXloPxb .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Stz1vGklJdXloPxb .rough-node .label,#mermaid-svg-Stz1vGklJdXloPxb .node .label,#mermaid-svg-Stz1vGklJdXloPxb .image-shape .label,#mermaid-svg-Stz1vGklJdXloPxb .icon-shape .label{text-align:center;}#mermaid-svg-Stz1vGklJdXloPxb .node.clickable{cursor:pointer;}#mermaid-svg-Stz1vGklJdXloPxb .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Stz1vGklJdXloPxb .arrowheadPath{fill:#333333;}#mermaid-svg-Stz1vGklJdXloPxb .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Stz1vGklJdXloPxb .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Stz1vGklJdXloPxb .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Stz1vGklJdXloPxb .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Stz1vGklJdXloPxb .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Stz1vGklJdXloPxb .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Stz1vGklJdXloPxb .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Stz1vGklJdXloPxb .cluster text{fill:#333;}#mermaid-svg-Stz1vGklJdXloPxb .cluster span{color:#333;}#mermaid-svg-Stz1vGklJdXloPxb div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Stz1vGklJdXloPxb .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Stz1vGklJdXloPxb rect.text{fill:none;stroke-width:0;}#mermaid-svg-Stz1vGklJdXloPxb .icon-shape,#mermaid-svg-Stz1vGklJdXloPxb .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Stz1vGklJdXloPxb .icon-shape p,#mermaid-svg-Stz1vGklJdXloPxb .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Stz1vGklJdXloPxb .icon-shape .label rect,#mermaid-svg-Stz1vGklJdXloPxb .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Stz1vGklJdXloPxb .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Stz1vGklJdXloPxb .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Stz1vGklJdXloPxb :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} imagey1:y2, x1:x2
y 47~313, x 174~474
原图 (360, 540, 3)
裁剪图
马匹区域
第 3 课 · 图像缩放(Image Resize)
为什么需要缩放
深度学习模型(如 ResNet50 )要求固定尺寸输入(224×224)。若原图是 500×500 或任意尺寸,必须缩放到模型要求的尺寸才能送入。
完整代码
python
import cv2
image_path = "../data/horse.jpg"
image = cv2.imread(image_path)
image_resizing = cv2.resize(image, (400, 300)) # (宽, 高)
cv2.imshow("original image", image)
cv2.imshow("resize image", image_resizing)
cv2.waitKey(0)
cv2.destroyAllWindows()
要点
cv2.resize(图像, (width, height))- 参数是
(宽度, 高度),注意与image.shape的(高度, 宽度)相反
- 参数是
- 这是深度学习预处理中最常用的一步(统一输入尺寸)
第 4 课 · 图像旋转(Image Rotate)
什么是旋转
将图像沿顺时针或逆时针旋转 90° / 180° / 270°。
完整代码
python
import cv2
image_path = "../data/horse.jpg"
image = cv2.imread(image_path)
image_rotated = cv2.rotate(image, cv2.ROTATE_90_COUNTERCLOCKWISE)
cv2.imshow("rotated image", image_rotated)
cv2.waitKey(0)
cv2.destroyAllWindows()
旋转常量(cv2.rotate 第二参数)
| 常量 | 效果 |
|---|---|
cv2.ROTATE_90_CLOCKWISE |
顺时针 90° |
cv2.ROTATE_90_COUNTERCLOCKWISE |
逆时针 90° |
cv2.ROTATE_180 |
旋转 180° |
cv2.rotate()只支持 90° 的倍数旋转(90 / 180 / 270)。
第 5 课 · 通道分割(Image Split)
什么是 cv2.split
把一张 BGR 三通道图像拆分成独立的蓝、绿、红单通道,便于单通道分析。
完整代码
python
import cv2
image_path = "../data/horse.jpg"
image = cv2.imread(image_path)
blue, green, red = cv2.split(image) # 按 BGR 顺序解包
cv2.imshow("blue image", blue)
cv2.imshow("green image", green)
cv2.imshow("red image", red)
cv2.waitKey(0)
cv2.destroyAllWindows()
要点
cv2.split(image)返回 3 个单通道图像 ,按 B → G → R 顺序解包blue, green, red = cv2.split(image)
- 每个单通道显示为灰度图(单通道无颜色)
OpenCV 默认颜色顺序是 BGR(第 1 通道=蓝,第 2 通道=绿,第 3 通道=红)。
#mermaid-svg-O7e5JfGqZrXXaRBn{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-O7e5JfGqZrXXaRBn .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-O7e5JfGqZrXXaRBn .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-O7e5JfGqZrXXaRBn .error-icon{fill:#552222;}#mermaid-svg-O7e5JfGqZrXXaRBn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-O7e5JfGqZrXXaRBn .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-O7e5JfGqZrXXaRBn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-O7e5JfGqZrXXaRBn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-O7e5JfGqZrXXaRBn .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-O7e5JfGqZrXXaRBn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-O7e5JfGqZrXXaRBn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-O7e5JfGqZrXXaRBn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-O7e5JfGqZrXXaRBn .marker.cross{stroke:#333333;}#mermaid-svg-O7e5JfGqZrXXaRBn svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-O7e5JfGqZrXXaRBn p{margin:0;}#mermaid-svg-O7e5JfGqZrXXaRBn .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-O7e5JfGqZrXXaRBn .cluster-label text{fill:#333;}#mermaid-svg-O7e5JfGqZrXXaRBn .cluster-label span{color:#333;}#mermaid-svg-O7e5JfGqZrXXaRBn .cluster-label span p{background-color:transparent;}#mermaid-svg-O7e5JfGqZrXXaRBn .label text,#mermaid-svg-O7e5JfGqZrXXaRBn span{fill:#333;color:#333;}#mermaid-svg-O7e5JfGqZrXXaRBn .node rect,#mermaid-svg-O7e5JfGqZrXXaRBn .node circle,#mermaid-svg-O7e5JfGqZrXXaRBn .node ellipse,#mermaid-svg-O7e5JfGqZrXXaRBn .node polygon,#mermaid-svg-O7e5JfGqZrXXaRBn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-O7e5JfGqZrXXaRBn .rough-node .label text,#mermaid-svg-O7e5JfGqZrXXaRBn .node .label text,#mermaid-svg-O7e5JfGqZrXXaRBn .image-shape .label,#mermaid-svg-O7e5JfGqZrXXaRBn .icon-shape .label{text-anchor:middle;}#mermaid-svg-O7e5JfGqZrXXaRBn .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-O7e5JfGqZrXXaRBn .rough-node .label,#mermaid-svg-O7e5JfGqZrXXaRBn .node .label,#mermaid-svg-O7e5JfGqZrXXaRBn .image-shape .label,#mermaid-svg-O7e5JfGqZrXXaRBn .icon-shape .label{text-align:center;}#mermaid-svg-O7e5JfGqZrXXaRBn .node.clickable{cursor:pointer;}#mermaid-svg-O7e5JfGqZrXXaRBn .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-O7e5JfGqZrXXaRBn .arrowheadPath{fill:#333333;}#mermaid-svg-O7e5JfGqZrXXaRBn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-O7e5JfGqZrXXaRBn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-O7e5JfGqZrXXaRBn .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-O7e5JfGqZrXXaRBn .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-O7e5JfGqZrXXaRBn .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-O7e5JfGqZrXXaRBn .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-O7e5JfGqZrXXaRBn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-O7e5JfGqZrXXaRBn .cluster text{fill:#333;}#mermaid-svg-O7e5JfGqZrXXaRBn .cluster span{color:#333;}#mermaid-svg-O7e5JfGqZrXXaRBn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-O7e5JfGqZrXXaRBn .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-O7e5JfGqZrXXaRBn rect.text{fill:none;stroke-width:0;}#mermaid-svg-O7e5JfGqZrXXaRBn .icon-shape,#mermaid-svg-O7e5JfGqZrXXaRBn .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-O7e5JfGqZrXXaRBn .icon-shape p,#mermaid-svg-O7e5JfGqZrXXaRBn .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-O7e5JfGqZrXXaRBn .icon-shape .label rect,#mermaid-svg-O7e5JfGqZrXXaRBn .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-O7e5JfGqZrXXaRBn .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-O7e5JfGqZrXXaRBn .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-O7e5JfGqZrXXaRBn :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} cv2.split()
cv2.split()
cv2.split()
BGR 彩色图
(360, 540, 3)
Blue 通道
(360, 540)
Green 通道
(360, 540)
Red 通道
(360, 540)
第 6 课 · 图像保存(Image Save)
为什么需要保存
对图像做完处理(如旋转)后,想使用处理后的结果图,必须先保存到磁盘。本课以旋转后的图像为例保存。
完整代码
python
import cv2
image_path = "../data/horse.jpg"
image = cv2.imread(image_path)
img_rotate = cv2.rotate(image, cv2.ROTATE_90_COUNTERCLOCKWISE)
cv2.imwrite("rotated_image.jpg", img_rotate) # 保存图像
要点
cv2.imwrite(文件名, 图像)- 第一个参数:保存路径/文件名(含扩展名,如
.jpg) - 第二个参数:要保存的图像数组
- 第一个参数:保存路径/文件名(含扩展名,如
- 保存后可在项目目录看到
rotated_image.jpg(360×540 JPEG 24-bit)
本章小结(速查表)
| 操作 | 函数 / 语法 | 关键点 |
|---|---|---|
| 读图 | cv2.imread(path) |
flags 决定彩色/灰度 |
| 显示 | cv2.imshow(name, img) |
配 waitKey() 保持 |
| 等待 | cv2.waitKey(0) |
0=无限等待 |
| 关窗 | cv2.destroyAllWindows() |
收尾必备 |
| 裁剪 | img[y1:y2, x1:x2] |
数组切片 |
| 缩放 | cv2.resize(img, (w,h)) |
参数是(宽,高) |
| 旋转 | cv2.rotate(img, cv2.ROTATE_90_CW) |
90°倍数 |
| 分割 | cv2.split(img) |
返回B,G,R |
| 保存 | cv2.imwrite(name, img) |
处理后落盘 |
核心易错点
- BGR 顺序:OpenCV 图像通道是 BGR,不是 RGB
- shape vs resize 参数顺序 :
shape是(高, 宽),resize参数是(宽, 高) - 窗口要 waitKey :没有
cv2.waitKey(),窗口会一闪而过 - 路径反斜杠转正斜杠 :Python 路径用
/,Windows 反斜杠\会被当转义符