使用 OpenCV 组合两个图像
Posted
技术标签:
【中文标题】使用 OpenCV 组合两个图像【英文标题】:Combining Two Images with OpenCV 【发布时间】:2011-11-27 04:32:49 【问题描述】:我正在尝试使用 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
生成的图像是:
可能很难与网站的其他部分区分开来,但大部分图像都是白色的,对应于单个图像应该在的位置。黑色区域是没有写入图像数据的地方。
为什么我的所有图像数据都被转换为白色?
【问题讨论】:
你见过来自 OpenCV 2.3.1 的find_obj.py sample 吗?它看起来与您正在尝试做的完全一样。 @Andrey,是的,这实际上就是我要转换为 OpenCV 2.1 的内容。我没有 2.3 也无法编译,所以我现在正在使用 2.1。 你也可以创建一个关于你的编译问题的问题。我认为是可以解决的。请注意,此示例的 flann 部分无法使用 OpenCV 2.1 实现,因为 flann 索引的 python 绑定仅在 2.3.1 中添加。 【参考方案1】:对于您的图像恰好大小相同的情况(这是显示图像处理结果的常见情况),您可以使用 numpy 的连接来简化您的代码。
垂直堆叠(img1 over img2):
vis = np.concatenate((img1, img2), axis=0)
水平堆叠(img1在img2的左边):
vis = np.concatenate((img1, img2), axis=1)
验证:
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)
out.png 图像将在左侧包含 img1,在右侧包含 img2。
【讨论】:
垂直和水平的代码是一样的吗? 我修复了复制粘贴错误。水平方向沿轴 1。您可以自己轻松尝试。我在响应中添加了验证码。 并非总是如此ValueError: all the input array dimensions except for the concatenation axis must match exactly
如何添加偏移量以使两张图像重叠一点?
这救了我的命!!非常感谢。【参考方案2】:
对于希望将 2 个彩色图像合二为一的用户, 这是对安德烈的回答的一个小修改,对我有用:
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
【讨论】:
【参考方案3】: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()
或者如果您更喜欢传统方式:
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()
【讨论】:
cv2.COLOR_GRAY2BGR 在 OpenCV 2.3 中似乎不存在。此外,您还可以读取灰度图像,然后将它们转换回 RGB。所以你的结果会是灰度的不是吗? 我们可以为彩色图像执行此操作吗??【参考方案4】:您还可以使用 OpenCV 的内置函数 cv2.hconcat
和 cv2.vconcat
,正如它们的名字所暗示的,它们分别用于水平和垂直连接图像。
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()
水平串联
垂直串联
【讨论】:
【参考方案5】:在 OpenCV 3.0 中,您可以按如下方式轻松使用它:
#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')
【讨论】:
【参考方案6】:使用一行代码的三种最佳方法
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)
【讨论】:
【参考方案7】:为了水平堆叠:
imgHor = np.hstack((img, img))
为了垂直堆叠:
imgVer = np.vstack((img, img))
为了显示:
cv2.imshow("Horizontal", imgHor) # horizontal stack
cv2.imshow("Vertical", imgVer) # vertical stack
【讨论】:
以上是关于使用 OpenCV 组合两个图像的主要内容,如果未能解决你的问题,请参考以下文章
使用Python,OpenCV旋转图像任意角度(完整和局部丢失~)