这两天在做目标检测项目,为了帮助理解,需要制作检测视频。在这里记录一下:
1.把一系列图片放入文件夹下,把文件夹下所有图片等比例resieze到相同尺寸,比如1300*1300,不足的地方用白色替代。
#coding:utf-8
import os
import cv2
import glob
import numpy as np
from PIL import Image
#把图片resize到固定尺寸,不足补白
def process_image(img_path, min_side):
img = cv2.imread(img_path)
size = img.shape
h, w = size[0], size[1]
#长边缩放为min_side
scale = max(w, h) / float(min_side)
new_w, new_h = int(w/scale), int(h/scale)
resize_img = cv2.resize(img, (new_w, new_h))
# 填充至min_side * min_side
if new_w % 2 != 0 and new_h % 2 == 0:
top, bottom, left, right = (min_side-new_h)/2, (min_side-new_h)/2, (min_side-new_w)/2 + 1, (min_side-new_w)/2
elif new_h % 2 != 0 and new_w % 2 == 0:
top, bottom, left, right = (min_side-new_h)/2 + 1, (min_side-new_h)/2, (min_side-new_w)/2, (min_side-new_w)/2
elif new_h % 2 == 0 and new_w % 2 == 0:
top, bottom, left, right = (min_side-new_h)/2, (min_side-new_h)/2, (min_side-new_w)/2, (min_side-new_w)/2
else:
top, bottom, left, right = (min_side-new_h)/2 + 1, (min_side-new_h)/2, (min_side-new_w)/2 + 1, (min_side-new_w)/2
pad_img = cv2.copyMakeBorder(resize_img, int(top), int(bottom), int(left), int(right), cv2.BORDER_CONSTANT, value=[255,255,255]) #从图像边界向上,下,左,右扩的像素数目
#print pad_img.shape
#cv2.imwrite("after-" + os.path.basename(filename), pad_img)
return pad_img
def resize_to_fix_white(data_dir, save_dir, min_side):
num = 0
for image in os.listdir(data_dir):
num += 1
print("%d/%d, image:%s" %(num, len(os.listdir(data_dir)), image))
#print(save_dir)
# mkdir(os.path.join(save_dir, label))
#print(os.path.join(data_dir, "*.jpg"))
img = cv2.imread(os.path.join(data_dir, image))
if type(img) == type(None):
print("damaged image %s, del it" %(img))
continue
print(os.path.join(data_dir, image))
img_pad = process_image(os.path.join(data_dir, image), min_side)
cv2.imshow("image:", img_pad)
cv2.waitKey(10)
cv2.imwrite(os.path.join(save_dir, image), img_pad)
if __name__ == "__main__":
resize_to_fix_white( r"C:\Users\XX\Desktop\photo", r"C:\Users\XX\Desktop\copy", 1300)
2.把文件夹下所有图片横向连接,组合成一张很长的图片。
#多张图片横向拼接
#单个图片的大小为1300*1300
UNIT_SIZE = 1300
TARGET_WIDTH = 40 * UNIT_SIZE
path = r"C:\Users\wuji\Desktop\copy"
images = []
imagefile = []
#存储所有图片文件名称
for root, dirs, files in os.walk(path):
for f in files:
images.append(f)
#我这里是将40张图片横向拼接
for i in range(40):
imagefile.append(path+'/'+images[i])
target = Image.new('RGB',(TARGET_WIDTH, UNIT_SIZE))
left = 0
right = UNIT_SIZE
for image in imagefile:
#print(image)
#将现有图片复制到新的上面 参数分别为图片文件和复制的位置(左上角, 右下角)
target.paste(Image.open(image), (left, 0, right, UNIT_SIZE))
left += UNIT_SIZE
right += UNIT_SIZE
#图片的质量 0~100
quantity_value = 100
target.save(path+'/end.jpg', quantity = quantity_value)
3.因为我做的是安检视频,所有需要图片的流动,把刚刚拼接的图像再分成更多张。
pth = r"C:\Users\XX\Desktop\copy\end.jpg"
image = cv2.imread(pth)
print(image.shape)
n = int(52000/1300)
j = 0
for i in range(0, 52000, 20):
if( (int(i) + int(1300)) <= 52000):
cropImg = image[ 0:1300, int(i):int(i) + int(1300)]
print('00'+format(str(j),'0>4')+'.jpg')
cv2.imwrite(os.path.join(r"C:\Users\XX\Desktop\sub",'00'+format(str(j),'0>4')+'.jpg'), cropImg)
j+=1
4.制作视频。
fps = 10
size = (1300, 1300)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
path = r'C:/Users/wuji/Desktop/sub'
videowriter = cv2.VideoWriter("test.avi", fourcc, fps, size)
for i in os.listdir(path):
print(os.path.join(path,i))
img = cv2.imread(os.path.join(path, i))
videowriter.write(img)
print("end")
videowriter.release()
结束啦。做出来效果挺好的,检测效果也不错。开森(▽)