OpenCV基础
基本读写
| 函数 | 描述 |
|---|---|
| cv.imread() | 从文件读取图像 |
| cv.imdecode() | 从内存缓冲区读取图像 |
| cv.imshow() | 在openCV窗口显示图像 |
| cv.imwrite() | 将图像写入文件 |
| cv.waitKey() | 等待按键输入, 参数为等待时间 |
| cv.destroyAllwindows() | 释放所有窗口 |
函数imread()用于读取图像文件, 其用法为: cv.imread(filename[, flags])
其中flags为读取模式, 取值如下:
cv.IMREAD_GRAYSCALE: 将图像作为灰度图读取cv.IMREAD_COLOR: 默认值, 将图像作为BGR三通道彩色图像读取cv.IMREAD_ANYDEPTH: 当输入图像具有相应深度时返回 16 位/32 位图像,否则将其转换为 8 位图像cv.IMREAD_UNCHANGED: 载入原图(包括alpha通道)
更多参数可以查阅OpenCV官方文档
使用示例:
import cv2 as cvimport sysimg = cv.imread("cirno.png", cv.IMREAD_COLOR) #注意:imread不支持中文路径cv.imshow("hello opencv", img)if img is None: sys.exit("无法读取图像")cv.waitKey(0)cv.destroyAllWindows()使用imdecode()函数可以读取内存缓冲区中的图像, 配合fromfile()函数可完成中文路径的图像读取, 其用法为: cv.imdecode(buf, flags)
其中buf是存放图像数据的内存缓存, 通常用数组或字节向量表示. 如果内存缓冲区太短或者包含无效数据, 则返回空矩阵图像
使用示例:
import cv2 as cvimport sysimport numpy as npimg = cv.imdecode(np.fromfile("琪露诺.png", dtype=np.uint8), cv.IMREAD_GRAYSCALE)cv.imshow("hello opencv", img)if img is None: sys.exit("无法读取图像")cv.waitKey(0)cv.destroyAllWindows()由于读取到的图像都是用矩阵表示的, 因此可以获取图像的长宽和通道数:
img = cv.imread("cirno.png", cv.IMREAD_UNCHANGED)height, width, channels = np.shape(img)[:3]print("height=", height, "width=", width, "channels=", channels)height= 640 width= 640 channels= 4使用imwrite()可以输出图像到文件, 用法为: cv.imwrite(filename, img[, params])
其中params表示特定格式保存的参数, 例如:
cv.IMWRITE_PNG_COMPRESSION: 对于PNG格式保存, 压缩级别可在 0 到 9 之间. 值越高, 文件大小越小, 压缩时间越长, 默认值为1(最佳速度设置)cv.IMWRITE_JPEG_QUALITY: 对应JPEG格式保存, 质量范围在0~100, 默认值为95
更多参数可以查阅OpenCV官方文档
使用示例:
#把png图片右上角改为半透明, 并输出import cv2 as cv
img = cv.imread("cirno.png", cv.IMREAD_UNCHANGED)b, g, r, a = cv.split(img)print(a.shape)a[:int(a.shape[0]/2), int(a.shape[1]/2):] = 127img = cv.merge((b, g, r, a))cv.imshow("img", img)cv.waitKey(0)cv.destroyAllWindows()cv.imwrite("cirno1.png", img, [cv.IMWRITE_PNG_COMPRESSION, 9]) #opencv的查看窗口无法看到透明效果, 必须保存后查看基础图像处理
颜色空间转换
通过cvtColor()函数进行颜色空间的转换, 可以将图片转换成灰度图, 二值图, HSV以及HSI等不同颜色空间, 其用法为: cv.cvtColor(src, code[, dst[, dstCn]])
其中code表示颜色空间转换参数, dst表示输出与src相同大小和深度的图像, dstCn表示目标图像通道数, 其默认值为0, 即根据源图像和目标图像自动确定
#将图像分别转换为灰度图和HSV图像src_img = cv.imread("cirno.png", cv.IMREAD_UNCHANGED)gray_img = cv.cvtColor(src_img,cv.COLOR_BGR2GRAY)hsv_img = cv.cvtColor(src_img,cv.COLOR_BGR2HSV)h, s, v = cv.split(hsv_img)cv.imshow("gray_img", gray_img)cv.imshow("h", h) #色调cv.imshow("s", s) #饱和度cv.imshow("v", v) #灰度#由于opencv内部窗口只能显示BGR格式的图像, 所以不能正常显示HSV图像cv.waitKey(0)cv.destroyAllWindows()基本图形绘制
| 函数 | 描述 |
|---|---|
| cv.rectangle() | 绘制矩形 |
| cv.circle() | 绘制圆形 |
| cv.ellipse() | 绘制椭圆 |
| cv.line() | 绘制线段 |
| cv.polylines() | 绘制多边形 |
| cv.fillPoly() | 绘制填充多边形 |
更多绘制函数可以查看OpenCV官方文档
- 使用
rectangle()可以绘制矩形, 其用法为
cv.rectangle(img, pt1, pt2, color, thickness=1, lineType=LINE_8, shift=0)
或者
cv.rectangle(img, rec, color, thickness=1, lineType=LINE_8, shift=0)
其中pt1和pt2表示对角线的两个点坐标元组, rec表示左上角坐标和宽高组成的元组, color表示矩形的颜色或亮度(灰度图像), thickness表示线条粗细, 取负值时(如cv.FILLED)表示绘制填充矩形, lineType表示线条类型, shift表示点坐标的移位位数
- 使用
circle()可以绘制圆形, 其用法为
cv.circle(img, center, radius, color, thickness=1, lineType=LINE_8, shift=0)
其中center表示圆心坐标, radius表示半径
- 使用
ellipse()绘制椭圆, 其用法为
cv.ellipse(img, center, axes, angle, start_angle, end_angle, color, thickness=1, lineType=LINE_8, shift=0)
其中axes表示轴长, angle表示偏转角, start_angle和end_angle分别表示圆弧起始位置角度和终止位置角度
使用示例:
#在图像左上角分别绘制一个矩形, 圆形, 椭圆src_img = cv.imread("cirno.png", cv.IMREAD_UNCHANGED)rect_img = src_img.copy()cv.rectangle(rect_img, (30, 40), (130, 180), (255, 204, 102, 255), 2)cir_img = src_img.copy()cv.circle(cir_img, (150, 150), 80, (255, 204, 102, 255), 2)ellipse_img = src_img.copy()cv.ellipse(ellipse_img, (150, 150), (80, 40), -60, 0, 360, (255, 204, 102, 255), 2) #-60表示逆时针旋转椭圆输出图像:

