Opencv 基础常用API

创建和显示窗口相关函数

namedWindow()

功能 :创建一个显示图像的窗口。在调用 imshow() 之前,通常需要先用它创建一个窗口(如果不创建,imshow 会自动创建一个默认大小且不可调节的窗口)。

原型 :void namedWindow(const String& winname, int flags = WINDOW_AUTOSIZE);

  • parm1 (winname) :String 类型。窗口的名称(标识符)。后续的 imshow、resizeWindow 等函数都要通过这个名称来指定操作哪个窗口。

  • parm2 (flags) :int 类型。窗口的标志位,决定窗口的大小和显示方式。常用值:

    • WINDOW_AUTOSIZE (默认):窗口大小自动适应图片大小,用户不能手动改变窗口大小。

    • WINDOW_NORMAL:用户可以自由拖动改变窗口大小(在调试大分辨率图片时非常有用)。

    • WINDOW_OPENGL:支持 OpenGL 渲染。


imread()

功能 :从指定的文件路径中加载图像。

原型 :Mat imread(const String& filename, int flags = IMREAD_COLOR);

  • parm1 (filename) :String 类型。要读取的图像文件的路径(包括文件名和后缀)。

  • parm2 (flags) :int 类型。读取图像的颜色模式。常用值:

    • IMREAD_COLOR(默认值 1):始终将图像转换为 3 通道 BGR 彩色图像。

    • IMREAD_GRAYSCALE(值 0):始终将图像转换为单通道灰度图像。

    • IMREAD_UNCHANGED(值 -1):原样读取,保留 Alpha 透明通道。

  • 返回值 :返回一个 Mat(矩阵)对象。如果读取失败(如路径错误、文件损坏),则返回一个空矩阵(Python 中为 None)。

imshow()

功能 :在指定的窗口中显示图像。

原型 :void imshow(const String& winname, InputArray mat);

  • parm1 (winname) :String 类型。要显示图像的窗口的名称。如果该窗口尚未创建,OpenCV 会使用默认参数自动创建一个。

  • parm2 (mat) :InputArray 类型(通常传入 cv::Mat)。要显示的图像数据矩阵。


waitKey()

功能 :等待用户按键。极其重要! 它是 OpenCV 刷新 GUI 窗口事件队列的"触发器"。必须放在 imshow() 之后调用。

原型 :int waitKey(int delay = 0);

  • parm1 (delay) :int 类型。等待按键的时间(单位:毫秒)。

    • delay = 0:无限期等待,直到用户按下任意键。

    • delay > 0:等待指定毫秒数(如 30 表示约 30 FPS 的视频播放速度),如果期间没有按键则返回 -1,继续执行后续代码。

返回值 :int 类型。返回按下按键的 ASCII 码(例如 ESC 键是 27)。如果超时未按键则返回 -1。


resizeWindow()

功能 :改变指定窗口的大小。通常配合 WINDOW_NORMAL 标志使用。

原型 :void resizeWindow(const String& winname, int width, int height);

  • parm1 (winname) :String 类型。要调整大小的窗口名称。

  • parm2 (width, height) :int 类型。这里其实包含两个参数:

    • width:窗口的新宽度(像素)。

    • height:窗口的新高度(像素)。


imwrite()

功能 :将图像数据矩阵(Mat)保存为指定格式的图像文件。格式由文件名的后缀(如 .jpg, .png 等)决定。

原型 :bool imwrite(const String& filename, InputArray img, const std::vector<int>& params = std::vector<int>());

  • parm1 (filename) :String 类型。要保存的文件名(需包含扩展名,如 "output.jpg")。

  • parm2 (img) :InputArray 类型(通常传入 cv::Mat)。要保存的图像数据矩阵。

  • parm3 (params) :const std::vector<int>& 类型(可选)。特定格式的编码参数。通常不填。如果填,是一对对的键值对。例如保存为 JPEG 时,传入 {cv::IMWRITE_JPEG_QUALITY, 90} 表示压缩质量为 90%(0-100)。保存 PNG 时用 IMWRITE_PNG_COMPRESSION(0-9)。

  • 返回值 :bool 类型。保存成功返回 true,失败返回 false(例如路径不存在或权限不足)。


