Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV subplots images with titles and space around borders

I am looking to display some images in OpenCV Python with titles and borders around the each subplot. something like this (courtesy of the following stackoverflow post: OpenCV (Python) video subplots):

WHAT I WANT: enter image description here

But I only manage to get this with that code adapted.

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

WHAT I HAVE enter image description here

Is it possible to obtain this using OpenCV? I know a workaround would be to put text on the images, but that's not what I want because it will cover important information that way.

UPDATE

My bad, I didn't specify initially: I have 4 subplots (so 4 different images) and not two like in the example. Also, I want the solution to be as fast as possible since I have video (time restrictions)

enter image description here

like image 800
RMS Avatar asked Nov 29 '22 09:11

RMS


2 Answers

The general idea would be to create a new image with width += width/10 and height += height/20. Write some text as heading and place the input image along the center as:

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

like image 38
ZdaR Avatar answered Dec 04 '22 06:12

ZdaR


I have a pretty quick and dirty solution. You can refine it to suit your needs. I have the explanation alongside the code as well:

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

You can find many other options for different borders 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

like image 51
Jeru Luke Avatar answered Dec 04 '22 05:12

Jeru Luke