目录
一.OpenCV介绍
1.基本定位与用途
2.与Python的联系
3.环境安装
二.图像表示
三.图像存储
四.彩色图像
五.图像操作
1.创造窗体
2.读取图像
3.显示图像
4.保存图像
5.创建黑白图像
6.图像切片
7.图像调整大小
六.图像绘制
1.绘制直线
2.绘制图片
3.绘制矩形
4.绘制文本
5.读取视频
定位:跨平台的计算机视觉库,支持 C++、Python、Java 等语言,提供大量计算机视觉算法与工具。
用途:广泛用于图像处理、目标检测、图像分割、人脸识别、姿态估计、视频分析(如行为识别、运动跟踪 )等场景,在计算机视觉科研与工程实践中应用极广。
与 NumPy 等科学计算库无缝集成,可通过 Python 简洁的代码调用 OpenCV 中图像读取、处理(如滤波、边缘检测)、特征提取、目标识别等核心功能,快速实现计算机视觉应用,无需深入底层 C/C++ 实现细节,降低了开发门槛,让 OpenCV 的强大功能更易被广泛使用。
numpy:
pip install numpy==1.26.0 -i https://pypi.tuna.tsinghua.edu.cn/simple/
OpenCV:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python
像素是图像的基本单元,每个像素存储着图像的颜色、亮度和其他特征。一系列像素组合到一起就形成了完整的图像,在计算机中,图像以像素的形式存在并采用二进制格式进行存储。根据图像的颜色不同,每个像素可以用不同的二进制数表示。
日常生活中常见的图像是RGB三原色图。RGB图上的每个点都是由红(R)、绿(G)、蓝(B)三个颜色按照一定比例混合而成的,几乎所有颜色都可以通过这三种颜色按照不同比例调配而成。在计算机中,RGB三种颜色被称为RGB三通道,每个通道的取值都是0-255,根据这三个通道存储的像素值,来对应不同的颜色。
在OpenCV中,无论是读取还是创建图像,结果都是一个NumPy数组。
彩色图像:三维数组
灰度图像:二维
图像本质上是像素值的二维或三维矩阵(对于彩色图像)
形状(Shape):图像的尺寸由其高(height)、宽(width)和通道数(channels)决定。可以通过img.shape
属性获取这些信息。
对于彩色图像(如RGB),返回的是一个包含三个值的元组 (height, width, channels)。对于灰度图像,返回的是一个包含两个值的元组 (height, width),因为灰度图像只有一个通道。
数据类型(dtype):图像中的每个像素值的数据类型决定了可以存储的最大值。例如,8位无符号整数(uint8)允许的范围是从0到255。
像素表示
单通道图像(灰度图像):每个像素由一个数值表示,代表该点的亮度。值越低(接近0),颜色越暗;值越高(接近255),颜色越亮。多通道图像(彩色图像): 在OpenCV中,默认情况下,彩色图像是以BGR(蓝-绿-红)顺序存储。
import cv2 as cv
# 读取图像 cv.imread(path,读取方式) 默认读为彩色图
cat=cv.imread("../images/(读取的图像名)")
print(cat)
print(cat.shape) # (h,w,c) 元组 (1,)
print(cat.dtype) # np.uint8
# 读为灰度图
cat1=cv.imread("../images/读取的图像名",cv.IMREAD_GRAYSCALE)
print(cat1)
print(cat1.shape) # (h,w)
# 保存图像 cv.imwrite(path,img)
cv.imwrite("./gray.jpg",cat1)
# 显示图像 cv.imshow(window,img)
cv.imshow("myimg",cat)
cv.imshow("cat",cat1)
# 留下绘制时间,cv.waitKey(n) 等待n毫秒 40:40毫秒后关闭窗口 0:表示一直等待
cv.waitKey(0)
# 释放资源
cv.destroyAllWindows()
RGB 颜色空间:是最常见的颜色模型,代表红色(Red)、绿色(Green)和蓝色(Blue),这三种颜色通过不同强度的光的组合来创建其他颜色。在 OpenCV 中,默认情况下彩色图像是以 BGR(蓝 - 绿 - 红)顺序存储的,每个通道的取值范围是 0-255。
HSV 颜色空间:更接近人类对颜色的感知,H 表示色调(Hue),表示颜色的种类;S 表示饱和度(Saturation),表示颜色的纯度或强度;V 表示明度(Value),表示颜色的明暗程度。
Lab 颜色空间:是一种均匀颜色空间,它的亮度通道(L)与颜色通道(a 和 b)是分离的,常用于颜色处理和图像分析,在某些情况下比 RGB 颜色空间更适合进行颜色相关的操作。
cv2.namedWindow () 函数
在 OpenCV 中,cv2.namedWindow()
函数用于创建一个可以显示图像的窗口。窗口可以是固定大小的,也可以调整大小以适应显示的图像。
cv2.namedWindow(winname[, flags])
参数说明:
winname
:窗口的名称,作为窗口的唯一标识符,类型为字符串。
flags
:窗口的属性标志,可选参数,默认值为cv2.WINDOW_AUTOSIZE
。
窗口属性标志
flags
参数有以下几种常用值:
cv2.WINDOW_NORMAL:窗口可以调整大小。
cv2.WINDOW_AUTOSIZE:窗口大小会自动调整以适应显示的图像,用户无法手动调整。cv2.WINDOW_OPENGL:窗口支持 OpenGL。
cv2.WINDOW_FULLSCREEN:全屏显示窗口。
cv2.WINDOW_FREERATIO:图像比例可以自由调整。
cv2.WINDOW_KEEPRATIO:保持图像的比例。
示例:
import cv2
# 读取图像
image = cv2.imread('example.jpg') # 请替换为实际图像路径
# 创建一个可调整大小的窗口
cv2.namedWindow('Image Viewer', cv2.WINDOW_NORMAL)
# 在窗口中显示图像
cv2.imshow('Image Viewer', image)
# 等待按键事件
cv2.waitKey(0)
# 关闭所有窗口
cv2.destroyAllWindows()
cv2.imread(filename, flags=cv2.IMREAD_COLOR)
说明
filename:
必需参数,指定图像文件的路径(绝对或相对路径)。
支持的常见图像格式:JPEG、PNG、BMP、TIFF 等。
flags
(读取方式):可选参数,控制图像的读取模式。常用取值:
cv2.IMREAD_COLOR
(默认值,简写为1
)读取彩色图像,会忽略图像的透明度通道(Alpha)。
cv2.IMREAD_GRAYSCALE
(简写为0
)以灰度模式读取图像,返回单通道灰度图。
cv2.IMREAD_UNCHANGED
(简写为-1
)读取包含 Alpha 通道的原始图像(若图像有透明度信息)。
示例:
import cv2
# 1. 读取彩色图像(默认方式)
color_img = cv2.imread('example.jpg') # 等价于 cv2.imread('example.jpg', 1)
# 2. 读取灰度图像
gray_img = cv2.imread('example.jpg', cv2.IMREAD_GRAYSCALE) # 或 flags=0
# 3. 读取包含Alpha通道的图像(若存在)
rgba_img = cv2.imread('transparent.png', cv2.IMREAD_UNCHANGED) # 或 flags=-1
# 检查图像形状
print(f"彩色图像形状: {color_img.shape}") # 输出: (高度, 宽度, 3)
print(f"灰度图像形状: {gray_img.shape}") # 输出: (高度, 宽度)
print(f"RGBA图像形状: {rgba_img.shape}") # 输出: (高度, 宽度, 4)
cv2.imshow(winname, mat)
说明
winname
必需参数,指定显示图像的窗口名称(字符串类型)。若该窗口不存在,OpenCV 会自动创建一个新窗口;若已存在,则更新窗口内容。
mat
必需参数,要显示的图像数据,通常是一个numpy.ndarray
数组(通过cv2.imread()
读取或其他图像处理操作生成)。
显示图像的完整流程通常包含以下步骤:
读取图像(使用cv2.imread()
)
创建窗口(可选,使用cv2.namedWindow()
)
显示图像(使用cv2.imshow()
)
等待按键(使用cv2.waitKey()
)
关闭窗口(使用cv2.destroyAllWindows()
)
示例
简单显示彩色图像
import cv2
# 读取图像
img = cv2.imread('example.jpg') # 确保图像路径正确
# 显示图像(自动创建窗口)
cv2.imshow('Color Image', img)
# 等待用户按键(0表示无限等待)
cv2.waitKey(0)
# 关闭所有窗口
cv2.destroyAllWindows()
cv2.imwrite(filename, img, params=None)
说明
filename
必需参数,指定保存图像的路径(含文件名和扩展名)。支持的常见格式:JPEG(.jpg
/.jpeg
)、PNG(.png
)、BMP(.bmp
)、TIFF(.tiff
)等。
img
必需参数,要保存的图像数据(numpy.ndarray
类型)。
params
可选参数,用于指定特定格式的保存参数(如 JPEG 质量、PNG 压缩级别等)。
示例
JPG:
import cv2
# 读取图像
img = cv2.imread('input.jpg')
# 保存图像(默认质量)
cv2.imwrite('output.jpg', img)
# 保存图像(指定JPEG质量,0-100,数值越高质量越好)
cv2.imwrite('output_high_quality.jpg', img, [cv2.IMWRITE_JPEG_QUALITY, 90])
PNG
import cv2
# 读取图像并转为灰度
color_img = cv2.imread('input.jpg')
gray_img = cv2.cvtColor(color_img, cv2.COLOR_BGR2GRAY)
# 保存为PNG(默认压缩级别)
cv2.imwrite('output_gray.png', gray_img)
# 保存为PNG(指定压缩级别,0-9,数值越高文件越小)
cv2.imwrite('output_gray_compressed.png', gray_img, [cv2.IMWRITE_PNG_COMPRESSION, 3])
不同格式的保存参数通过params
列表指定:
格式 | 参数标志 | 取值范围 | 默认值 | 说明 |
---|---|---|---|---|
JPEG | cv2.IMWRITE_JPEG_QUALITY |
0-100(越高越好) | 95 | 控制 JPEG 图像的压缩质量 |
PNG | cv2.IMWRITE_PNG_COMPRESSION |
0-9(越高越小) | 3 | 控制 PNG 图像的压缩级别 |
WEBP | cv2.IMWRITE_WEBP_QUALITY |
0-100(越高越好) | 100 | 控制 WebP 图像的压缩质量 |
创建全黑图像
使用np.zeros()
创建一个指定尺寸和数据类型的数组,所有元素初始化为 0。对于图像来说,这代表全黑图像。
import numpy as np
import cv2
# 创建一个500x500的全黑彩色图像(3通道)
height, width = 500, 500
black_image = np.zeros((height, width, 3), dtype=np.uint8)
# 显示图像
cv2.imshow('Black Image', black_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
创建全白图像
将全黑图像的所有像素值设为 255(对于 8 位图像,255 代表最大亮度),即可得到全白图像。
# 方法1:创建全黑图像后修改所有像素值
white_image = black_image.copy() # 复制全黑图像
white_image[:, :] = 255 # 将所有像素的RGB值设为255
# 方法2:直接使用np.ones()创建全1数组,再乘以255
white_image_direct = np.ones((height, width, 3), dtype=np.uint8) * 255
# 显示图像
cv2.imshow('White Image', white_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
OpenCV 图像是一个numpy.ndarray
,其索引规则为:
行(Row):对应图像的y 坐标(垂直方向)
列(Column):对应图像的x 坐标(水平方向)
通道(Channel):彩色图像有 3 个通道(BGR),灰度图像只有 1 个通道
切片语法img[y:y+h, x:x+w]
表示:
从第y
行开始,到第y+h
行结束(不包含y+h
)
从第x
列开始,到第x+w
列结束(不包含x+w
)
示例
import cv2
# 读取图像
img = cv2.imread('example.jpg') # 替换为实际图像路径
# 定义切片区域(x,y,w,h)
x, y, w, h = 100, 50, 200, 150 # 从(100,50)开始,宽200,高150
# 执行切片(剪裁)
roi = img[y:y+h, x:x+w] # ROI: Region of Interest
# 显示原图和切片
cv2.imshow('Original Image', img)
cv2.imshow('Cropped ROI', roi)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 保存切片
cv2.imwrite('cropped_roi.jpg', roi)
cv2.resize()
cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])
说明:
src:输入图像,通常为 NumPy 数组(如uint8
类型)
dsize:输出图像尺寸,格式为(宽度, 高度)
的元组
fx, fy:可选的缩放因子(浮点型),若指定则覆盖 dsize
interpolation:插值方法,常用选项包括:
cv2.INTER_NEAREST
:最近邻插值(速度快,适用于缩小)
cv2.INTER_LINEAR
:双线性插值(默认,适用于放大)
cv2.INTER_CUBIC
:双三次插值(质量更高,计算慢)
cv2.INTER_AREA
:区域插值(适用于缩小或图像抽取)
示例:
import cv2
# 读取图像
img = cv2.imread('example.jpg')
# 方法1:指定目标尺寸
resized1 = cv2.resize(img, (500, 300)) # 宽度500,高度300
# 方法2:使用缩放因子
resized2 = cv2.resize(img, None, fx=0.5, fy=0.5) # 宽高各缩小一半
# 不同插值方法对比
resized_nearest = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_NEAREST)
resized_linear = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_LINEAR)
cv2.line()
cv2.line(img, pt1, pt2, color, thickness=None, lineType=None, shift=None)
参数说明:
img:输入图像(NumPy 数组),函数会直接修改此图像
pt1, pt2:直线的起点和终点坐标,格式为(x, y)
元组
color:线条颜色,BGR 格式(例如(255, 0, 0)
表示蓝色)
thickness:线条宽度(像素),默认值为 1
lineType:线条类型,可选:
cv2.LINE_4
:4 连通线型(速度快)
cv2.LINE_8
:8 连通线型(默认)
cv2.LINE_AA
:抗锯齿线型(更平滑)
shift:坐标点的小数位数(通常忽略)
示例:
import cv2
import numpy as np
# 创建黑色背景图像(500x500像素)
img = np.zeros((500, 500, 3), dtype=np.uint8)
# 绘制蓝色对角线(厚度为2像素)
cv2.line(img, (0, 0), (500, 500), (255, 0, 0), 2)
# 绘制绿色水平线(厚度为3像素,抗锯齿)
cv2.line(img, (100, 200), (400, 200), (0, 255, 0), 3, cv2.LINE_AA)
# 绘制红色垂直线(厚度为5像素)
cv2.line(img, (300, 100), (300, 400), (0, 0, 255), 5)
# 绘制黄色斜线(厚度为1像素)
cv2.line(img, (500, 0), (0, 500), (0, 255, 255), 1)
# 显示图像
cv2.imshow('Lines', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 保存图像(可选)
cv2.imwrite('lines_example.jpg', img)
cv2.circle()
cv2.circle(img, center, radius, color, thickness=None, lineType=None, shift=None)
参数说明:
img:输入图像(NumPy 数组),函数会直接修改此图像
center:圆心坐标,格式为(x, y)
元组
radius:圆的半径(像素值,必须为整数)
color:线条或填充颜色,BGR 格式(例如(0, 0, 255)
表示红色)
thickness:线条宽度(像素):
正值:绘制空心圆
-1:填充整个圆形区域
lineType:线条类型(同cv2.line()
)
shift:坐标点的小数位数(通常忽略)
import cv2
import numpy as np
# 创建黑色背景图像
img = np.zeros((500, 500, 3), dtype=np.uint8)
# 绘制红色空心圆(半径100,线宽2)
cv2.circle(img, (250, 150), 100, (0, 0, 255), 2)
# 绘制蓝色填充圆(半径50)
cv2.circle(img, (150, 300), 50, (255, 0, 0), -1)
# 绘制绿色抗锯齿空心圆(半径80,线宽3)
cv2.circle(img, (350, 300), 80, (0, 255, 0), 3, cv2.LINE_AA)
# 绘制多个同心圆(演示不同半径)
for r in range(20, 100, 20):
cv2.circle(img, (250, 400), r, (0, 255, 255), 2)
# 显示图像
cv2.imshow('Circles', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 保存图像(可选)
cv2.imwrite('circles_example.jpg', img)
cv2.circle()
cv2.circle(img, center, radius, color, thickness=None, lineType=None, shift=None)
参数说明:
img:输入图像(NumPy 数组),函数会直接修改此图像
center:圆心坐标,格式为(x, y)
元组
radius:圆的半径(像素值,必须为整数)
color:线条或填充颜色,BGR 格式(例如(0, 0, 255)
表示红色)
thickness:线条宽度(像素):
正值:绘制空心圆
-1:填充整个圆形区域
lineType:线条类型(同cv2.line()
)
shift:坐标点的小数位数(通常忽略
示例
import cv2
import numpy as np
# 创建黑色背景图像
img = np.zeros((500, 500, 3), dtype=np.uint8)
# 绘制红色空心圆(半径100,线宽2)
cv2.circle(img, (250, 150), 100, (0, 0, 255), 2)
# 绘制蓝色填充圆(半径50)
cv2.circle(img, (150, 300), 50, (255, 0, 0), -1)
# 绘制绿色抗锯齿空心圆(半径80,线宽3)
cv2.circle(img, (350, 300), 80, (0, 255, 0), 3, cv2.LINE_AA)
# 绘制多个同心圆(演示不同半径)
for r in range(20, 100, 20):
cv2.circle(img, (250, 400), r, (0, 255, 255), 2)
# 显示图像
cv2.imshow('Circles', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 保存图像(可选)
cv2.imwrite('circles_example.jpg', img)
cv2.putText()
cv2.putText(img, text, org, fontFace, fontScale, color, thickness=None, lineType=None, bottomLeftOrigin=None)
参数说明:
img:输入图像(NumPy 数组)
text:要绘制的文本字符串
org:文本框左下角坐标(x, y)
fontFace:字体类型,例如:
cv2.FONT_HERSHEY_SIMPLEX
(简单无衬线字体,最常用)
cv2.FONT_HERSHEY_PLAIN
(小尺寸无衬线字体)
cv2.FONT_HERSHEY_COMPLEX
(复杂衬线字体)
fontScale:字体大小缩放因子
color:文本颜色(BGR 格式)
thickness:字体线条宽度(像素)
lineType:线条类型,推荐使用cv2.LINE_AA
(抗锯齿)
bottomLeftOrigin:可选参数,若为True
则文本方向反转
示例
import cv2
import numpy as np
# 创建黑色背景图像
img = np.zeros((500, 500, 3), dtype=np.uint8)
# 绘制白色简单文本(默认字体)
cv2.putText(img, 'Hello OpenCV!', (50, 100),
cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
# 绘制红色复杂文本(抗锯齿)
cv2.putText(img, 'Complex Font', (50, 200),
cv2.FONT_HERSHEY_COMPLEX, 1.2, (0, 0, 255), 2, cv2.LINE_AA)
# 绘制绿色小文本
cv2.putText(img, 'Small Text', (50, 250),
cv2.FONT_HERSHEY_PLAIN, 1.5, (0, 255, 0), 1)
# 绘制多行文本
text = 'Multi-line\nText Example'
y0, dy = 300, 40
for i, line in enumerate(text.split('\n')):
y = y0 + i*dy
cv2.putText(img, line, (50, y),
cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 255), 2)
# 显示图像
cv2.imshow('Text on Image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 保存图像(可选)
cv2.imwrite('text_example.jpg', img)
cap = cv2.VideoCapture(path)
path:视频流资源路径设置为0,代表从默认摄像头捕获视频流
ret,frame = cap.read()
返回值cap调用read()方法得到一个布尔值和一帧图像,布尔值表示是否成功读取到帧,如果为False,可能是因为视频结束或读取失败,如果为True,frame则是当前帧的图像数据。
示例
import cv2 as cv
# 创建一个videocapture对象 cap=cv.VideoCapture(path)
# 读取视频文件
# cap=cv.VideoCapture("../images/videocap.mp4")
# 从默认摄像头获取实时视频流
cap=cv.VideoCapture(0)
# 循环读取每一帧图像
while True:
# 调用read()方法 读取每一帧图像
ret,img=cap.read()
# 判断是否读取成功
if not ret:
print("error!")
break
cv.imshow("dst",img)
#
if cv.waitKey(10)&0xFF==ord("q"):
print("按键退出!")
break
cap.release()
cv.destroyAllWindows()