destroyAllWindows()

功能 :关闭所有由 OpenCV 创建的高层级 GUI 窗口(销毁并释放相关内存资源)。

原型 :void destroyAllWindows();


相关代码:
python 复制代码
import cv2
import sys

# 1. 读取图像(替换为你自己的图片路径)
# 默认读取为彩色图 (cv2.IMREAD_COLOR)
img = cv2.imread('test.jpg') 

# 检查图像是否读取成功
if img is None:
    print("无法读取图像,请检查路径是否正确!")
    sys.exit()

# 2. 创建窗口(自动适应图片大小)
cv2.namedWindow('new', cv2.WINDOW_AUTOSIZE)

# 3. 在窗口中显示图像
cv2.imshow('new', img)

# 4. 等待按键(0 表示无限期等待)
key = cv2.waitKey(0)

# 5. 判断按键(按 q 或 ESC 键退出)
# 注意:Python 中 waitKey 返回的是整数,需用 ord() 转换字符
if key == ord('q') or key == 27:
    sys.exit(0)

# 6. 销毁所有窗口,释放资源
cv2.destroyAllWindows()

cv2.VideoCapture() ------ 捕获视频源

作用: 它的作用是"打开"一个视频来源,既可以是你电脑上的视频文件,也可以是插在电脑上的 USB 摄像头。

  • 读取摄像头 :括号里填数字(通常 0 代表默认摄像头,外接的可能是 1 或 2)。

    复制代码
    cap = cv2.VideoCapture(0) 
  • 读取视频文件:括号里填视频的路径。

    复制代码
    cap = cv2.VideoCapture('my_video.mp4')

cap.read() ------ 读取一帧画面

作用: 从打开的视频源里,读取当前的一帧图像。视频本质上就是一张张快速播放的图片。

  • 返回值:它返回两个东西。

    • ret (Boolean):布尔值,表示有没有成功读到画面(比如视频播完了,或者摄像头没连好,就会返回 False)。

    • frame (NumPy数组):就是读到的这一帧图像。

    复制代码
    ret, frame = cap.read()

    💡 关键提醒 :通常我们会把它放进一个 while 循环里,这样就能不断读取,形成连续的视频流。如果 ret 是 False,循环就可以结束了。


cap.release() ------ 释放资源作用: 关闭视频文件,或者断开与摄像头的连接。

为什么重要:如果不写这一句,摄像头可能会一直被程序"占用",导致你退出程序后,其他软件(甚至下次你自己再运行代码)打不开摄像头,只能重启电脑才能解决。

复制代码
cap.release()

cv2.VideoWriter() ------ 创建视频写入器

作用: 创建一个对象,告诉程序"我要保存一个什么样的视频文件"。

  • 参数要求:它通常需要 4 个必填参数(有时还有第 5 个控制彩色/灰度)。

    1. 文件名 :比如 'output.avi' 或 'output.mp4'。

    2. 编码格式(FourCC) :告诉电脑用什么格式压缩视频。最常见的是 cv2.VideoWriter_fourcc(*'XVID') 或 (*'MJPG')。

    3. 帧率(FPS) :每秒播放多少张画面,比如 20 或 30。

    4. 画面尺寸 :必须是一个元组 (width, height)。⚠️核心避坑点:这个尺寸必须和你后面 write 进去的每一帧画面的尺寸一模一样,否则视频保存出来是坏的(只有几KB或无法播放)。

python 复制代码
# 设置编码器
fourcc = cv2.VideoWriter_fourcc(*'XVID')
# 创建写入器(保存为 output.avi,帧率 20,尺寸 640x480)
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480))

out.write() ------ 写入一帧

作用: 把具体的画面(图像/帧)按顺序塞进刚才创建的视频文件里。

  • 注意:它和文件操作里的 f.write() 类似,你要把当前处理好的 frame 传进去。
python 复制代码
out.write(frame)  # frame 必须是一个 NumPy 数组(图像)

out.release() ------ 释放资源

作用: 关闭文件并确保所有数据都完整地写入到了硬盘上。

  • 为什么重要:和摄像头一样,如果不写这句,视频文件可能只占用内存而没有真正写进硬盘,导致文件损坏或只有 0 字节。
