https://github.com/RongSong1993/YOLOv3_SaveVideo
1.测试视频主要是调用到detector demo,主要修改的是demo.c中的demo函数。
./darknet detector demo ./cfg/voc.data ./cfg/yolov3-voc.cfg ./results/yolov3-voc_final.weights 1.mp4 -gpus 0,1
在image.c中定义视频保存函数
void save_video(image p, CvVideoWriter *mVideoWriter)
{
image copy = copy_image(p);
if(p.c == 3) rgbgr_image(copy);
int x,y,k;
IplImage *disp = cvCreateImage(cvSize(p.w,p.h), IPL_DEPTH_8U, p.c);
int step = disp->widthStep;
for(y = 0; y < p.h; ++y){
for(x = 0; x < p.w; ++x){
for(k= 0; k < p.c; ++k){
disp->imageData[y*step + x*p.c + k] = (unsigned char)(get_pixel(copy,x,y,k)*255);
}
}
}
cvWriteFrame(mVideoWriter,disp);
cvReleaseImage(&disp);
free_image(copy);
}
修改demo.c
定义
#define DEMO 1
#define SAVEVIDEO
#ifdef OPENCV
#ifdef SAVEVIDEO
static CvVideoWriter *mVideoWriter;
#endif
void demo(char *cfgfile, char *weightfile, float thresh, int cam_index, const char *filename, char **names, int classes, int delay, char *prefix, int avg_frames, float hier, int w, int h, int frames, int fullscreen)
{
//demo_frame = avg_frames;
image **alphabet = load_alphabet();
demo_names = names;
demo_alphabet = alphabet;
demo_classes = classes;
demo_thresh = thresh;
demo_hier = hier;
printf("Demo\n");
net = load_network(cfgfile, weightfile, 0);
set_batch_network(net, 1);
pthread_t detect_thread;
pthread_t fetch_thread;
srand(2222222);
int i;
demo_total = size_network(net);
predictions = calloc(demo_frame, sizeof(float*));
for (i = 0; i < demo_frame; ++i){
predictions[i] = calloc(demo_total, sizeof(float));
}
avg = calloc(demo_total, sizeof(float));
if(filename){
printf("video file: %s\n", filename);
cap = cvCaptureFromFile(filename);
#ifdef SAVEVIDEO
if(cap){
//int mfps = cvGetCaptureProperty(cap,CV_CAP_PROP_FPS); //local video file,needn't change
int mfps = 200;
mVideoWriter=cvCreateVideoWriter("Output.avi",CV_FOURCC('M','J','P','G'),mfps,cvSize(cvGetCaptureProperty(cap,CV_CAP_PROP_FRAME_WIDTH),cvGetCaptureProperty(cap,CV_CAP_PROP_FRAME_HEIGHT)),1);
}
#endif
}else{
cap = cvCaptureFromCAM(cam_index);
#ifdef SAVEVIDEO
if(cap){
//int mfps = cvGetCaptureProperty(cap,CV_CAP_PROP_FPS); //webcam video file,need change.
int mfps = 25; //the output video FPS,you can set here.
mVideoWriter=cvCreateVideoWriter("Output_webcam.avi",CV_FOURCC('M','J','P','G'),mfps,cvSize(cvGetCaptureProperty(cap,CV_CAP_PROP_FRAME_WIDTH),cvGetCaptureProperty(cap,CV_CAP_PROP_FRAME_HEIGHT)),1);
}
#endif
if(w){
cvSetCaptureProperty(cap, CV_CAP_PROP_FRAME_WIDTH, w);
}
if(h){
cvSetCaptureProperty(cap, CV_CAP_PROP_FRAME_HEIGHT, h);
}
if(frames){
cvSetCaptureProperty(cap, CV_CAP_PROP_FPS, frames);
}
}
if(!cap) error("Couldn't connect to webcam.\n");
buff[0] = get_image_from_stream(cap);
buff[1] = copy_image(buff[0]);
buff[2] = copy_image(buff[0]);
buff_letter[0] = letterbox_image(buff[0], net->w, net->h);
buff_letter[1] = letterbox_image(buff[0], net->w, net->h);
buff_letter[2] = letterbox_image(buff[0], net->w, net->h);
ipl = cvCreateImage(cvSize(buff[0].w,buff[0].h), IPL_DEPTH_8U, buff[0].c);
int count = 0;
if(!prefix){
cvNamedWindow("Demo", CV_WINDOW_NORMAL);
if(fullscreen){
cvSetWindowProperty("Demo", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
} else {
cvMoveWindow("Demo", 0, 0);
cvResizeWindow("Demo", 1352, 1013);
}
}
demo_time = what_time_is_it_now();
while(!demo_done){
buff_index = (buff_index + 1) %3;
if(pthread_create(&fetch_thread, 0, fetch_in_thread, 0)) error("Thread creation failed");
if(pthread_create(&detect_thread, 0, detect_in_thread, 0)) error("Thread creation failed");
if(!prefix){
#ifdef SAVEVIDEO
save_video(buff[0],mVideoWriter);
#endif
fps = 1./(what_time_is_it_now() - demo_time);
demo_time = what_time_is_it_now();
display_in_thread(0);
}else{
char name[256];
sprintf(name, "%s_%08d", prefix, count);
#ifdef SAVEVIDEO
save_video(buff[0],mVideoWriter);
#else
save_image(buff[(buff_index + 1)%3], name);
#endif
}
pthread_join(fetch_thread, 0);
pthread_join(detect_thread, 0);
++count;
}
}
用来测试录像视频,其中mfps为保存的处理帧率,保存结果为Output.avi。
参考
https://blog.csdn.net/sinat_33718563/article/details/79964758