这篇博客主要来记录工作中积累的知识,代码,以方便后面复用,提升工作效率。
一、将视频转化为一帧帧图片,同时将图片分割为五份
C++实现:
#include <iostream>
#include <opencv2/opencv.hpp>
#include <direct.h>
#include <io.h>
using namespace cv;
using namespace std;
// 将图片(960*5) * 1280 切分为 5个 960*1280的图片 分别存在right_front right_back left_back left_front front文件夹中
void cutImages(string path)
{
char temp_file[7];
string filename;
int num = 1;
for (; ; )
{
sprintf_s(temp_file, "%06d", num);
filename = temp_file;
filename = path + filename + ".jpg";
Mat img = imread(filename, 1);
if (img.empty())
{
cout << num << endl;
break;
}
//如果读取成功,开始分割
int height = img.rows; // 应该是1280
int width = img.cols; // 应该是960*5 = 4800
cout << width << " * " << height << endl;
// 1-960 961-960*2 960*2+1 - 960*3 960*3+1 - 960*4 960*4+1 - 960*5
vector<Mat> subImages;
int sub_height = height;
int sub_width = width / 5;
cout << sub_width << " * " << sub_height << endl;
for (int i = 0; i < 5; i++)
{
Rect rect(i*sub_width, 0, sub_width, sub_height);
subImages.push_back(img(rect));
}
Mat dst;
string dst_folder;
for (int i = 0; i < subImages.size(); i++)
{
dst = subImages[i];
switch (i)
{
case 0:
dst_folder = "1_right_front\\";
break;
case 1:
dst_folder = "2_right_back\\";
break;
case 2:
dst_folder = "3_left_back\\";
break;
case 3:
dst_folder = "4_left_front\\";
break;
case 4:
dst_folder = "5_front\\";
break;
default:
dst_folder = "other(wrong)\\";
break;
}
if (_access((path + dst_folder).c_str(), 6) == -1)
{
_mkdir((path + dst_folder).c_str());
}
imwrite(path + dst_folder + temp_file + ".jpg", dst);
}
num++;
}
}
// 将视频转换为一帧帧图片
void video2image(string video, string path)
{
VideoCapture capture(video);
if (!capture.isOpened())
{
cerr << "Failed to open a video" << endl;
return;
}
Mat frame;
int num = 1;
string filename;
char temp_file[7];
int i = 0;
for (;;)
{
capture >> frame;
if (frame.empty())
break;
sprintf_s(temp_file, "%06d", num);//每张图片前缀由六个字符构成,不够六个字符的前面用0补完整
filename = temp_file;
cout << temp_file << endl;
filename = path + filename + ".jpg";
num++;
imwrite(filename, frame);
}
capture.release();
}
int main()
{
// Mat img = imread("C:\\Users\\windows10\\Pictures\\Saved Pictures\\dog1.jpg", 1);
// imshow("test dog", img);
string video = "G:\\01.Project\\01.Academy\\01.TenEyes\\data\\1\\1.avi";
string path = "G:\\01.Project\\01.Academy\\01.TenEyes\\data\\images\\";
//video2image(video, path);
cutImages(path);
waitKey(0);
}
python实现(功能更加全面):
# coding=utf-8
import os
import cv2
from PIL import Image
import numpy as np
import glob
def video2image(): # 提取视频中图片 按照每帧提取
video_path = '/home/zhongchh/data/ten/1/' # 视频所在的路径
f_save_path = '/home/zhongchh/data/ten/image' # 保存图片的上级目录
videos = os.listdir(video_path) # 返回指定路径下的文件和文件夹列表。
videos.sort()
for video_name in videos: # 依次读取视频文件
file_name = video_name.split('.')[0] # 拆分视频文件名称 ,剔除后缀
folder_name = f_save_path + file_name # 保存图片的上级目录+对应每条视频名称 构成新的目录存放每个视频的
os.makedirs(folder_name, exist_ok=True) # 创建存放视频的对应目录
vc = cv2.VideoCapture(video_path + video_name) # 读入视频文件
c = 0 # 计数 统计对应帧号
rval = vc.isOpened() # 判断视频是否打开 返回True或Flase
while rval: # 循环读取视频帧
rval, frame = vc.read() # videoCapture.read() 函数,第一个返回值为是否成功获取视频帧,第二个返回值为返回的视频帧:
if rval:
frame=cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) #convert channel to 1
pic_path = folder_name + '/'
if rval:
cv2.imwrite(pic_path + str(c).zfill(4) + '.jpg', frame) # 存储为图像,保存名为 文件夹名_数字(第几个文件).jpg
cv2.waitKey(1) # waitKey()--这个函数是在一个给定的时间内(单位ms)等待用户按键触发;如果用户没有按下 键,则接续等待(循环)
c = c + 1
else:
break
vc.release()
print('save_success ' + folder_name)
def image_crop():
image_path = '/home/zhongchh/data/ten/image2'
images = os.listdir(image_path)
images.sort()
for i in range(1,6):
if not os.path.exists(image_path + '_'+str(i)+'/'):
os.makedirs(image_path+'_'+str(i)+'/')
for img_name in images:
img = Image.open(os.path.join(image_path,img_name))
img1 = img.crop((0,0,900,1280)).rotate(90,expand=True)
img2 = img.crop((900,0,1800,1280)).rotate(90,expand=True)
img3 = img.crop((1800,0,2700,1280)).rotate(90,expand=True)
img4 = img.crop((2700,0,3600,1280)).rotate(90,expand=True)
img5 = img.crop((3600,0,4500,1280)).rotate(90,expand=True)
img1.save(image_path+'_1/'+img_name)
img2.save(image_path+'_2/'+img_name)
img3.save(image_path+'_3/'+img_name)
img4.save(image_path+'_4/'+img_name)
img5.save(image_path+'_5/'+img_name)
def image_paste():
image_path = '/home/zhongchh/data/ten/rainbow'
images = os.listdir(image_path+'/1')
images.sort()
for idx,img_name in enumerate(images):
img1 = Image.open(os.path.join(image_path,'1',img_name)).rotate(-90,expand=True)
img2 = Image.open(os.path.join(image_path,'2',img_name)).rotate(-90,expand=True)
img3 = Image.open(os.path.join(image_path,'3',img_name)).rotate(-90,expand=True)
img4 = Image.open(os.path.join(image_path,'4',img_name)).rotate(-90,expand=True)
img5 = Image.open(os.path.join(image_path,'5',img_name)).rotate(-90,expand=True)
img = Image.new('RGB',(4500,1280))
img.paste(img1,(0,0,900,1280))
img.paste(img2,(900,0,1800,1280))
img.paste(img3,(1800,0,2700,1280))
img.paste(img4,(2700,0,3600,1280))
img.paste(img5,(3600,0,4500,1280))
img.save(image_path+'/result_frame_rgb/'+str(idx).zfill(4)+'.png')
def image2video():
image_path = '/home/zhongchh/data/ten/result_frame_combine_rgb'
save_path = '/home/zhongchh/data/ten/combine_disp_rgb.mp4'
fps = 20
filelist = os.listdir(image_path)
filelist.sort()
# size = (591,705) #图片的分辨率片
fourcc = cv2.VideoWriter_fourcc('D', 'I', 'V', 'X') # 不同视频编码对应不同视频格式(例:'I','4','2','0' 对应avi格式) ('D', 'I', 'V', 'X')mp4
video = cv2.VideoWriter(save_path, fourcc, fps, (4500,2560))
for idx,item in enumerate(filelist):
if item.endswith('.png'): # 判断图片后缀是否是.png
item = image_path + '/' + item
img = cv2.imread(item) # 使用opencv读取图像,直接返回numpy.ndarray 对象,通道顺序为BGR ,注意是BGR,通道值默认范围0-255。
video.write(img) # 把图片写进视频
print(idx)
video.release() # 释放
def updown_paste():
ori_path = '/home/zhongchh/data/ten/image1'
disp_path = '/home/zhongchh/data/ten/rainbow/result_frame_rgb'
images = os.listdir(ori_path)
images.sort()
for idx,img_name in enumerate(images):
imgs = img_name.split('.')
img1 = Image.open(os.path.join(ori_path,imgs[0]+'.jpg'))
img2 = Image.open(os.path.join(disp_path,imgs[0]+'.png'))
img = Image.new('RGB',(4500,2560))
img.paste(img1,(0,0,4500,1280))
img.paste(img2,(0,1280,4500,2560))
img.save('/home/zhongchh/data/ten/result_frame_combine_rgb/'+str(idx).zfill(4)+'.png')
image2video()
二、与系统无关的问题
matlab标定相机参数
https://jingyan.baidu.com/article/22a299b5e6da909e18376a75.html