python 复制代码
out.release()

相关代码:

python 复制代码
import cv2

# 1. 打开摄像头
cap = cv2.VideoCapture(0)

# 获取摄像头的实际分辨率(重要:防止尺寸不匹配导致保存失败)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# 2. 设置视频写入器 (注意这里用的是实际获取的 width 和 height)
fourcc = cv2.VideoWriter_fourcc(*'mjpg')
out = cv2.VideoWriter('my_record.avi', fourcc, 20.0, (width, height))

while True:
    # 读取一帧
    ret, frame = cap.read()
    if not ret:
        break

    # 显示出来
    cv2.imshow('Recording...', frame)
    
    # 3. 写入文件
    out.write(frame)

    # 按 ESC 退出
    if cv2.waitKey(1) == 27:
        break

# 4. 释放所有资源 (非常重要,顺序无所谓,但千万别漏)
cap.release()
out.release()
cv2.destroyAllWindows()
print("视频保存完毕!")

setMouseCallback()

功能 :为指定的窗口设置鼠标事件的回调函数。当用户在该窗口内进行鼠标操作(如点击、移动、双击等)时,OpenCV 会自动调用你设定的 callback 函数。

原型 :void setMouseCallback(const String& winname, MouseCallback onMouse, void* userdata = 0);

  • parm1 (winname) :String 类型。窗口的名称(必须与 namedWindow 创建的名称一致)。

  • parm2 (callback) :MouseCallback 类型。回调函数的函数名。必须符合特定的参数格式(见下方)。

  • parm3 (userdata) :void* 类型。传递给回调函数的用户自定义数据指针(默认传 0 或 NULL 即可,高级用法中可以传入结构体指针来共享数据)。


回调函数 callback() (自定义)

功能 :这是由开发者自己实现的一个函数。它不会主动运行,只有当鼠标在指定窗口发生动作时,才会被系统"回调"执行。

原型 :void onMouse(int event, int x, int y, int flags, void* userdata);

  • parm1 (event) :int 类型。鼠标事件的类型。常用值:

    • EVENT_MOUSEMOVE (0):鼠标移动。

    • EVENT_LBUTTONDOWN (1):鼠标左键按下。

    • EVENT_RBUTTONDOWN (2):鼠标右键按下。

    • EVENT_LBUTTONUP (4):鼠标左键松开。

    • EVENT_LBUTTONDBLCLK (7):鼠标左键双击。

  • parm2 (x) :int 类型。鼠标当前在窗口图像坐标系中的 X 坐标(列)。

  • parm3 (y) :int 类型。鼠标当前在窗口图像坐标系中的 Y 坐标(行)。

  • parm4 (flags) :int 类型。鼠标事件的标志位,通常用于判断是否有组合键(如 EVENT_FLAG_SHIFTKEY、EVENT_FLAG_CTRLKEY)或哪个按键被按下。

  • parm5 (userdata) :void* 类型。接收来自 setMouseCallback 传递进来的用户数据指针。


示例代码

python 复制代码
import cv2
import numpy as np

# 全局变量记录点击坐标
pt = (-1, -1)

# 鼠标回调函数
def mouse_callback(event, x, y, flags, userdata):
    global pt
    # 如果发生左键按下事件
    if event == cv2.EVENT_LBUTTONDOWN:
        pt = (x, y)
        print(f"点击坐标: {pt}, 传入的自定义数据: {userdata}")

# 创建窗口
cv2.namedWindow('mouse', cv2.WINDOW_NORMAL)
cv2.resizeWindow('mouse', 640, 360)

# 设置鼠标回调
cv2.setMouseCallback('mouse', mouse_callback, "123")

# 显示窗口和背景
img = np.zeros((360, 640, 3), np.uint8)

while True:
    # 如果有点击过,在点击位置画一个红色的实心圆(起到可视化反馈的作用)
    if pt != (-1, -1):
        cv2.circle(img, pt, 10, (0, 0, 255), -1)
        
    cv2.imshow('mouse', img)
    key = cv2.waitKey(1) # 等待 1ms,用于刷新界面和监听键盘
    
    # 补充退出逻辑:如果按下 ESC 键(ASCII 码为 27)则退出
    if key == 27:
        break

