【CV】OpenCV(基于Python)学习笔记|CSDN创作打卡

以下内容中的页码均来自《OpenCV 4详解 : 基于Python》

目录

第2章 载入、显示与保存数据

2.2 图像的读取与显示

2.2.1 图像读取函数 cv.imread()

函数原型:img = cv.imread(filename [, flags])

  • filename:需要读取的图像的路径,包含图像名称和图像文件扩展名
  • flags:读取图像的形式,默认按照彩色图像格式读取(可选择的标志见P27表2-2)

如果无法正确读取图像,返回None,可通过print(img)查看得到的结果是否为None来判断是否成功读取了图像。

2.2.2 图像窗口函数 cv.namedWindow()

函数原型:None = cv.namedWindow(winname [, flags])

  • winname:窗口名称,用作窗口的标识符,用于识别此窗口
  • flags:窗口属性设置标志(可选择的标志见P28表2-3)

flags标志可以设置多个,不同参数之间用“|”分隔,默认为根据图像大小显示窗口、保持图像比例、创建的窗口允许添加工具栏和状态栏

2.2.3 图像显示函数 cv.imshow()

函数原型:None = cv.imshow(winname, img)

  • winname:要显示图像的窗口的名称
  • img:要显示的图像

为了让图像不是一闪而过的,需要在本函数后加上cv.waitKey()函数,来将程序暂停一段时间,暂停时间可以以参数的形式赋值,单位为毫秒;参数默认值为0,表示等待用户按键结束该函数。

2.2.4 关闭窗口函数 cv.destroyWindow()/cv.destroyAllWindows()

函数原型:
None = cv.destroyWindow(winname)
None = cv.destroyAllWindows()

  • winname:要关闭的窗口的名称

2.3 视频的加载与摄像头的调用

2.3.1 读取视频数据 cv.VideoCapture()

函数原型:
<VideoCapture object> = cv.VideoCapture()
<VideoCapture object> = cv.VideoCapture(filename [, apiPreference])

  • filename:读取的视频文件的名称
  • apiPreference:读取数据时设置的属性

第一行中的VideoCapture函数需要在使用时通过open()函数指出,如对象名为video,则用video.open("testvideo.mov")来打开视频文件。
第二行中的VideoCapture函数在默认情况下自动搜索合适的视频属性标志,在使用时一般可以省略属性标志。

  • 创建视频对象后,用isOpened()函数判断是否创建成功,成功返回True,失败返回False。如video.isOpened()
  • 判断已经成功创建视频对象后,用read()函数读取一帧图像,如通过ret, img = viedo.read()从video对象中读取一帧图像存放在img中,ret变量存储是否成功读取对象,成功为True,失败为False。也可以通过ret变量判断读取视频文件时是否已经到了结尾。
  • 另外,可以通过get(propId)函数获取视频属性,如video.get(0)propId的可选标志见P30表2-4

示例代码(来自书本,略有改动,后同):

import cv2 as cv
if __name__ == '__main__':
video = cv.VideoCapture('./videos/road.mp4')
# 判断是否成功创建视频流
while video.isOpened(): # video.isOpened()成功读取返回true,读取失败返回false
ret, frame = video.read() # frame中存储一帧的图像;ret读取成功为true,读取失败为false
if ret is True:
cv.imshow('Video', frame)
# 设置视频播放速度,设置值等于1000为原速度,高于1000会减慢,低于1000加快
# 此代码为按视频原速度播放,cv.CAP_PROP_FPS表示原视频的帧率
cv.waitKey(int(1000 / video.get(cv.CAP_PROP_FPS)))
# 按下q退出
if cv.waitKey(1) & 0xFF == ord('q'):
break
else:
break
# 输出相关信息
print('视频中图像的宽度为:{}'.format(video.get(cv.CAP_PROP_FRAME_WIDTH)))
print('视频中图像的高度为:{}'.format(video.get(cv.CAP_PROP_FRAME_HEIGHT)))
print('视频帧率为:{}'.format(video.get(cv.CAP_PROP_FPS)))
print('视频总帧数为:{}'.format(video.get(cv.CAP_PROP_FRAME_COUNT)))
# 释放并关闭窗口
video.release()
cv.destroyAllWindows()

