在有些项目中需要在一个窗口画面中显示多个子画面【这里说的不是plt.subplot()】,比如像下面这种,可以将狗头在画面的右下角进行显示。比如你是做目标检测或者跟踪等,你现在想要将检测后的目标在画面右下角显示或要进一步处理,那么这篇文章可以帮到你。
其实很简单,就是获取目标的尺寸,然后在你原图中开一个窗口,把该目标放进去。
第一步:获取目标坐标
比如,这张狗的原始图像尺寸为(375,499,3)
然后获取了一下狗头的左上角坐标和右下角坐标分别为:(182,123)和(283,210)。我们可以显示一下这个狗头
crop_img = img[123:210, 182:283] # 在原图中获取狗头
第二步:开子窗口
现在想把狗头在原图右下角显示(当然你可以在其他位置显示),比如下图所示,那么我们就需要算一下这个窗口的大小,比如我这的子窗口是固定大小(尺寸为100*100),你也可以根据目标大小来设置.
crop_img = cv2.resize(crop_img, (100, 100)) # 把狗头reshape成100*100
# 获取子窗口坐标,W,H是原图的尺寸
windows_x1 = W - crop_img.shape[1]
windows_y1 = H - crop_img.shape[0]
windows_x2 = W
windows_y2 = H
第三步:将目标放进子窗口
接下来就可以将目标放进原图中开辟的子窗口了
img[windows_y1:windows_y2, windows_x1:windows_x2] = crop_img
完整代码:
'''
(0,0)—————————————————— W (x)
|
|
|
|
|
|
H(y)
dog.jpg shape (375,499,3)
狗头位置:x1:182,y1:123
x2:283 y2:210
'''
img = cv2.imread("dog.jpg")
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
H, W, _ = img.shape
crop_img = img[123:210, 182:283] # 获取狗头区域(根据自己的图像需要自己调)
crop_img = cv2.resize(crop_img, (100, 100)) # 将狗头resize成100*100大小
windows_x1 = W - crop_img.shape[1]
windows_y1 = H - crop_img.shape[0]
windows_x2 = W
windows_y2 = H
img[windows_y1:windows_y2, windows_x1:windows_x2] = crop_img
plt.imshow(img)
plt.show()
效果图:
多画面视频显示
结合上面的思路,就可以进行多画面的视频显示啦,完整代码如下:
cap = cv2.VideoCapture(0)
fps = cap.get(cv2.CAP_PROP_FPS)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
out = cv2.VideoWriter("视频复制和粘贴.avi", fourcc, fps, size)
while True:
ret, frame = cap.read()
if ret != True:
break
else:
H, W, _ = frame.shape
crop_image = frame.copy()
crop_image = cv2.resize(crop_image, (200, 200))
windows_x1 = W - crop_image.shape[1]
windows_y1 = H - crop_image.shape[0]
windows_x2 = W
windows_y2 = H
frame[windows_y1:windows_y2, windows_x1:windows_x2] = crop_image
cv2.imshow("video", frame)
out.write(frame)
if cv2.waitKey(25) & 0xff == ord('q'):
cap.release()
cv2.destroyAllWindows()
break
效果如下:
下面的代码是我将图像和视频多窗口显示的功能进行了集合,可以在终端直接输入命令运行。
比如想进行图像的多窗口显示,输入以下:
python test.py --mode image --image_path "dog.jpg"
想进行视频的多窗口显示,输入以下:
python test.py --mode video --video_path 0
完整代码:
import cv2
import matplotlib.pyplot as plt
import numpy as np
import argparse
def image_crop(image_path):
'''
(0,0)—————————————————— W (x)
|
|
|
|
|
|
H(y)
dog.jpg shape (375,499,3)
狗头位置:x1:182,y1:123
x2:283 y2:210
'''
img = cv2.imread(image_path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
H, W, _ = img.shape
# 注意:截取的时候应该是img[y1:y2, x1:x2] 取决你坐标系怎么建立的
crop_img = img[123:210, 182:283]
crop_img = cv2.resize(crop_img, (100, 100))
windows_x1 = W - crop_img.shape[1]
windows_y1 = H - crop_img.shape[0]
windows_x2 = W
windows_y2 = H
img[windows_y1:windows_y2, windows_x1:windows_x2] = crop_img
plt.imshow(img)
plt.show()
def video_crop(video_path):
if video_path == '0':
video_path = int(video_path)
cap = cv2.VideoCapture(video_path)
fps = cap.get(cv2.CAP_PROP_FPS)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
out = cv2.VideoWriter("视频复制和粘贴.avi", fourcc, fps, size)
while True:
ret, frame = cap.read()
if ret != True:
break
else:
H, W, _ = frame.shape
crop_image = frame.copy()
crop_image = cv2.resize(crop_image, (200, 200))
windows_x1 = W - crop_image.shape[1]
windows_y1 = H - crop_image.shape[0]
windows_x2 = W
windows_y2 = H
frame[windows_y1:windows_y2, windows_x1:windows_x2] = crop_image
cv2.imshow("video", frame)
out.write(frame)
if cv2.waitKey(25) & 0xff == ord('q'):
cap.release()
cv2.destroyAllWindows()
break
if __name__=='__main__':
parse = argparse.ArgumentParser()
parse.add_argument('--mode', type=str, default='image', help='you can choose "image" or "video"')
parse.add_argument('--image_path', type=str, default="dog.jpg", help='image path')
parse.add_argument('--video_path', type=str, default='0', help='video path')
opt = parse.parse_args()
if opt.mode == 'image':
image_crop(opt.image_path)
if opt.mode == 'video':
video_crop(opt.video_path)
视频转gif代码
在附一个视频转gif的代码
from moviepy.editor import *
clip = (VideoFileClip(r"你的视频路径.avi")
.subclip(0,2) # 从第几秒开始(比如我这从视频的开始到第二秒)
.resize(0.4))
clip.write_gif("video多窗口显示.gif")