# 退出后销毁窗口
cv2.destroyAllWindows()

createTrackbar()

功能 :在指定的窗口上创建一个滑动条(滑块)。常用于实时调整算法参数(如二值化阈值、Canny 的高低阈值等),无需每次重新编译代码。

原型 :int createTrackbar(const String& trackbarname, const String& winname, int* value, int count, TrackbarCallback onChange = 0, void* userdata = 0);

  • parm1 (trackbarname) :String 类型。滑动条的名称(显示在滑块旁边)。

  • parm2 (winname) :String 类型。滑动条依附的窗口名称(必须与 namedWindow 创建的名称一致)。

  • parm3 (value) :int* 类型(指针)。极其重要! 这是一个指向整型变量的指针,滑块当前的数值会实时同步到这个变量里。(在 Python 中没有指针,通常传入一个初始值,并在回调函数中获取)。

  • parm4 (count) :int 类型。滑动条的最大值(最小值永远是 0)。

  • parm5 (onChange) :TrackbarCallback 类型(可选)。滑动条数值改变时触发的回调函数。如果设为 0 或 None,则不会触发任何函数(Python 中必须传,否则无法获取实时值)。

  • parm6 (userdata) :void* 类型(可选)。传递给回调函数的用户数据指针。


getTrackbarPos()

功能 :获取指定窗口上指定滑动条的当前数值。

原型 :int getTrackbarPos(const String& trackbarname, const String& winname);

  • parm1 (trackbarname) :String 类型。要获取数值的滑动条名称。

  • parm2 (winname) :String 类型。滑动条所在的窗口名称。

  • 返回值 :int 类型。返回当前滑块指示的数值。


示例代码:

python 复制代码
import cv2
import numpy as np

def callback():
    pass

cv2.namedWindow('trackbar', cv2.WINDOW_NORMAL)

cv2.createTrackbar('R', 'trackbar', 0, 255, callback)
cv2.createTrackbar('G', 'trackbar', 0, 255, callback)
cv2.createTrackbar('B', 'trackbar', 0, 255, callback)

img = np.zeros((480, 640, 3), np.uint8)

while True:
    cv2.imshow('trackbar', img)

    r = cv2.getTrackbarPos('R', 'trackbar')
    g = cv2.getTrackbarPos('G', 'trackbar')
    b = cv2.getTrackbarPos('B', 'trackbar')

    img[:] = [b, g, r]
    key = cv2.waitKey(10)
    if key & 0xFF == ord('q'):
        break

cv2.destroyAllWindows()

色彩空间转换

cv2.cvtColor(src, code)

  • 作用:把图像从一个色彩空间转换到另一个色彩空间。

  • src:输入图像(通常是 NumPy 数组)。

  • code:转换代码(就是你列表里的那些常量)。

  • 注意:转换后的图像,通道数和数据类型可能会变。比如 BGR 转 GRAY(灰度),通道数会从 3 变成 1;BGR 转 HSV,通道数还是 3,但数值范围变了。


示例代码:

python 复制代码
import cv2

def callback():
    pass

cv2.namedWindow('color', cv2.WINDOW_NORMAL)

img =  cv2.imread('./picture/rmb.jpg')

colorspaces = [cv2.COLOR_BGR2RGB, cv2.COLOR_BGR2GRAY,
               cv2.COLOR_BGR2HSV, cv2.COLOR_BGR2YUV]

cv2.createTrackbar('curcolor', 'color', 0, 3, callback)
while True:
    index = cv2.getTrackbarPos('curcolor', 'color')

    #颜色空间转换API
    cvt_img = cv2.cvtColor(img, colorspaces[index])

    cv2.imshow('color', cvt_img)
    key = cv2.waitKey(10)
    print(key)
    if key & 0xFF == ord('q'):
        break
cv2.destroyAllWindows()

numpy 创建特殊矩阵的操作

Array(通用数组)

  • 概念:把一串普通的数字(或者嵌套的列表),按照你指定的行列结构,转换成一个可以进行数学运算的二维或多维矩阵。

  • 在视觉中的意义 :这是图像在计算机里的真实面目。

    • 当你用 OpenCV 读取一张图片时,它返回的就是一个巨大的 Array(数组)。

    • 如果你手动输入一堆数字构成一个 Array,它就可以被当作一张小尺寸的图片来处理。

    • 前几个(Zero, One, Full)都是自动批量生成 特定数值的 Array;而 Array 函数是你手动填入具体数值来构建矩阵。