关于if __name__ == '__main__'的解释点此查看

2.3.2 摄像头的直接调用 cv.VideoCapture()

函数原型:<VideoCapture object> = cv.VideoCapture(index [, apiPreference])

  • index:摄像头的索引号,0表示使用计算机的默认摄像头
  • apiPreference:读取数据时设置的属性

示例代码与2.3.1基本相同,另可以在cv.imshow('Video', frame)前添加frame = cv.flip(frame, 1)对摄像头拍摄的图像进行水平翻转,翻转后的视频为镜像,若不添加上述代码也可,视频为非镜像状态。

2.4 数据的保存

2.4.1 保存图像 cv.imwrite()

函数原型:retval = cv.imwrite(filename, img [, params])

  • filename:图像保存的路径和文件名,包含图像格式
  • img:将要保存的图像(Array类型的数组)
  • params:保存图片格式时的属性设置标志

如果成功保存,返回True,失败返回False

函数第三个参数一般不需要填写,第三个参数的设置方式如下:

# 将img以等级为95的图像质量保存
cv.imwrite(filename, img, [int(cv.IMWRITE_JPEG_QUALITY), 95])
# 将img以值为6的压缩级别进行保存
cv.imwrite(filename, img, [int(cv.IMWRITE_PNG_COMPRESSION), 6])

第三个参数的可选择标志见P33表2-5

2.4.2 保存视频 cv.VideoWriter()

函数原型:
<VideoWriter object> = cv.VideoWriter()
<VideoWriter object> = cv.VideoWriter(filename, fourcc, fps, frameSize [, isColor])

  • filename:保存视频的路径和文件名
  • fourcc:压缩帧的4字符编/解码器选项
  • fps:保存视频的帧率,即每秒多少张图像
  • frameSize:视频帧的大小
  • isColor:表示是否以彩色形式保存视频,默认为彩色

第一行的VideoWriter函数与VideoCapture函数相同,后续需要通过open()函数设置保存的文件名称等参数。

fourcc参数可以设置的编解码器选项见P35表2-6,如果赋值为“-1”则会自动搜索合适的编解码器。

frameSize参数一定要与图像的尺寸相同。

示例代码如下:

import cv2 as cv
if __name__ == '__main__':
# 设置编/解码方式
fourcc = cv.VideoWriter_fourcc(*'DIVX')
# 采用默认摄像头获取图像
video = cv.VideoCapture(0)
# cv.VideoWriter()第一种构造函数(两种方法效果相同)
# result = cv.VideoWriter()
# result.open('./videos/Save_video.avi', fourcc, 20.0, (640, 480))
# cv.VideoWriter()第二种构造函数
result = cv.VideoWriter('./videos/Save_video.avi', fourcc, 20.0, (640, 480))
# 判断是否成功创建视频流
while video.isOpened():
ret, frame = video.read()
if ret is True:
# 将每一帧图像进行水平翻转
frame = cv.flip(frame, 1)
# 将一帧一帧图像写入视频
result.write(frame)
cv.imshow('Video', frame)
cv.waitKey(25)
# 键盘按下q退出
if cv.waitKey(1) & 0xFF == ord('q'):
break
else:
break
# 释放并关闭窗口
video.release()
result.release()
cv.destroyAllWindows()

2.4.3 保存和读取XML和YMAL文件 cv.FileStorage()

2.4.3.1 保存

首先进行初始化
函数原型:<FileStorage object> = cv.FileStorage(filename, flags [, encoding])

  • filename:打开的文件名称
  • flags:对文件执行的操作类型标志(详见P37表2-7)
  • encoding:编码格式

