在全局matplotlib图中,我想要一些不同大小的子图。例如,一个子图应该是从opencv2(网络摄像头)捕获的帧的确切大小,另一个应该是从该帧获得的较小图像。
我有两个不同的问题,都涉及到尺寸调整:
获取框架:
import cv2
import matplotlib.pyplot as plt
cap = cv2.VideoCapture(0)
ret, frame = cap.read()
构建图和子图:
fig = plt.figure()
img = fig.add_subplot(121)
img2 = fig.add_subplot(122)
然后将帧放入子图
img.imshow(frame) #this should be the original size of captured frame
#take out a square of the frame, and plot with box dimensions
#img2.imshow(box)
干杯!
------编辑------
虽然我将使用网络摄像头拍摄图像,但问题的核心是: 1.使用opencv打开图像 2.将图像绘制成一个子图,与opencv读取图像具有相同的维度
代码:
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('flower.jpg')
cv2.imshow('img',img)
fig = plt.figure()
video_plot = plt.subplot2grid((10, 10), (0, 0)) #Here I need to specify the same size as original
video = video_plot.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
cv2.waitKey(0)
cv2.destroyAllWindows()
plt.show()
原始256x256图片,用opencv打开读取
较小的图像,如果我省略了colspan和rowspan(= 1) plt.subplot2grid((10,10),(0,0))
更大的图像,如果我最大限度地使用colspan和rowspan: plt.subplot2grid((10,10),(0,0),colspan = 10,rowspan = 10)
总而言之,我如何绘制相同的图像尺寸?
答案 0 :(得分:0)
图形尺寸确实以英寸为单位。在matplotlib中也指定了每英寸点数(dpi)。
知道以英寸为单位的图形尺寸和dpi允许您通过将像素除以dpi和图形大小来将轴定位在图形坐标(从0到1)中。例如。为了将轴放置在距离左下角50像素的位置,您可以将轴放在
处fig.add_axes([50./dpi/figsize[0], 50./dpi/figsize[1], ...])
宽度和高度的类比取决于每个方向的像素数除以dpi和数字大小(以英寸为单位)。
完整示例:
import matplotlib.pyplot as plt
import numpy as np; np.random.seed(0)
ar = np.random.poisson(lam=10, size=(250,300))
cut = ar[50:100, 200:250]; print cut.shape
dpi=100. # dots per inch
figsize=(5, 3.5)
fig = plt.figure(figsize=figsize)
ax = fig.add_axes([50./dpi/figsize[0],50./dpi/figsize[1],
ar.shape[1]/dpi/figsize[0],ar.shape[0]/dpi/figsize[1]])
im = ax.imshow(ar)
ax2 = fig.add_axes([100./dpi/figsize[0]+ar.shape[1]/dpi/figsize[0],50./dpi/figsize[1],
cut.shape[1]/dpi/figsize[0],cut.shape[0]/dpi/figsize[1]])
im2 = ax2.imshow(cut)
ax.axis("off")
plt.show()
答案 1 :(得分:0)
@ImportanceOfBeingErnes的解决方案为我工作,但我很难理解它。问题在于opencv和matplotlib图像从数组中提取的宽度/高度不同。我更喜欢使用可读的变量名来隐藏这种复杂性。
因此,此辅助函数是获取适当轴的核心:
def addImage(fig,image,x,y):
dpi=fig.dpi
fw,fh=fig.get_size_inches()[:2]
ih,iw=image.shape[:2]
ax = fig.add_axes([x/dpi/fw,y/dpi/fh,iw/dpi/fw,ih/dpi/fh])
return ax
#!/usr/bin/python
# -*- encoding: utf-8 -*-
# part of https://github.com/WolfgangFahl/play-chess-with-a-webcam
# see https://stackoverflow.com/questions/43372792/matplotlib-opencv-image-subplot
import matplotlib.pyplot as plt
import sys
import cv2
def main(argv):
# get the square chessbord file as an example
default_file = '../../testMedia/chessBoard011.jpg'
filename = argv[0] if len(argv) > 0 else default_file
image = cv2.imread(filename)
cv2.cvtColor(ima,cv2.COLOR_BGR2RGB)
# resize it to fit at the default 100 dpi
w=320
h=320
x=50
y=50
image = cv2.resize(image,(w,h))
# 6 x 4 inch figure
figsize=(6, 4)
fig = plt.figure(figsize=figsize)
# add the image at position x=50, y=50 (in image coordinates)
ax=addImage(fig,image,x,y)
im = ax.imshow(image)
subboard2x2=image[w//4:w//2,h//4:h//2,:]
yLegendOffset=100
ax2=addImage(fig,subboard2x2,w+yLegendOffset,h//2)
im2=ax2.imshow(subboard2x2)
ax.axis("off")
plt.show()
def addImage(fig,image,x,y):
dpi=fig.dpi
fw,fh=fig.get_size_inches()[:2]
ih,iw=image.shape[:2]
ax = fig.add_axes([x/dpi/fw,y/dpi/fh,iw/dpi/fw,ih/dpi/fh])
return ax
if __name__ == "__main__":
main(sys.argv[1:])