Zero(零矩阵/全零数组)

  • 概念 :所有元素的值全是 0。

  • 在视觉中的意义 :代表**"什么都没有"**。在图像里,0 通常代表纯黑色;在掩膜(Mask)里,0 代表遮罩、不显示。它是极其常用的"初始画布"。

One(全一矩阵/全一数组)

  • 概念 :所有元素的值全是 1。

  • 在视觉中的意义 :代表**"基础单位"** 或**"全亮"**。在数学里,它是计算的基础;在图像处理里,如果把它乘上 255,就会变成一张纯白色的图;它也常被用作滤波器(卷积核)的基础模板。

Full(自定义填充矩阵)

  • 概念 :所有元素的值全是你指定的任意数值。

  • 在视觉中的意义 :它是 Zero 和 One 的升级版。如果你想要一张纯灰色的背景(填充 128),或者一张特定颜色的图片(比如每个像素的 BGR 都是 255, 0, 0),就用它来快速生成一张底色图。

Identity(单位矩阵)

  • 概念 :一个正方形 的矩阵。它的特征是:从左上角到右下角的主对角线上全是 1,其余所有位置全是 0。

  • 在视觉中的意义 :数学里的"数字 1"。任何矩阵乘以它,都等于它本身。在图像处理中,它常代表**"原封不动"**(比如在坐标变换时,代表没有任何平移、缩放或旋转的初始状态)。

Eye(对角线矩阵)

  • 概念 :它是 Identity 的"灵活版"。它不仅也能生成主对角线为 1 的方阵,还能生成非正方形 的矩阵,或者让那一排 1 发生偏移(不在正中间,而是偏左上或偏右下)。

  • 在视觉中的意义:主要用于更复杂的数学运算。比如你在做图像的特征提取、坐标映射时,需要用到带有偏移量的数学结构,它就能派上用场。


示例代码:

python 复制代码
import cv2

# 1. 读取图片
img = cv2.imread('./picture/rmb.jpg')

if img is None:
    print("图片读取失败,请检查路径!")
    exit()

# 2. 读值:打印坐标 (100, 100) 处的 BGR 像素值
# 注意:OpenCV 的坐标是 [y, x](先行后列)
print("坐标 (100, 100) 的 BGR 值为:", img[100, 100])

# 3. 写值:修改矩阵中的像素
# 这里用你截图里的逻辑,但为了保证不管图片多大都不会报错,我们改画一个 100x100 的正方形
# 把这个区域全部赋值为 [0, 0, 255](纯红色)
img[0:100, 100:200] = [0, 0, 255] 

# 4. 显示修改后的图片
cv2.imshow('img', img)
key = cv2.waitKey(0) # 无限等待,直到用户按键

if key & 0xFF == ord('q'):
    cv2.destroyAllWindows()

numpy ROI

. 获取子矩阵(划出 ROI 区域)

  • 概念:利用 NumPy 的切片功能,从原图中"框"出一个感兴趣的区域(Region of Interest)。

  • 意义 :这是做图像处理的起点。你不需要处理整张图,只把注意力集中在局部(比如车牌、人脸、特定物体)。注意,它默认是视图,修改它会直接改变原图。

  • 对应代码:

    复制代码
    roi = img[100:400, 100:600]

2. 整个区域填充(涂色)

  • 概念 :把当前矩阵(ROI)里的所有行(:)、所有列(:)的像素,全部替换为指定的 BGR 颜色。

  • 意义:常用于打码(隐私遮挡)、画实心图形,或者给某个特定区域换背景色。

    这里的 [:, :] 代表把这个子矩阵"掏空涂满"。

  • 对应代码:

    复制代码
    roi[:, :] = [0, 0, 255]  # 把刚才切出来的长方形全涂成红色

