首页 > 编程笔记 > Python笔记 阅读:2

OpenCV hstack()函数的用法(附带实例)

在某些场景下,比如有多个摄像头视频图像,如果一个视频图像显示在一个窗口中,则会因为窗口过多而显得凌乱。此时就需要一个窗口能显示多个视频图像。

要达到这个效果,原理并不复杂,只需要调整每个视频的尺寸大小为窗口的一部分,这样多个图像组合起来正好可以占满一个窗口。在 OpenCV 中,我们可以利用 hstack() 函数来实现单窗口显示多幅图像。

hstack() 函数就是把两个行相同的数组或者矩阵的列从左到右排列起来,也就是把列水平排列起来,其声明如下:
numpy.hstack(tup)
其中,tup 是 ndarrays 数组序列。这里说的数组就是 NumPy 库的 array,比如定义了一个 3 行 5 列的二维矩阵:
a=np.array([[ 0,  1,  2,  3,  4],
    [ 5,  6,  7,  8,  9],
    [10, 11, 12, 13, 14]])

print(a.shape)  # 输出 (3, 5)

这里的行数是矩阵的高度,列数是矩阵的宽度。比如建立一个一维矩阵 b,长度为 b.shape:
b =np.array([1,2,3,4])
print(b.shape)
输出是(4,),4 就是一维矩阵的长度,因为不存在二维,也就没有二维的长度,所以括号里的逗号后面是空的。

再比如建立 4 行 2 列的二维矩阵:
c =np.array([[1,1],[1,2],[1,3],[1,4]])
print(c.shape)
输出是 (4,2),shape[0] 表示行数,这里是 4 行,shape[1] 表示列数,这里是 2 列。注意方括号的数量。

有时候方括号也可以用圆括号来表示,比如 2 行 3 列的二维矩阵:
x = np.array(((1,2,3),(4,5,6)))  #2行3列
print(x.shape)
输出是 (2,3)。注意圆括号的数量匹配。

简单复习 array 基本知识后,我们可以用 hstack 函数来合并行数相同的数组,比如合并两个都是 1 行的一维数组:
a = np.array((1,2,3))    #1行3列
b = np.array((4,5,6,7))  #1行4列
e = np.hstack((a,b))
print(e)
输出:

array([1, 2, 3, 4,5,6,7])  #结果依然是1行


又比如合并 3 个两行的二维数组:
a = np.array([[1,2],[3,4]])
b = np.array(((1,2,3),(4,5,6)))  #2行3列
c = np.array(((1,1,1,1),(2,2,2,2)))
e = np.hstack((a,b,c))
print(e)
输出:

[[1 2 1 2 3 1 1 1 1]
[3 4 4 5 6 2 2 2 2]]

了解了 hstack() 函数后,我们可以在一个窗口中显示多幅图片,原理是直接将通过 imread() 函数返回的二维矩阵传入 hstack() 函数中。

【实例】单窗口中显示多幅图片。
import cv2 as cv
import numpy as np #导入numpy模块
def opecv_muti_pic():
    img1 = cv.imread('1.jpg')
    print(img1.shape)
    img2 = cv.imread('2.jpg')
    print(img2.shape)
    img3 = cv.imread('3.jpg')
    print(img3.shape)
    imgs = np.hstack([img1,img2,img3])
    #展示多个
    cv.imshow("mutil_pic", imgs)
    #等待关闭
    cv.waitKey(0)

opecv_muti_pic()
在上述代码中,首先读取了 3 幅图片,并各自返回了二维矩阵数组。这 3 幅图片在工程目录下可以找到,为了节省篇幅,这里不对是否读取成功进行判断,但一线企业开发不能少了这个判断。

随后,把 3 幅图片的矩阵传入 hstack() 函数中进行合并,并返回合并后的矩阵,然后通过 imshow 显示出来。我们每次读取一幅图片,就把它的宽度和高度打印出来。可以发现,高度(行数)都是相同的,否则是不能用于 hstack 的。例如,把图片 3 缩放后保存,再运行程序,就会报错。

运行工程,结果如下图所示:

相关文章