Skip to content

Commit c2b3df5

Browse files
committed
fixes after testing writing other video files, add examples and README info
1 parent 7b90b3f commit c2b3df5

File tree

4 files changed

+70
-18
lines changed

4 files changed

+70
-18
lines changed

README.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,13 @@ to run a demo with a feed from your webcam or run
5050

5151
python demo.py
5252

53-
to use a image from the images folder.
53+
to use a image from the images folder or run
54+
55+
python demo_video.py <video-file>
56+
57+
to process a video file (requires [ffmpeg-python][ffmpeg]).
58+
59+
[ffmpeg]: https://pypi.org/project/ffmpeg-python/
5460

5561
### Todo list
5662
- [x] convert caffemodel to pytorch.
@@ -73,6 +79,18 @@ to use a image from the images folder.
7379
#### Body + Hand
7480
![](images/demo_preview.png)
7581

82+
#### Video Body
83+
84+
![](images/kc-e129SBb4-sample.processed.gif)
85+
86+
Attribution: [this video](https://www.youtube.com/watch?v=kc-e129SBb4).
87+
88+
#### Video Hand
89+
90+
![](images/yOAmYSW3WyU-sample.small.processed.gif)
91+
92+
Attribution: [this video](https://www.youtube.com/watch?v=yOAmYSW3WyU).
93+
7694
### Citation
7795
Please cite these papers in your publications if it helps your research (the face keypoint detector was trained using the procedure described in [Simon et al. 2017] for hands):
7896

demo_video.py

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,35 @@
44
from glob import glob
55
import os
66
import argparse
7+
import json
8+
9+
# video file processing setup
10+
# from: https://stackoverflow.com/a/61927951
11+
import argparse
12+
import subprocess
13+
import sys
14+
from pathlib import Path
15+
from typing import NamedTuple
16+
17+
18+
class FFProbeResult(NamedTuple):
19+
return_code: int
20+
json: str
21+
error: str
22+
23+
24+
def ffprobe(file_path) -> FFProbeResult:
25+
command_array = ["ffprobe",
26+
"-v", "quiet",
27+
"-print_format", "json",
28+
"-show_format",
29+
"-show_streams",
30+
file_path]
31+
result = subprocess.run(command_array, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
32+
return FFProbeResult(return_code=result.returncode,
33+
json=result.stdout,
34+
error=result.stderr)
35+
736

837
# openpose setup
938
from src import model
@@ -34,9 +63,6 @@ def process_frame(frame, body=True, hands=True):
3463
# https://stackoverflow.com/questions/61036822/opencv-videowriter-produces-cant-find-starting-number-error
3564
import ffmpeg
3665

37-
def to8(img):
38-
return (img/256).astype('uint8')
39-
4066
# open specified video
4167
parser = argparse.ArgumentParser(
4268
description="Process a video annotating poses detected.")
@@ -47,28 +73,34 @@ def to8(img):
4773
video_file = args.file
4874
cap = cv2.VideoCapture(video_file)
4975

50-
# pull video file info
51-
# don't know why this is how it's defined https://stackoverflow.com/questions/52068277/change-frame-rate-in-opencv-3-4-2
52-
input_fps = cap.get(5)
76+
# get video file info
77+
ffprobe_result = ffprobe(args.file)
78+
info = json.loads(ffprobe_result.json)
79+
videoinfo = [i for i in info["streams"] if i["codec_type"] == "video"][0]
80+
input_fps = videoinfo["avg_frame_rate"]
81+
# input_fps = float(input_fps[0])/float(input_fps[1])
82+
input_pix_fmt = videoinfo["pix_fmt"]
83+
input_vcodec = videoinfo["codec_name"]
5384

5485
# define a writer object to write to a movidified file
55-
assert len(video_file.split(".")) == 2, \
56-
"file/dir names must not contain extra ."
57-
output_file = video_file.split(".")[0]+".processed.avi"
86+
postfix = info["format"]["format_name"].split(",")[0]
87+
output_file = ".".join(video_file.split(".")[:-1])+".processed." + postfix
5888

5989

6090
class Writer():
61-
def __init__(self, output_file, input_fps, input_framesize, gray=False):
91+
def __init__(self, output_file, input_fps, input_framesize, input_pix_fmt,
92+
input_vcodec):
6293
if os.path.exists(output_file):
6394
os.remove(output_file)
6495
self.ff_proc = (
6596
ffmpeg
6697
.input('pipe:',
6798
format='rawvideo',
68-
pix_fmt='gray' if gray else 'rgb24',
69-
s='%sx%s'%(input_framesize[1],input_framesize[0]))
70-
.filter('fps', fps=input_fps, round='up')
71-
.output(output_file, pix_fmt='yuv420p')
99+
pix_fmt="bgr24",
100+
s='%sx%s'%(input_framesize[1],input_framesize[0]),
101+
r=input_fps)
102+
.output(output_file, pix_fmt=input_pix_fmt, vcodec=input_vcodec)
103+
.overwrite_output()
72104
.run_async(pipe_stdin=True)
73105
)
74106

@@ -86,12 +118,14 @@ def close(self):
86118
if frame is None:
87119
break
88120

89-
if writer is None:
90-
input_framesize = frame.shape[:2]
91-
writer = Writer(output_file, input_fps, input_framesize)
92121
posed_frame = process_frame(frame, body=not args.no_body,
93122
hands=not args.no_hands)
94123

124+
if writer is None:
125+
input_framesize = posed_frame.shape[:2]
126+
writer = Writer(output_file, input_fps, input_framesize, input_pix_fmt,
127+
input_vcodec)
128+
95129
cv2.imshow('frame', posed_frame)
96130

97131
# write the frame
10.7 MB
Loading
5.7 MB
Loading

0 commit comments

Comments
 (0)