3. 提取单个通道(切片进阶)

  • 概念 :在已有的 ROI 矩阵基础上,通过第三个维度的索引(0、1、2)单独提取某一个颜色通道。

  • 意义:分离 B、G、R 通道,用来做颜色过滤、阈值分割,或者单独分析某个颜色的强度。

  • 对应代码:

    复制代码
    # 提取 roi 里的第一个通道(OpenCV里0代表Blue通道)
    blue_channel = roi[:, :, 0] 

4. 局部嵌套切片(画中画)

  • 概念 :在已切好的子矩阵 roi 中,再次使用切片 [y1:y2, x1:x2] 划定一个更小的范围进行赋值。

  • 意义:实现精准的局部修改,比如在一大块红色区域里,再画一个绿色的实心小方块。

  • 对应代码:

    复制代码
    # 在刚才的红底 ROI 里,再切出一块小正方形,涂成绿色
    roi[10:200, 10:200] = [0, 255, 0]

示例代码:

python 复制代码
import cv2
import numpy as np

# 1. 创建一张 600x800 的纯白画布作为底图 (代替你读取的图片,方便直接跑)
img = np.full((600, 800, 3), 255, dtype=np.uint8)

# ================= 核心代码区 =================

# ① 划出 ROI 区域:从 Y=100 到 400,X=100 到 600
roi = img[100:400, 100:600]

# ② 整体填充:把这块 ROI 全部涂成红色 (BGR: 0,0,255)
roi[:] = [0, 0, 255]

# ③ 嵌套涂色:在红色的 ROI 里面,再切出 Y=10到100,X=10到100 的小块,涂成绿色 (BGR: 0,255,0)
roi[10:100, 10:100] = [0, 255, 0]

# ④ 提取单通道:把整个大图的蓝色通道单独拿出来(验证切片原理,这步不改变图像,只是拿出来看)
blue_channel = img[:, :, 0] 

# ================= 核心代码结束 =================

# 显示图像
cv2.namedWindow('Result', cv2.WINDOW_NORMAL)
cv2.imshow('Result', img)  # 此时原图 img 上已经被画上了一大块红底绿方块!

key = cv2.waitKey(0)
if key & 0xFF == ord('q'):
    cv2.destroyAllWindows()

MAT

为:OpenCV 的图像/矩阵容器,由「矩阵头 + 数据指针」组成。

好处:

  • 自动内存管理:不用手动 malloc/free,引用计数自动释放。

  • 浅拷贝高效 :Mat B = A; 只复制头、共享数据,不拷贝像素。

  • 支持 ROI:可只引用图像局部区域,零拷贝。

  • 函数传参快 :传 Mat 不复制大数据。

需要独立副本时用 clone() 与 copyto() 深拷贝。

深浅拷贝:

相关推荐
FelixZhang0281 小时前
不懂金融或不会编程,如何开始量化?从策略搭建到回测验证
人工智能·python·算法·数学建模·均值算法·自然语言处理·金融
可乐ea1 小时前
Kimi K3.1 Pro 选型:1M 上下文和每任务成本怎么算
人工智能·计算机视觉·ai智能体·上下文窗口·大模型选型·kimik3.1pro·agent成本
Dawson Zhu1 小时前
【AI编译器入门③】编译前端:ONNX、TorchScript与动态shape处理
人工智能·语言模型·架构·aigc·agi
愤怒火龙果1 小时前
AI攻防 AIRT05-AI Supply Chain and Infrastructure Attacks
人工智能·ai安全
Yan-英杰1 小时前
手机/平板远控电脑哪个好用?ToDesk、向日葵、TeamViewer 六大维度实测对比
人工智能·智能手机·电脑·teamviewer·ai开发工具
Solange__1 小时前
AI模型编辑器、Blender和3D Agent怎么选?按5类修改任务比较局部编辑、拓扑与自动化
人工智能·3d·自然语言处理·编辑器·音视频·blender·游戏策划
lucas_AI1 小时前
为什么大模型总敢一本正经地胡说?研究者关掉了它脑内的 8 个「自信开关」
人工智能·llm
Dovis(誓平步青云)1 小时前
切换语言后按钮被截断,本地化审计怎样发现长度风险
开发语言·前端·javascript·人工智能·机器学习·华为·harmonyos
科起点AI1 小时前
初稿写作指南:用科起点AI从文献阅读到初稿生成
人工智能·aigc·ai写作