该函数用于声明打开的文件名称和操作的类型。
filename为字符串类型,文件的扩展名可以是“.xml”“.ymal”“.yml”。
flags参数表示对文件执行读取操作、写入操作等。

打开文件后,可以使用isOpened()来判断是否成功打开文件,成功打开返回True,打开失败返回False。

cv.FileStorage()函数中没有声明参数,可通过open()函数单独声明,函数原型如下:
retval = cv.FileStorage.open(filename, flags [, encoding])

  • filename:打开的文件名称
  • flags:对文件执行的操作类型标志(详见P37表2-7)
  • encoding:编码格式

成功打开文件后,使用cv.FileStorage.write()函数将数据写入文件中,函数原型如下:
None = cv.FileStorage.write(name, val)

  • name:写入文件中的变量名称
  • val:变量值(目前支持实数、字符串和矩阵)

2.4.3.2 读取

  • 读取实数型
    file.getNode('x').real()
  • 读取字符串型
    file.getNode('x').string()
  • 读取矩阵型
    file.getNode('x').mat()

对2.4.3的示例代码:

import cv2 as cv
import numpy as np
if __name__ == '__main__':
# 创建FileStorage对象file,用于写入数据
# 读者可以尝试将文件后缀名改为.yml或.yaml
# file = cv.FileStorage('./data/MyFile.yml', cv.FileStorage_WRITE)
# file = cv.FileStorage('./data/MyFile.yaml', cv.FileStorage_WRITE)
file = cv.FileStorage('./data/MyFile.xml', cv.FileStorage_WRITE)
# 写入数据
file.write('name', '张三')
file.write('age', 16)
file.write('date', '2019-01-01')
scores = np.array([[98, 99], [96, 97], [95, 98]])
file.write('scores', scores)
# 释放对象
file.release()
# 创建FileStorage对象file1,用于读取数据
file1 = cv.FileStorage('./data/MyFile.xml', cv.FileStorage_READ)
# 判断MyFile.xml文件是否成功打开
if file1.isOpened():
# 读取数据
name1 = file1.getNode('name').string()
age1 = file1.getNode('age').real()
date1 = file1.getNode('date').string()
scores1 = file1.getNode('scores').mat()
# 展示读取结果
print('姓名:{}'.format(name1))
print('年龄:{}'.format(age1))
print('记录日期:{}'.format(date1))
print('成绩单:{}'.format(scores1))
else:
print('Can\'t open MyFile.xml.')
# 释放对象
file1.release()

第3章 图像基本操作

3.1 颜色空间

3.1.1.6 不同颜色空间之间的互相转换 cv.cvtColor()

函数原型:dst = cv.cvtColor(src, code, [, dst [, dstCn]])

  • src:待转换颜色空间的原始图像
  • code:颜色空间转换的标志(详见P44表3-1)
  • dst:颜色空间转换后的目标图像
  • dstCn:目标图像中的通道数,默认为0

3.1.2 多通道分离与合并 cv.split()/cv.merge()

3.1.2.1 分离 cv.split()

函数原型:mv = cv.split(m [, mv])

  • m:待分离的多通道图像
  • mv:分离后的单通道图像

3.1.2.2 合并 cv.merge()

函数原型:dst = cv.merge(mv [, dst])

  • mv:需要合并的图像
  • dst:合并后输出的图像

3.2 图像像素的操作

3.2.1 图像像素统计

3.2.1.1 寻找图像像素的最大值与最小值 cv.minMaxLoc()

函数原型:
minVal, maxVal, minLoc, maxLoc = cv.minMaxLoc(src [, mask])

  • src:需要寻找最大值和最小值的图像(图像可表示为矩阵)
  • mask:图像掩模(用于在图像的指定区域内寻找最值,默认值为None,表示寻找范围为整个图像)
  • minVal:图像中的最小值
  • maxVal:图像中的最大值
  • minLoc:图像中的最小值在矩阵中的坐标
  • maxLoc:图像中的最大值在矩阵中的坐标

若图像中存在多个最值,则输出的最值位置为按行扫描从左至右第1次检测到的最值位置

