导入模块:
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
cv.imread(firepath, flags=1)
读取图像
firepath 图像的路径
flags 图像的打开方式
返回值 返回一个图像对象,实际上是一个三维矩阵cv.imwrite(firepath, img)
firepath 图像的保存路径
img 要保存的图像对象
flags参数 | 属性 | 含义 |
---|---|---|
1 | cv.IMREAD_COLOR | 以彩色模式加载图像,任何图像的透明度都将被忽略,这是默认参数 |
0 | cv.IMREAD_GRAYSCALE | 以灰度模式加载图像 |
-1 | cv.IMREAD_UNCHANGED | 包括alpha通道的加载图像模式 |
cv.imshow(winname, mat)
显示图像
winname 图像显示窗口的名称,字符串的形式
mat 要显示的图像对象cv.waitKey(time)
图像的停留时间
time=0 时表示图像一直停留cv.destroyAllWindows()
按任意键可以停止 waitKey(time) 的等待,并关闭所有图像
例:
img = cv.imread("HappyFish.jpg", 1)
cv.imshow("HappyFish", img)
cv.waitKey(0)
在 OpenCV 中,读取和表达图像的方式是B-G-R通道,(Blue-Green-Red)
在 OpenCV 中,图像对象实际上是一个 M×N×3 的三维矩阵,数据类型一般为 uint8 [0, 255],如图所示:
例:分别显示出一张彩色图像的 B-G-R 灰度 [0, 255]
img = cv.imread("HappyFish.jpg", 1)
# B
img_b = img[:, :, 0]
# G
img_g = img[:, :, 1]
# R
img_r = img[:, :, 2]
cv.imshow("B", img_b)
cv.imshow("G", img_g)
cv.imshow("R", img_r)
# 原图
cv.imshow("img", img)
此外,在 Matplotlib 中,读取和表达图像的方式是R-G-B通道,显然,如果想要使 OpenCV 打开的图像通过 Matplotlib 来表达,就需要通道的转换,很显然,B-G-R通道 ⇨ R-G-B通道 的转换,只需要将一维矩阵中的元素反转即可
img[:, :, ::-1]
对图像对象进行通道转换,即一维矩阵的反转
img[:, ::-1, :]
对图像进行列翻转,即对图像进行水平翻转
img[::-1, :, :]
对图像进行行翻转,即对图像进行竖直翻转
注:还可以多处进行 ::-1 处理
plt.imshow(img, cmap=)
使用 Matplotlib 来显示图像,通道:R-G-B
img 要显示的图像
cmap= 图像显示的颜色图谱plt.show()
显示图像
cmap参数 | 含义 |
---|---|
plt.cm.autumn | 红-橙-黄 |
plt.cm.bone | 黑-白,x线 |
plt.cm.cool | 青-洋红 |
plt.cm.copper | 黑-铜 |
plt.cm.flag | 红-白-蓝-黑 |
plt.cm.gray | 黑-白 |
plt.cm.hot | 黑-红-黄-白 |
plt.cm.hsv | hsv颜色空间, 红-黄-绿-青-蓝-洋红-红 |
plt.cm.inferno | 黑-红-黄 |
plt.cm.jet | 蓝-青-黄-红 |
plt.cm.magma | 黑-红-白 |
plt.cm.pink | 黑-粉-白 |
plt.cm.plasma | 绿-红-黄 |
plt.cm.prism | 红-黄-绿-蓝-紫-…-绿模式 |
plt.cm.spring | 洋红-黄 |
plt.cm.summer | 绿-黄 |
plt.cm.viridis | 蓝-绿-黄 |
plt.cm.winter | 蓝-绿 |
img_cv = cv.imread("HappyFish.jpg", 1)
img_plt = img_cv[:, :, ::-1]
# 原图在OpenCV中的显示
cv.imshow("img_cv", img_cv)
# 反转图在OpenCV中的显示
cv.imshow("img_plt_in_cv", img_plt)
# 反转图在Matplotlib中显示
plt.imshow(img_plt)
plt.show()
cv.waitKey(0)
cv.destroyAllWindows()
cv.line(img, start, end, color, thickness, lineType)
绘制直线
img 要绘制直线的图像
start, end 直线的起点和终点
color 直线的颜色,用(B, G, R)表示
thickness 线条宽度
lineType 线条类型cv.circle(img, centerpoint, radius, color, thickness, lineType)
绘制圆形
img 要绘制圆形的图像
centerpoint, radius 圆形的圆心和半径
color 线条的颜色,用(B, G, R)表示
thickness 线条宽度,为-1时生成闭合的图案并填充线条颜色
lineType 线条类型cv.rectangle(img, leftupper, rihtdown, color, thickness, lineType)
绘制矩形
img 要绘制矩形的图像
leftupper, rightdown 矩形的左上角和右下角坐标
color 线条的颜色,用(B, G, R)表示
thickness 线条宽度,为-1时生成闭合的图案并填充线条颜色
lineType 线条类型cv.putText(img, text, station, font, fontsize, color, thickness, cv.LINE_AA)
向图像中添加文字
img 要添加文字的图像
text 要写入的文本内容
station 文本的放置位置
font 字体
fontsize 字体大小
color 线条的颜色,用(B, G, R)表示
thickness 线条宽度
cv.LINE_AA 一种线条类型
例:绘制多个图案
# 创建一个全黑的三维矩阵作为图像对象
img = np.zeros((512, 512, 3), np.uint8)
# 绘制图形
cv.line(img, (0, 0), (511, 511), color=(255, 0, 0), thickness=5)
cv.rectangle(img, (384, 0), (510, 128), color=(0, 255, 0), thickness=3)
cv.circle(img, (447, 63), radius=63, color=(0, 0, 255), thickness=-1)
# 添加字体
font = cv.FONT_HERSHEY_SIMPLEX
cv.putText(img, "OpenCV", (10, 500), font, 4, (255, 255, 255), thickness=2, lineType=cv.LINE_AA)
# 显示图像
plt.imshow(img[:, :, ::-1])
plt.title("result"), plt.xticks([]), plt.yticks([])
plt.show()
前面已经提到,图像对象实际上是一个三维矩阵,因此我们可以通过对三维矩阵的操作来实现对图像的操作
当我们只指定图像对象的行、列下标时,我们就可以获得图像的B-G-R的1×3一维数组
例:
img = cv.imread("HappyFish.jpg", 1)
# 获取某个像素点的值——(100, 100)
px = img[100, 100]
# 仅获取蓝色通道的强度值
px_blue = img[100, 100, 0]
# 修改某些位置的像素值
img[0:100, 0:100] = [255, 0, 255]
cv.imshow("img", img)
cv.waitKey(0)
cv.destroyAllWindows()
图像属性 | 含义 |
---|---|
shape | 图像的像素形状 |
size | 像素的总个数,M×N |
dtype | 每个像素的数据类型 |
b, g, r = cv.split(img)
把图像对象分别拆分成b,g,r三个通道的二维矩阵
img = cv.merge((b, g, r))
把b,g,r三个通道合并成一张图像
例:
import cv2 as cv
img = cv.imread("HappyFish.jpg", 1)
# 拆分通道
b, g, r = cv.split(img)
cv.imshow("B", b)
cv.imshow("G", g)
cv.imshow("R", r)
# 合并通道,即原图
cv.imshow("img", cv.merge((b, g, r)))
cv.waitKey()
cv.destroyAllWindows()
OpenCV 中有150多种颜色空间转换方法,其中最广泛使用的转换方法有两种,B-G-R↔Gray(灰度图) 和 B-G-R↔HSV(深度色彩的彩色图)
cv.cvtColor(input_img, flag)
返回一个改变色彩空间后的图像对象
input_img 要进行转换的图像
flag 转换类型:
- cv.COLOR_BGR2GRAY:B-G-R→Gray
- cv.COLOR_GRAY2BGR:Gray→B-G-R
- cv.COLOR_BGR2HSV:B-G-R→HSV
- cv.COLOR_HSV2BGR:HSV→B-G-R
例:
img = cv.imread("HappyFish.jpg", 1)
img = cv.cvtColor(img, cv.COLOR_BGR2HSV)
cv.imshow("HSV", img)
cv.waitKey()
cv.destroyAllWindows()
可以使用 OpenCV 中的 cv.add() 函数把两幅图像相加,或者可以直接通过 Numpy 操作添加两个图像,如:res = img1 + img2,两个图像应该具有相同的大小和数据类型,或者可以和一个标量进行相加
注:由于图像通道的数据类型一般为 uint8 [0, 255] ,因此在进行图像的加法时可能会溢出,当数据溢出时,OpenCV加法 和 Numpy加法 之间存在差异, OpenCV加法 是饱和操作,而 Numpy加法 是模运算,见以下代码:
x = np.uint8([250])
y = np.uint8([10])
print(cv.add(x, y))
out: 250+10 = 260 ⇨ 255
print(x+y)
out: 250+10 = 260 % 256 = 4
cv.add(img1, img2)
将 img1 和 img2 两张图片相加
注:两张图片的大小须一致
例:分别显示用 Numpy 和 OpenCV 作图像相加的效果
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 读取图像
img1 = cv.imread("Cloud.jpg", 1)
img2 = cv.imread("Building.jpg", 1)
# 加法操作
img_np = img1 + img2
img_cv = cv.add(img1, img2)
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10, 8))
axes[0, 0].imshow(img1[:, :, ::-1])
axes[0, 0].set_title("Cloud")
axes[0, 1].imshow(img2[:, :, ::-1])
axes[0, 1].set_title("Building")
axes[1, 0].imshow(img_np[:, :, ::-1])
axes[1, 0].set_title("img_np")
axes[1, 1].imshow(img_cv[:, :, ::-1])
axes[1, 1].set_title("img_cv")
plt.show()
图像的混合实际上也是加法,但是要相加的两幅图像的权重不同,不同的权重表示具有不同的透明度,一般为 0~1
公式表示为: dst = α·img1 + β·img2 + γ
cv.addWeighted(src1, alpha, src2, beta, gamma)
按权重和偏移值对图像进行混合
src1 第一张图片
alpha 第一张图片的权值
src2 第二张图片
beta 第二张图片的权值
gamma 偏移值
img1 = cv.imread("Cloud.jpg", 1)
img2 = cv.imread("Building.jpg", 1)
img = cv.addWeighted(img1, 0.5, img2, 1, 10)
cv.imshow("img", img)
cv.waitKey(0)
cv.destroyAllWindows()