- 使用polylines()可以绘制多边形, 其用法为
cv.polylines(img, pts, isClosed, color, thickness=1, lineType=LINE_8, shift=0)
其中pts表示包含多边形顶点的数组, isClosed表示绘制的多边形线段是否闭合
- 使用
fillPoly()可以绘制填充多边形, 其用法为
cv.fillPoly(img, pts, color, thickness=1, lineType=LINE_8, shift=0[, offset])
其中offset表示轮廓上所有点的偏移量, 方便绘制多个位置不同的相同多边形
使用示例:
src_img = cv.imread("cirno.png", cv.IMREAD_UNCHANGED)poly_img = src_img.copy()pts = np.array([(50, 40), (150, 60), (60, 180)], np.int32) #多边形点集, 数据类型一定要是int32cv.polylines(poly_img, [pts], True, (255, 204, 102, 255), 2)fillpoly_img = src_img.copy()cv.fillPoly(fillpoly_img, [pts], (255, 204, 102), offset=(80, 80)) #绘制填充多边形, 并且向右下方位移(80, 80)输出图像:
打印文字
使用putText()函数可以在图片上打印文字(注意, 该函数无法识别中文, 因此不能打印中文) 其用法为
cv.putText(img, text, org, fontFace, fontScale, color, thickness=1, lineType=LINE_8, bottomLeftOrigin=false)
其中text表示要绘制的文本字符串, org表示文本字符串的锚点坐标, fontFace字体类型,参见 HersheyFonts。fontScale字体缩放因子, 负数时会使文本镜像或者反转, bottomLeftOrigin默认为false, 即以左上角为锚点, 反之在左下角(但是我自己用的时候实际效果是字体颠倒了)
可以通过函数getTextSize()来确定文本框大小和基线偏移量(即文本框与基线的垂直距离), 方便绘制, 用法为
cv.getTextSize(text, fontFace, fontScale, thickness)
使用示例:
src_img = cv.imread("cirno.png", cv.IMREAD_UNCHANGED)text_img = src_img.copy()cv.putText(text_img, "Minaiice", (80, 80), cv.FONT_HERSHEY_COMPLEX, 2.0, (255, 204, 102, 255), 2)cv.imshow("text", text_img)输出图像:

添加边框
使用copyMakeBorder()可以为图像设置边界, 即在图像边沿进行额外填充, 用法如下
cv.copyMakeBorder(src, top, bottom, left, right, borderType[, dst[, value]])
其中top, bottom, left, right表示在原图像四个方向填充的像素量; borderType表示边界类型, 取值如下:
部分信息可能已经过时