3.2.1.1.1 图像矩阵形状调整函数 np.reshape()

函数原型:dst = np.reshape(array, shape [, order])

  • array:需要调整尺寸和通道数的图像
  • shape:重塑后的矩阵的维度
  • order:读取/写入元素时的顺序

3.2.1.2 计算图像的均值和标准差 cv.mean()/cv.meanStdDev()

求均值函数原型:retal = cv.mean(src [, mask])

  • src:待求均值的图像(其通道数为1~4的整数)
  • mask:图像掩模(不输出此参数时,表示取所有像素的均值)

同时求均值和标准差函数原型:
mean, stddev = cv.meanStdDev(src [, mean [, stddev [, mask]]])

  • src:待求均值和标准差的图像
  • mean:图像每个通道的均值
  • stddev:图像每个通道的标准差
  • mask:图像掩模

3.2.2 两图像间的像素操作

3.2.2.1 两幅图像的比较运算 cv.max()/cv.min()

函数原型:
dst = cv.max(src1, src2 [, dst])
dst = cv.min(src1, src2 [, dst])

  • src1:第1幅图像,可以是任意通道数的矩阵
  • src2:第2幅图像,尺寸、通道数及数据类型与第1个参数一致
  • dst:保留对应位置较大(较小)灰度值后的图像

判断每一个像素点,保留两幅图像中灰度值较大(较小)的像素点

3.2.2.2 两幅图像的逻辑运算 cv.bitwise_?()

函数原型:
与运算:dst = cv.bitwise_and(src1, src2 [, dst [, mask]])
或运算:dst = cv.bitwise_or(src1, src2 [, dst [, mask]])
异或运算:dst = cv.bitwise_xor(src1, src2 [, dst [, mask]])
非运算:dst = cv.bitwise_not(src [, dst [, mask]])

  • src1:第1幅图像,可以是多通道图像数据
  • src2:第2幅图像,尺寸、通道数及数据类型与第1个参数一致
  • dst:逻辑运算输出结果
  • mask:掩模矩阵,用于设置图像或矩阵中逻辑运算的范围
  • src:输入的图像矩阵

ps:异或运算:相同为0,不相同为1

3.2.3 图像二值化

函数原型:retval, dst = cv.threshold(src, thresh, maxval, type [, dst])

  • src:待二值化的图像,图像的数据类型只能是uint8或float32
  • thresh:二值化的阈值
  • maxval:二值化过程中的最大值。此参数只在两种二值化方法中发挥作用,但使用其他方法也需要输入此参数
  • type:选择图像的二值化方法的标志(可选择的标志见P57表3-2)
  • dst:二值化后的图像

