Python 带有标题和边框周围空间的OpenCV子绘图图像
我希望在OpenCV Python中显示一些图像,每个子地块周围都有标题和边框。类似这样的事情(由下面的帖子提供:): 我想要什么: 但我只能通过修改代码来实现这一点Python 带有标题和边框周围空间的OpenCV子绘图图像,python,opencv,image-processing,Python,Opencv,Image Processing,我希望在OpenCV Python中显示一些图像,每个子地块周围都有标题和边框。类似这样的事情(由下面的帖子提供:): 我想要什么: 但我只能通过修改代码来实现这一点 import cv2 im1 = cv2.imread('Lenna.png') final_frame = cv2.hconcat((im1, im1)) cv2.imshow('lena', final_frame) 我拥有的 是否可以使用OpenCV获取此信息? 我知道一个解决办法是在图像上添加文本,但这不是我
import cv2
im1 = cv2.imread('Lenna.png')
final_frame = cv2.hconcat((im1, im1))
cv2.imshow('lena', final_frame)
我拥有的
是否可以使用OpenCV获取此信息?
我知道一个解决办法是在图像上添加文本,但这不是我想要的,因为这样可以覆盖重要信息
更新
我的缺点是,我最初没有指定:我有4个子图(因此有4个不同的图像),而不是示例中的两个。此外,我希望解决方案尽可能快,因为我有视频(时间限制)
我有一个快速而肮脏的解决方案。您可以根据自己的需要对其进行优化。我在代码旁边也有解释:
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)
您可以为不同的边界找到许多其他选项
总体思路是创建一个新图像,其宽度+=width/10和高度+=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)
导入cv2
将numpy作为np导入
img=cv2.imread(“/Users/anmoluppal/Downloads/Lenna.png”)
高度、宽度,ch=img.shape
新宽度,新高度=宽度+宽度/20,高度+高度/8
#用新的宽度和高度装入新的帆布箱。
画布=np.ones((新高度,新宽度,ch),数据类型=np.uint8)*125
#新建用原始图像替换画布中心
顶部填充,左侧填充=60,10
如果填充顶部+高度<新高度,填充左侧+宽度<新宽度:
画布[padding\u top:padding\u top+高度,padding\u left:padding\u left+宽度]=img
其他:
打印“给定的填充超出限制。”
text1=“示例图像1”
text2=“示例图像2”
img1=cv2.putText(canvas.copy(),text1,(int(0.25*width),30),cv2.FONT\u HERSHEY\u COMPLEX,1,np.array([255,0,0]))
img2=cv2.putText(canvas.copy(),text2,(int(0.25*width),30),cv2.FONT\u HERSHEY\u COMPLEX,1,np.array([255,0,0]))
最终=cv2.hconcat((img1,img2))
cv2.imwrite(“./debug.png”,最终版本)
我使用其他答案创建了一个可用于任意行/列的通用函数:
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图像:
希望这个答案有帮助。你可以修改它以满足你的要求。一个小评论。为什么不增加中顶部边框的大小,例如
常量=cv2.copyMakeBorder(img1100,10,10,10,cv2.border\u常量,value=black)
。这样就不再需要紫色的矩形了。我不是要找什么花哨的东西,而是要找一些快速简单的东西:)就像我说的,你可以随时修改它。您还可以调整文本的位置:我希望这对你有帮助:)嘿,这是一个更好的解决方案。伟大的工作伙伴!!!!我的方法很快又脏:不用担心,伙计,你的解决方案是使用内置方法,比如cv2.copyMakeBorder
,而不是数学,这对我来说很好,谢谢欣赏:)如果你有相同大小的图像,你必须小心numpy数组
将数组数组展平为n维数组。在本例中,是一个五维数组。我还没有找到一个好方法来强制numpy
保留数组数组,但是这个解决方法正在起作用:a1=np.random.random((300300,1))
a2=a1
imgs=np.empty([1,2],dtype=object)
imgs[0,0]=a1
imgs[0,1]=a2
#--- I finally concatenated both the above images horizontally---
final_img = cv2.hconcat((vcat, vcat))
cv2.imshow('Final', final_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
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)
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)