文章目录
- 一、cv.imread( filename[, flags] ) -> retval
- 二、cv.filter2D( src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]] ) -> dst
- 三、cv.imshow(winname, mat) ->None
- 四、cv.imwrite(filename, img[, params]) ->retval
- 五、cv.waitKey([, delay]) ->retval
- 六、cv.destroyAllWindows() ->None
- 七、cv.threshold(src, thresh, maxval, type[, dst]) ->retval, dst
- 八、cv.cvtColor(src, code[, dst[, dstCn]]) ->dst
- 题外话
一、cv.imread( filename[, flags] ) -> retval
和 cv.imread( filename[, dst[, flags]] ) -> dst
函数文档
1.1 主要功能
从指定的文件中加载图像并返回该图像矩阵(numpy.ndarray——多维数组对象)。
- 如果无法读取图像,则返回一个空矩阵。
- 支持常见的*.jpg, *.png, *.bmp等文件格式。
1.2 参数
- filename 要加载的文件路径。
- flags 标志,可以取 cv::ImreadModes 中的值。
- retval 是返回值(return value)的意思。
现阶段常用的标志如下,其他标志可见 官方文档 。
flags | 功能 |
---|---|
cv.IMREAD_UNCHANGED | 按原样返回已加载的图像,包括 alpha 通道(透明度、如果存在)。忽略 EXIF 方向信息。相机拍摄照片时的方向。 |
cv.IMREAD_GRAYSCALE | 将图像转换为单通道灰度图像。 |
cv.IMREAD_COLOR_BGR | 将图像转换为 3 通道 BGR 彩色图像。 |
1.3 注
-
opencv-python 对中文支持的不是很好,经常会因为字符编码等问题导致乱码 或 找不到文件位置的情况,所以尽量使用英文路径和名称。
-
imread 函数通过内容而非文件扩展名确定图像类型。
-
对于彩色图像,解码后的图像将以 B G R 顺序存储通道。
-
如果无法读取图像,则返回一个空矩阵。
在如下程序中
import cv2 # 读取图像 image = cv2.imread(r'D:\CSDN\image processing\Edge Detection\result\abc.png') # 检查图像是否成功加载 if image is not None: print("Image shape:", image.shape) print("Image type:", type(image)) else: print("Failed to load image") with open(r'D:\CSDN\image processing\Edge Detection\result\abc.png', 'rb') as f: data = f.read() print("Data type:", type(data))
imread 读取不存在的文件时,仅会给出警告,但程序继续运行。
[ WARN:0@0.042] global loadsave.cpp:241 cv::findDecoder imread_('D:\CSDN\image processing\Edge Detection\result\abc.png'): can't open/read file: check file path/integrity
而 open 函数读取不存在的文件时,则直接报错,程序退出。
FileNotFoundError: [Errno 2] No such file or directory: 'D:\\CSDN\\image processing\\Edge Detection\\result\\abc.png'
-
当使用 IMREAD_GRAYSCALE 时,如果编解码器内部支持灰度转换,则会使用该编解码器的内部灰度转换,结果可能与 cvtColor 函数的输出不同。
二、cv.filter2D( src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]] ) -> dst
2.1 主要功能
将图像与卷积核进行卷积。
- 此函数可以将任意的线性滤波器应用于图像。所以 Roberts 算子等边缘检测算法均可以调用此函数来实现。
- 当滤波器核的部分区域超出了图像边界时,函数会根据边界模式来插值(填充)边界外的像素值。
2.2 参数
- src 输入图像矩阵。
- dst 输出图像,具有与输入图像相同的大小和通道数。
- ddepth 期望的输出图像深度。例如:
- ddepth 参数的默认值是 -1,输出图像的深度将与输入图像的深度相同。
- CV_8U 8 位无符号整数,0 到 255。适用于大多数图像处理任务,例如灰度图像或彩色图像。
- CV_8S 8 位有符号整数 ,128 到 127。
- CV_16U 16 位无符号整数,0 到 65535。适用于高动态范围图像或某些中间计算过程。
- CV_32F 32 位浮点数。
- CV_64F 64 位双精度浮点数。
- kernel 卷积核。
- anchor 卷积核中的锚点,默认值为(-1, -1),表示锚点位于卷积核的中心。
- delta 为每个过滤后的像素值上添加delta。若 delta 为 1,则每个像素值都会增加 1。
- borderType 边界处理类型,定义了如何处理超出图像边界的情况。例如:
- BORDER_CONSTANT 使用常数值 0 填充边界外的像素。
- BORDER_REPLICATE 使用边界像素值填充边界外的像素。a b c d e → a a a b c d e e e
- BORDER_REFLECT 使用沿边界对称的像素值填充边界外的像素。a b c d e → b a a b c d e e d
- BORDER_REFLECT_101 使用沿边界对称的像素值填充边界外的像素,但不包含边界像素本身。a b c d e → c b a b c d e d c
- BORDER_DEFAULT 默认边界模式,与 BORDER_REFLECT_101 相同。
- BORDER_ISOLATED仅处理图像内部的像素,不处理边界像素。
2.3 计算原理
dst ( x , y ) = ∑ 0 ≤ x ′ < kernel.cols 0 ≤ y ′ < kernel.rows kernel ( x ′ , y ′ ) ∗ src ( x + x ′ − anchor.x , y + y ′ − anchor.y ) \texttt{dst} (x,y) = \sum _{ \substack{0\leq x' < \texttt{kernel.cols}\\{0\leq y' < \texttt{kernel.rows}}}} \texttt{kernel} (x',y')* \texttt{src} (x+x'- \texttt{anchor.x} ,y+y'- \texttt{anchor.y} ) dst(x,y)=0≤x′<kernel.cols0≤y′<kernel.rows∑kernel(x′,y′)∗src(x+x′−anchor.x,y+y′−anchor.y)
对于每个目标像素 d s t ( x , y ) dst(x,y) dst(x,y),使用卷积核 kernel 中每个元素 与 原图像 src 中相应位置的像素值相乘,并求和。
这里的相应位置是相对于锚点 anchor 的位置。锚点通常位于卷积核的中心位置。
2.4 filter2D 函数疑问
-
borderType 选择 BORDER_CONSTANT 时使用的常数是什么?
未找到 opencv-python 4.10.0.84 中 cv.filter2D 函数的源码,opencv-4.10.0 中也没找到 C++ 版本的代码。只能做实验验证,经测试得常数为 0。
-
2 x 2 卷积核的 anchor 锚点在哪个位置?
同样,经测试在右下角。
2.5 注
在设置 borderType 时,需要显式传递参数,即 borderType= xx,此时该标志位才能被正确识别。
三、cv.imshow(winname, mat) ->None
3.1 主要功能
在指定的窗口中显示图像。
如果窗口未被创建过,则默认使用 cv::WINDOW_AUTOSIZE 标志创建窗口,图像将显示其原始大小,但受限于屏幕分辨率。
3.2 参数
- winname 窗口的名称。
- mat 要显示的图像。
3.3 注
- 必须在调用 imshow 后紧接着调用 cv::waitKey 或 cv::pollKey 函数来执行 GUI 的维护任务,以确保窗口正常显示图像并响应鼠标和键盘事件。
- 若要关闭窗口,可以使用 cv::destroyWindow 函数。
- 在 Windows 中,按下 Ctrl+C 将图像复制到剪贴板,按下 Ctrl+S 将显示对话框以保存图像
四、cv.imwrite(filename, img[, params]) ->retval
4.1 主要功能
将图像保存到指定文件。
通常情况下,只能保存 8-bit 无符号(CV_8U)单通道或 3 通道(‘BGR’ 顺序)的图像。但是,对于PNG 编码器,还可以包含一个 Alpha 通道。
4.2 参数
- filename 保存图像的文件名。文件格式根据文件名的扩展名来决定(参见 cv::imread 的支持列表)。
- img 要保存的图像。
- params 可选参数,用于控制图像的保存方式,详见 cv::ImwriteFlags 。(暂时不常用)
五、cv.waitKey([, delay]) ->retval
5.1 主要功能
等待用户按键事件。
- delay ≤ 0 时,会无限期地等待,直到用户按下某个键。
- delay > 0 时,由于操作系统在切换线程之间有最小的时间间隔,因此该函数不会精确地等待 delay 毫秒,而是至少等待 delay 毫秒。
- 如果在指定时间之内没有按下按键,则返回 -1 。
5.2 参数
delay 延迟时间,单位为毫秒。0是代表“永远”的特殊值。
5.3 注
- waitKey 和 pollKey 是 HighGUI 中处理 GUI 事件的唯一方法。
- cv::waitKey 的使用条件:至少创建一个窗口,如果同时打开了多个窗口,其中一个窗口必须是活动的(即当前选中的窗口)。如果打开了多个窗口,那么其中任何一个窗口都可以成为活动窗口。
六、cv.destroyAllWindows() ->None
6.1 主要功能
销毁所有打开的窗口。
6.2 cv2.waitKey(0) + cv2.destroyAllWindows()
等待用户按下任意键后关闭所有窗口。
七、cv.threshold(src, thresh, maxval, type[, dst]) ->retval, dst
7.1 主要功能
对每个数组元素应用阈值操作。
- 通常是对灰度图像进行阈值处理,以获得二值图像或进行噪声过滤。
- THRESH_OTSU 和 THRESH_TRIANGLE 这两个特殊的阈值处理类型可以与其他阈值处理类型组合使用。函数会根据 Otsu’s 或 Triangle 算法自动确定最佳阈值值,并使用这个最佳阈值值代替指定的阈值值。
7.2 参数
-
src 输入图像。
-
dst 输出图像,与 src 具有相同大小和类型以及相同通道数的输出数组。
-
thresh 阈值。
-
maxval 使用 THRESH_BINARY 和 THRESH_BINARY_INV 阈值类型时的最大值。
-
type 阈值处理类型,见 ThresholdTypes 。
type 功能 THRESH_BINARY 如果像素值大于阈值,则设置为 maxval;否则设置为 0。 THRESH_BINARY_INV 如果像素值大于阈值,则设置为 0;否则设置为 maxval。 THRESH_TRUNC 如果像素值大于阈值,则设置为阈值;否则保持不变。 THRESH_TOZERO 如果像素值大于阈值,则设置为原像素值;否则设置为 0。 THRESH_TOZERO_INV 如果像素值大于阈值,则设置为 0;否则保持不变。 THRESH_OTSU 使用 Otsu 算法选择最优阈值。 THRESH_TRIANGLE 使用 Triangle 算法选择最优阈值
7.3 计算原理
-
dst ( x , y ) = { maxval , if src ( x , y ) > thresh 0 , otherwise \texttt{dst}(x,y) = \begin{cases} \texttt{maxval}, & \text{if } \texttt{src}(x,y) > \texttt{thresh} \\ 0, & \text{otherwise} \end{cases} dst(x,y)={maxval,0,if src(x,y)>threshotherwise
-
dst ( x , y ) = { 0 , if src ( x , y ) > thresh maxval , otherwise \texttt{dst}(x,y) = \begin{cases} 0, & \text{if } \texttt{src}(x,y) > \texttt{thresh} \\ \texttt{maxval}, & \text{otherwise} \end{cases} dst(x,y)={0,maxval,if src(x,y)>threshotherwise
7.4 注
- 目前,Otsu 和 Triangle 方法仅支持 8 位单通道图像。
- 如果使用了 Otsu 或 Triangle 方法,则还会返回计算出的阈值。
- THRESH_OTSU 或 THRESH_TRIANGLE 可以与其他阈值类型组合使用。在这种情况下,函数会使用 Otsu 或 Triangle 算法确定最优阈值,并用这个值替代指定的阈值。
八、cv.cvtColor(src, code[, dst[, dstCn]]) ->dst
8.1 主要功能
将图像从一个颜色空间转换到另一个颜色空间。
需要再次注意的是,在 OpenCV 中,默认的颜色格式是 BGR。
8.2 参数
- src 输入图像
- dst 输出图像
- code 颜色空间转换代码,详见 ColorConversionCodes 。其中一些常用的包括:
- COLOR_BGR2GRAY 从 BGR 转换到灰度图。
- COLOR_GRAY2BGR 从灰度图转换到 BGR。
- COLOR_BGR2RGB 从 BGR 转换到 RGB。
- COLOR_RGB2BGR 从 RGB 转换到 BGR。
- dstCn 定了目标图像中的通道数。为默认值 0,将根据源图像和转换代码自动推断出通道数。
题外话
-
为什么下载的是 opencv-python 4.10.0.84,但 import 的是 cv2 而不是 cv4 ?
因为 cv2 中的 2 并不是 OpenCV 的版本号。cv 表示库使用的 API 主要是基于 C 语言的;cv2 表示库使用的 API 主要是基于C++的。
详情可见 OpenCV 介绍 和 一些其他博客做的总结,如 OpenCV各版本差异与演化,从1.x到4.0 等。 -
filter2D 函数实际上计算的是相关(correlation),而不是卷积(convolution)。也就是说,如果需要真正的卷积,需要翻转内核,并设置新锚点。
这是数学上的严谨定义,平时使用时仍称卷积即可。
【这两个概念及他们的区别,与本篇文章核心处相关度不大。详细信息可参考:
】