局部自适应阈值的二值化函数原型:
dst = cv.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C [, dst])

  • src:待二值化的图像,只能是8位单通道类型的图像
  • maxValue:二值化后的最大值,要求为非零数
  • adaptiveMethod:自适应确定阈值的方法,分为均值法(cv.ADAPTIVE_THRESH_MEAN_C)和高斯法(cv.ADAPTIVE_THRESH_GAUSSIAN_C
  • thresholdType:选择图像二值化方法的标志,只能是cv.THRESH_BINARYcv.THRESH_BINARY_INV
  • blockSize:自适应确定阈值的像素领域大小,一般取值为3、5、7
  • C:从平均值或者加权平均值中减去的常数,可正可负
  • dst:二值化后的图像,与输入图像具有相同的尺寸、数据类型

3.2.4 LUT cv.LUT()

函数原型:dst = cv.LUT(src, lut [, dst])

  • src:输入的图像,仅支持8位
  • lut:256个灰度值的查找表
  • dst:输出图像

3.3 图像连接和图像变换

3.3.1 图像连接 cv.vconcat()/cv.hconcat()

图像垂直连接函数原型:dst = cv.vconcat(src [, dst])

  • src:需要连接的图像(可以用矩阵表示)(要求均具有相同的长度、数据类型和通道数)
  • dst:连接后的图像(可以用矩阵表示)

图像水平连接函数原型:dst = cv.hconcat(src [, dst])

  • src:需要连接的图像(可以用矩阵表示)(要求均具有相同的高度、数据类型和通道数)
  • dst:连接后的图像(可以用矩阵表示)

示例:img = cv.hconcat((img0, img1))

3.3.2 图像尺寸变换 cv.resize()

函数原型:dst = cv.resize(src, dsize [, dst [, fx [,fy [, interpolation]]]])

  • src:输入的图像
  • dsize:输出图像的尺寸
  • dst:输出图像
  • fx:水平轴的比例因子,如果沿水平轴将图像放大为原来的2倍,则指定为2
  • fy:垂直轴的比例因子,如果沿垂直轴将图像放大为原来的2倍,则指定为2
  • interpolation:插值方法的标志(可以选择的标志见P66表3-3)

3.3.3 图像翻转变换 cv.flip()

函数原型:dst = cv.flip(src, flipCode [, dst])

  • src:输入的图像
  • flipCode:翻转方式标志。数值大于0,绕y轴翻转;数值等于0,绕x轴翻转;数值小于0,绕两条轴翻转
  • dst:输出的图像

3.3.4 图像仿射变换(三点变换) cv.getRotationMatrix2D()/cv.warpAffine()/cv.getAffineTransform()

计算旋转矩阵的函数原型:retal = cv.getRotationMatrix2D(center, angle, scale)

  • center:图像旋转的中心
  • angle:图像旋转的角度,正值代表逆时针旋转
  • scale:沿两条轴的缩放比例,可以实现旋转过程中的图像缩放。不需要缩放输入1

确定旋转矩阵后,进行仿射变换后实现图像的旋转。
仿射变换函数原型:
dst = cv.warpAffine(src, M, dsize [, dst [, flags [, borderMode [, borderValue]]]])

  • src:输入的图像
  • M:2×3的变换矩阵(之前求得的旋转矩阵)
  • dsize:输出图像的尺寸
  • dst:放射变换后的输出图像,尺寸与dsize相同
  • flags:插值方法的标志(详见P69表3-4)
  • borderMode:像素边界外推方法的标志
  • borderValue:填充边界使用的数值,默认为0

利用三点求变换矩阵函数原型:retval = cv.getAffineTransform(src, dst)

  • src:原图像中3个像素的坐标
  • dst:目标图像中对应的3个像素的坐标

3.3.5 图像透视变换(四点变换) cv.getPerspectiveTransform()/cv.wrapPerspective()

利用四点求变换矩阵函数原型:retval = cv.getPerspectiveTransform(src, dst [, solveMethod)

  • src:原图像中4个像素的坐标
  • dst:目标图像中对应的4个像素的坐标
  • solveMethod:选择计算透视变换矩阵方法的标志(详见P72表3-6),默认为最佳主轴元素的高斯消元法

透视变换矩阵函数原型dst = cv.wrapPerspective(src, M, dsize [, dst [, flags [, borderMode [, borderValue]]]])

  • src:输入的图像
  • M:3×3的变换矩阵(之前求得的旋转矩阵)
  • dsize:输出图像的尺寸
  • dst:放射变换后的输出图像,尺寸与dsize相同
  • flags:插值方法的标志(详见P69表3-4)
  • borderMode:像素边界外推方法的标志
  • borderValue:填充边界使用的数值,默认为0

3.3.6 极坐标变换

函数原型:dst = cv.warpPolar(src, dsize, center, maxRadius, flags [, dst])

  • src:原图像
  • dsize:目标图像的大小
  • center:极坐标变换时极坐标在原图像中的原点
  • maxRadius:变换时边界圆的半径
  • flags:插值方法与极坐标映射方法的标志(插值方法见P66表3-3,极坐标映射方法见P74表3-7)
  • dst:极坐标变换后的输出图像
posted @   Fannnf  阅读(137)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示