用 OpenCV 结合两幅图像

我正在尝试使用 OpenCV 2.1将两个图像组合成一个图像,两个图像相邻放置。在 Python 中,我正在做:

import numpy as np, cv


img1 = cv.LoadImage(fn1, 0)
img2 = cv.LoadImage(fn2, 0)


h1, w1 = img1.height,img1.width
h2, w2 = img2.height,img2.width


# Create an array big enough to hold both images next to each other.
vis = np.zeros((max(h1, h2), w1+w2), np.float32)


mat1 = cv.CreateMat(img1.height,img1.width, cv.CV_32FC1)
cv.Convert( img1, mat1 )


mat2 = cv.CreateMat(img2.height, img2.width, cv.CV_32FC1)
cv.Convert( img2, mat2 )


# Copy both images into the composite image.
vis[:h1, :w1] = mat1
vis[:h2, w1:w1+w2] = mat2


h,w = vis.shape
vis2 = cv.CreateMat(h, w, cv.CV_32FC3)
vis0 = cv.fromarray(vis)
cv.CvtColor(vis0, vis2, cv.CV_GRAY2BGR)
cv.ShowImage('test', vis2)
cv.WaitKey()

这两个输入图像是:

Https://code.ros.org/trac/opencv/browser/trunk/opencv/samples/c/box.png?rev=2270

Https://code.ros.org/trac/opencv/browser/trunk/opencv/samples/c/box_in_scene.png?rev=2270

由此产生的图像是:

enter image description here

它可能很难与网站的其他部分区分开来,但是大部分图像是白色的,对应于单个图像应该在的位置。黑色区域是没有写入图像数据的地方。

为什么我所有的图像数据都被转换为白色?

224003 次浏览
import numpy as np, cv2


img1 = cv2.imread(fn1, 0)
img2 = cv2.imread(fn2, 0)
h1, w1 = img1.shape[:2]
h2, w2 = img2.shape[:2]
vis = np.zeros((max(h1, h2), w1+w2), np.uint8)
vis[:h1, :w1] = img1
vis[:h2, w1:w1+w2] = img2
vis = cv2.cvtColor(vis, cv2.COLOR_GRAY2BGR)


cv2.imshow("test", vis)
cv2.waitKey()

or if you prefer legacy way:

import numpy as np, cv


img1 = cv.LoadImage(fn1, 0)
img2 = cv.LoadImage(fn2, 0)


h1, w1 = img1.height,img1.width
h2, w2 = img2.height,img2.width
vis = np.zeros((max(h1, h2), w1+w2), np.uint8)
vis[:h1, :w1] = cv.GetMat(img1)
vis[:h2, w1:w1+w2] = cv.GetMat(img2)
vis2 = cv.CreateMat(vis.shape[0], vis.shape[1], cv.CV_8UC3)
cv.CvtColor(cv.fromarray(vis), vis2, cv.CV_GRAY2BGR)


cv.ShowImage("test", vis2)
cv.WaitKey()

For cases where your images happen to be the same size (which is a common case for displaying image processing results), you can use numpy's concatenate to simplify your code.

To stack vertically (img1 over img2):

vis = np.concatenate((img1, img2), axis=0)

To stack horizontally (img1 to the left of img2):

vis = np.concatenate((img1, img2), axis=1)

To verify:

import cv2
import numpy as np
img1 = cv2.imread('img1.png')
img2 = cv2.imread('img2.png')
vis = np.concatenate((img1, img2), axis=1)
cv2.imwrite('out.png', vis)

The out.png image will contain img1 on the left and img2 on the right.

For those who are looking to combine 2 color images into one, this is a slight mod on Andrey's answer which worked for me :

img1 = cv2.imread(imageFile1)
img2 = cv2.imread(imageFile2)


h1, w1 = img1.shape[:2]
h2, w2 = img2.shape[:2]


#create empty matrix
vis = np.zeros((max(h1, h2), w1+w2,3), np.uint8)


#combine 2 images
vis[:h1, :w1,:3] = img1
vis[:h2, w1:w1+w2,:3] = img2

in OpenCV 3.0 you can use it easily as follow:

#combine 2 images same as to concatenate images with two different sizes
h1, w1 = img1.shape[:2]
h2, w2 = img2.shape[:2]
#create empty martrix (Mat)
res = np.zeros(shape=(max(h1, h2), w1 + w2, 3), dtype=np.uint8)
# assign BGR values to concatenate images
for i in range(res.shape[2]):
# assign img1 colors
res[:h1, :w1, i] = np.ones([img1.shape[0], img1.shape[1]]) * img1[:, :, i]
# assign img2 colors
res[:h2, w1:w1 + w2, i] = np.ones([img2.shape[0], img2.shape[1]]) * img2[:, :, i]


output_img = res.astype('uint8')

You can also use OpenCV's inbuilt functions cv2.hconcat and cv2.vconcat which like their names suggest are used to join images horizontally and vertically respectively.

import cv2


img1 = cv2.imread('opencv/lena.jpg')
img2 = cv2.imread('opencv/baboon.jpg')


v_img = cv2.vconcat([img1, img2])
h_img = cv2.hconcat([img1, img2])


cv2.imshow('Horizontal', h_img)
cv2.imshow('Vertical', v_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Horizontal Concatenation

Horizontal

Vertical Concatenation

Vertical

The three best way to do it using a single line of code

import cv2
import numpy as np




img = cv2.imread('Imgs/Saint_Roch_new/data/Point_4_Face.jpg')
dim = (256, 256)
resizedLena = cv2.resize(img, dim, interpolation = cv2.INTER_LINEAR)
X, Y = resizedLena, resizedLena


# Methode 1: Using Numpy (hstack, vstack)
Fusion_Horizontal = np.hstack((resizedLena, Y, X))
Fusion_Vertical   = np.vstack((newIMG, X))


cv2.imshow('Fusion_Vertical using vstack', Fusion_Vertical)
cv2.waitKey(0)


# Methode 2: Using Numpy (contanate)
Fusion_Vertical   = np.concatenate((resizedLena, X, Y), axis=0)
Fusion_Horizontal = np.concatenate((resizedLena, X, Y), axis=1)


cv2.imshow("Fusion_Horizontal usung concatenate", Fusion_Horizontal)
cv2.waitKey(0)




# Methode 3: Using OpenCV (vconcat, hconcat)
Fusion_Vertical   = cv2.vconcat([resizedLena, X, Y])
Fusion_Horizontal = cv2.hconcat([resizedLena, X, Y])


cv2.imshow("Fusion_Horizontal Using hconcat", Fusion_Horizontal)
cv2.waitKey(0)

In order to stack horizontally:

imgHor = np.hstack((img, img))

In order to stack vertically:

imgVer = np.vstack((img, img))

In order to display:

cv2.imshow("Horizontal", imgHor) # horizontal stack
cv2.imshow("Vertical", imgVer)   # vertical stack