探索OpenCV--计算机视觉的入门指南
OpenCV(开源计算机视觉库)是一个用于计算机视觉和图像处理的跨平台库。它是由Intel发起并由多个贡献者维护的一个项目,现已被广泛应用于各种商业产品中。
OpenCV支持多种编程语言,如C++、Python等,并且可以在Windows、Linux、Android和Mac OS等操作系统上运行。
主要特点:
丰富的功能:OpenCV包含了大量预处理、特征检测、物体识别、结构分析、3D重建、机器学习等功能。
跨平台:可以在多种操作系统下使用。
开源:基于BSD许可发布,允许免费用于商业和研究目的。
社区活跃:拥有庞大的开发者和用户社区,提供了大量的教程和支持。
网址:
安装
使用如下命令安装openCV
pip install opencv-python
注意,为了让IDE(如VSCode)能够更好得显示opencv-python的代码补全,请安装如下库:
pip install opencv-stubs
引入
import cv2
读取图像
使用imread
读取图像
img = cv2.imread('image.jpg')
img = cv2.imread('image.jpg', flags=0)
对于flags
的输入有如下三个选项:
1
: 加载彩色图像0
: 加载灰色图像-1
: 加载包含alpha通道的图像
读取后的图像为numpy数组, 若为彩色图像, 则为三维数组,其颜色格式默认为BGR
如果想转换成RGB
,使用如下代码:
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
显示图像
img = cv2.imread('image.jpg')
cv2.imshow('test_show_image', img) # test_show_image为窗口名,可以为None或者任意字符串
cv2.waitKey(0) # 等待任意键盘按键输入
cv2.destroyAllWindows() # 销毁所有窗口
cv2.destroyWindow("test_show_image") # 销毁指定窗口,根据上面定义的窗口名看
写入图像
cv2.imwrite('new_image.jpg', img)
获取图像属性
获取图像形状
img.shape # (height, width, channel)
返回tuple,格式为(height, width, channel),就是高,宽,通道数
获取图像的大小
img.size
获取图像某个像素的值
前面我们知道了,cv2读取的图像是一个numpy数组,所以我们可以直接使用索引来获取某个像素的值
b, g, r = img[1, 1] # 获取第1行第1列的像素值
若读取的图像为彩色图(包含多个颜色通道,通常是RGB或BGR),那么读取的像素值将是一个包含三个元素的数组或元组,分别代表每个颜色通道的值。
这里的b,g,r分别对应蓝色、绿色和红色通道的值(以openCV默认格式来看)。每个值介于0到255之间的整数。
若读取的图像为灰度图(只包含一个通道),那么读取的像素值将是一个整数值,表示该像素的灰度级。这个值通常在0到255之间,其中0表示黑色,255表示白色。
注意:
像素坐标通常是按照
(行,列)
或(y,x)
的顺序指定的如果图像包含其他颜色模式,比如HSV或YUV,那么返回的像素值将对应这些颜色空间中的各个分量。
修改图像某个像素的值
img[1, 1] = [255, 255, 255] # 将第1行第1列的像素值修改为白色
调整图像大小
resized = cv2.resize(img, (width, height), interpolation=cv2.INTER_AREA)
其中width
和height
为缩放后的图像的宽和高,interpolation
为插值方法,常用的插值方法有:
cv2.INTER_NEAREST
:最近邻插值cv2.INTER_LINEAR
:双线性插值(默认)cv2.INTER_CUBIC
:双三次插值cv2.INTER_AREA
:区域插值
旋转图像
(h, w) = img.shape[:2] # 获取图像的长或者宽
center = (w // 2, h // 2) # 取图像的中心点
M = cv2.getRotationMatrix2D(center, angle, scale) # 获取旋转后的图像矩阵
rotated = cv2.warpAffine(img, M, (w, h)) # 应用旋转
其中angle
为旋转角度,scale
为缩放比例,M
为旋转矩阵,rotated
为旋转后的图像。
绘制形状
在读取一张图片后, 我们可以在图片上绘制一些形状。opencv-python提供了一些函数, 可以让我们在图片上绘制形状。
绘制矩形
使用cv2.rectangle
绘制一个矩形。
cv2.rectangle
的传入参数如下:
cv2.rectangle(img, pt1: tuple, pt2: tuple, color: tuple, thickness: int)
其中, img为cv2读取的图片。pt1和pt2为矩形的两个顶点, 分别为左上角和右下角。color为矩形的颜色。thickness为矩形的线条粗细。
注意这里的颜色的表示方式是BGR(蓝-绿-红), 即使你已经将img使用cv2.cvtColo
转换成了RGB
如果想要绘制一个红色的矩形, 这个参数需要传入的颜色元组应该是(0, 0, 255), 而不是(255, 0, 0)
下面是一个例子:
import cv2
img = cv2.imread("./test.png")
cv2.rectangle(img, (50, 50), (100, 100), (0, 255, 0), 3)
cv2.imshow("rectangle", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
绘制圆
使用cv2.circle
绘制一个圆。
cv2.circle
的传入参数如下:
cv2.circle(img, center: tuple, radius: int, color: tuple, thickness: int)
其中, img为cv2读取的图片。center为圆心的坐标, 以(x, y)的形式表示。radius为圆的半径, 以像素为单位。color为圆的颜色。thickness为圆的线条粗细。
注意这里的颜色的表示方式是BGR(蓝-绿-红), 即使你已经将img使用cv2.cvtColo
转换成了RGB
如果想要绘制一个红色的圆, 这个参数需要传入的颜色元组应该是(0, 0, 255), 而不是(255, 0, 0)
下面是一个例子:
import cv2
img = cv2.imread("./capture.png")
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
cv2.circle(img, (500, 500), 100, (0, 255, 0),3)
cv2.imshow("circle", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
绘制直线
使用cv2.line
绘制一个直线。
cv2.line
的传入参数如下:
cv2.line(img, pt1: tuple, pt2: tuple, color: tuple, thickness: int)
其中, img为cv2读取的图片。pt1和pt2分别为直线的起点和终点。color为直线的颜色。thickness为直线的线条粗细。
注意这里的颜色的表示方式是BGR(蓝-绿-红), 即使你已经将img使用cv2.cvtColo
转换成了RGB
如果想要绘制一个红色的直线, 这个参数需要传入的颜色元组应该是(0, 0, 255), 而不是(255, 0, 0)
下面是一个例子:
import cv2
img = cv2.imread("./capture.png")
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
cv2.line(img, (500, 500), (100, 100), (0, 255, 0), 3)
cv2.imshow("line", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
绘制椭圆
使用cv2.ellipse
绘制一个椭圆。
cv2.ellipse
的传入参数如下:
cv2.ellipse(img, center: tuple, axes: tuple, angle: int, startAngle: int, endAngle: int, color: tuple, thickness: int)
其中的参数解释如下:
img
: 要绘制椭圆的目标图像。这应该是一个已经创建好的图像对象, 例如通过cv2.imread读取的图像或通过np.zeros创建的空白图像。center
: 椭圆的中心坐标, 以(x, y)的形式表示。x是中心在水平方向上的位置, y是中心在垂直方向上的位置。axes
: 椭圆的长短轴长度, 以(major_axis_length, minor_axis_length)的形式表示。major_axis_length是椭圆长轴的长度, minor_axis_length是椭圆短轴的长度。angle
: 椭圆长轴与水平方向的夹角, 以度为单位。0度表示长轴水平, 正值表示逆时针旋转。startAngle
: 椭圆弧的开始角度, 以度为单位。0度表示从椭圆长轴的正方向开始。endAngle
: 椭圆弧的结束角度, 以度为单位。与startAngle一起定义了椭圆弧的范围。color
: 椭圆的颜色, 以(B, G, R)的形式表示。B是蓝色分量, G是绿色分量, R是红色分量。注意这里的颜色的表示方式是BGR(蓝-绿-红), 即使你已经将img使用cv2.cvtColo
转换成了RGBthickness
: 椭圆的线条粗细, 以像素为单位。如果设置为负数(例如-1), 则椭圆将被填充。
下面是一个例子:
import cv2
img = cv2.imread("./capture.png")
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
cv2.ellipse(img, (300, 425), (80, 20), 90, 0, 360, (0, 0, 255), -1)
cv2.imshow("ellipse", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
添加文本
使用cv2.putText
添加文本。
cv2.putText
的传入参数如下:
cv2.putText(img, text: str, org: tuple, fontFace: int, fontScale: float, color: tuple, thickness: int)
其中的参数解释如下:
img
: 要绘制文本的目标图像。这应该是一个已经创建好的图像对象, 例如通过cv2.imread读取的图像或通过np.zeros创建的空白图像。text
: 要绘制的文本字符串。org
: 文本字符串的左下角坐标, 以(x, y)的形式表示。x是文本字符串在水平方向上的位置, y是文本字符串在垂直方向上的位置。fontFace
: 字体类型。常用的字体类型有cv2.FONT_HERSHEY_SIMPLEX
,cv2.FONT_HERSHEY_PLAIN
等。fontScale
: 字体大小。这是一个缩放因子, 用于调整字体的大小。例如, 如果fontScale为1.0, 则字体大小为原始大小; 如果fontScale为2.0, 则字体大小为原始大小的两倍。color
: 文本的颜色, 以(B, G, R)的形式表示。B是蓝色分量, G是绿色分量, R是红色分量。注意这里的颜色的表示方式是BGR(蓝-绿-红), 即使你已经将img使用cv2.cvtColo
转换成了RGBthickness
: 文本的线条粗细, 以像素为单位。
下面是一个例子:
import cv2
img = cv2.imread("./capture.png")
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
cv2.putText(img, "Hello, World!", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
cv2.imshow("text", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
视频读取
openCV也可以读取视频,通过创建一个VideoCapture
对象即可:
# 创建一个VideoCapture对象,参数是视频文件路径。
cap = cv2.VideoCapture('path_to_your_video_file.mp4')
当然,VideoCapture
对象也可以捕获摄像头,方法非常简单:
cap = cv2.VideoCapture(0) # 使用默认摄像头
0
为设备索引,若有多个摄像头,请正确输入摄像头索引
视频帧获取
成功读取视频后,使用cap.read()
读取视频的每一帧
为了读取视频中的每一帧,我们可以使用while cap.isOpened()
开始一整个循环:
while cap.isOpened():
ret, frame = cap.read()
其中返回两个参数:
ret
用来指示是否成功读取了一帧,若为False
则意味着没有读取到帧,这可能是因为视频文件已经结束、摄像头连接问题、或者其他导致无法读取帧的原因。如果
ret
为True
,那么frame
将包含当前读取的图像帧数据,通常是以NumPy数组的形式表示,每个元素代表一个像素的颜色信息。
当成功读取到该帧后,可以像处理图片一样处理对应帧数以达到我们想要的结果