在有些项目中需要在一个窗口画面中显示多个子画面【这里说的不是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")