OpenCV 图像操作六件套:读取、裁剪、缩放、旋转、通道分割与保存

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() 保持

共同代码模板:每个文件开头都是

python 复制代码
import 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~313x 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) 处理后落盘

核心易错点

  1. BGR 顺序:OpenCV 图像通道是 BGR,不是 RGB
  2. shape vs resize 参数顺序shape(高, 宽)resize 参数是 (宽, 高)
  3. 窗口要 waitKey :没有 cv2.waitKey(),窗口会一闪而过
  4. 路径反斜杠转正斜杠 :Python 路径用 /,Windows 反斜杠 \ 会被当转义符
相关推荐
小小帅呀1 小时前
学习 VLA 第 1 天:VLA 概述与学习路线
人工智能
TechEdu2026061 小时前
[人工智能]Claude(Anthropic):模型能力、智能体与安全工程实践
人工智能·ai
pjj198541 小时前
opencv-图像透视转换
人工智能·opencv·计算机视觉
aneasystone本尊1 小时前
学习大模型推理的分词:从文本到 Token
人工智能
浪兎兎1 小时前
【深度学习】(四)案例:基于PyTorch的全连接神经网络实现手机价格区间预测
pytorch·深度学习·神经网络
桐桐桐1 小时前
Python 实战:批量生成带来源参数的 WhatsApp 短链 + 二维码
服务器·数据库·python·前端框架·ip·跨境电商·独立站
牧羊人.3331 小时前
计算机视觉基础 第 11 章| 特征检测与特征匹配
图像处理·人工智能·opencv·计算机视觉
TheBestRucy1 小时前
Python 九阳神功之肆:网络编程 · Socket 从入门到实战
开发语言·网络·python
艾莉丝努力练剑1 小时前
【AI大模型接入SDK】项目的数据结构设计
数据结构·人工智能·大模型·sdk·文件系统·岗位