OpenCV在边界周围绘制带有标题和空格的图像

时间:2017-02-23 15:54:13

标签: python opencv image-processing

我希望在 OpenCV Python 中显示一些图像,每个子图周围都有标题和边框。这样的事情(由以下stackoverflow帖子提供:OpenCV (Python) video subplots):

我想要什么: enter image description here

但我只是设法改编了代码。

 import cv2
 im1 = cv2.imread('Lenna.png')
 final_frame = cv2.hconcat((im1, im1))
 cv2.imshow('lena', final_frame)

我有什么 enter image description here

是否可以使用OpenCV获得此功能?  我知道一种解决方法是将文本放在图像上,但这不是我想要的,因为它将以这种方式覆盖重要信息。

更新

我的不好,我最初没有说明:我有4个子图(所以4个不同的图像),而不是像示例中的两个。此外,我希望解决方案尽可能快,因为我有视频(时间限制)

enter image description here

3 个答案:

答案 0 :(得分:5)

我有一个非常快速和肮脏的解决方案。您可以根据自己的需要进行优化。我也在代码旁边做了解释:

import cv2
import numpy as np

img1 = cv2.imread('lena.jpg')

#--- Here I am creating the border---
black = [0,0,0]     #---Color of the border---
constant=cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_CONSTANT,value=black )
cv2.imshow('constant',constant)

enter image description here

您可以找到不同边框的许多其他选项ON THIS PAGE

#--- Here I created a violet background to include the text ---
violet= np.zeros((100, constant.shape[1], 3), np.uint8)
violet[:] = (255, 0, 180) 

enter image description here

#--- I then concatenated it vertically to the image with the border ---

vcat = cv2.vconcat((violet, constant))
cv2.imshow('vcat', vcat)

enter image description here

#--- Now I included some text ---
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(vcat,'FRAME',(30,50), font, 2,(0,0,0), 3, 0)
cv2.imshow('Text', vcat)

enter image description here

#--- I finally concatenated both the above images horizontally---
final_img = cv2.hconcat((vcat, vcat))
cv2.imshow('Final', final_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

enter image description here

答案 1 :(得分:5)

一般的想法是使用width += width/10height += height/20创建新图片。将一些文本写为标题并将输入图像沿中心放置为:

import cv2
import numpy as np


img = cv2.imread("/Users/anmoluppal/Downloads/Lenna.png")

height, width, ch = img.shape
new_width, new_height = width + width/20, height + height/8

# Crate a new canvas with new width and height.
canvas = np.ones((new_height, new_width, ch), dtype=np.uint8) * 125

# New replace the center of canvas with original image
padding_top, padding_left = 60, 10
if padding_top + height < new_height and padding_left + width < new_width:
    canvas[padding_top:padding_top + height, padding_left:padding_left + width] = img
else:
    print "The Given padding exceeds the limits."

text1 = "Sample Image 1"
text2 = "Sample Image 2"
img1 = cv2.putText(canvas.copy(), text1, (int(0.25*width), 30), cv2.FONT_HERSHEY_COMPLEX, 1, np.array([255, 0, 0]))
img2 = cv2.putText(canvas.copy(), text2, (int(0.25*width), 30), cv2.FONT_HERSHEY_COMPLEX, 1, np.array([255, 0, 0]))

final = cv2.hconcat((img1, img2))
cv2.imwrite("./debug.png", final)

enter image description here

答案 2 :(得分:4)

我使用了其他答案来创建可用于任意行/列的通用化功能:

def cvSubplot(imgs,     # 2d np array of imgs (each img an np arrays of depth 1 or 3).
              pad=10,   # number of pixels to use for padding between images. must be even
              titles=None,  # (optional) np array of subplot titles
              win_name='CV Subplot' # name of cv2 window
              ):
    '''
    Makes cv2 based subplots. Useful to plot image in actual pixel size
    '''

    rows, cols = imgs.shape

    subplot_shapes = np.array([list(map(np.shape, x)) for x in imgs])
    sp_height, sp_width, depth = np.max(np.max(subplot_shapes, axis=0), axis=0)

    title_pad = 30
    if titles is not None:
        pad_top = pad + title_pad
    else:
        pad_top = pad

    frame = np.zeros((rows*(sp_height+pad_top), cols*(sp_width+pad), depth ))

    for r in range(rows):
        for c in range(cols):
            img = imgs[r, c]
            h, w, _ = img.shape
            y0 = r * (sp_height+pad_top) + pad_top//2
            x0 = c * (sp_width+pad) + pad//2
            frame[y0:y0+h, x0:x0+w, :] = img

            if titles is not None:
                frame = cv2.putText(frame, titles[r, c], (x0, y0-title_pad//4), cv2.FONT_HERSHEY_COMPLEX, .5, (255,255,255))

    cv2.imshow(win_name, frame)
    cv2.waitKey(0)

以下是用法示例:

import cv2
import numpy as np

a1 = np.random.random((40,400,1))
a2 = np.random.random((200,200,1))
a3 = np.random.random((100,100,1))
a4 = np.random.random((300,150,1))
a5 = np.random.random((100,150,1))
filler = np.zeros((0,0,1))

titles = np.array([['A', 'B', 'C'], ['D', 'E', 'Filler']])

imgs = np.array([[a1, a2, a3], [a4, a5, filler]])

cvSubplot(imgs, pad=20, titles=titles)

该脚本产生以下cv2图像:

enter image description here