forked from freder/cinemetrics
-
Notifications
You must be signed in to change notification settings - Fork 0
/
04_1_motion.py
146 lines (108 loc) · 3.26 KB
/
04_1_motion.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# -*- coding: utf-8 -*-
import cv
import math
import os
import sys
import xml.etree.ElementTree as et
import time
from lib import skip_frames
# TODO
# - last 499
DEBUG = False
MAX_FRAMES = 5000
WIDTH = 500
OUTPUT_DIR_NAME = "motion"
def main():
os.chdir(sys.argv[1])
try:
os.mkdir(OUTPUT_DIR_NAME)
except OSError:
pass
tree = et.parse("project.xml")
movie = tree.getroot()
file_path = movie.attrib["path"]
if DEBUG:
cv.NamedWindow("win", cv.CV_WINDOW_AUTOSIZE)
cv.MoveWindow("win", 200, 200)
cap = cv.CreateFileCapture(file_path)
skip_frames(cap, movie)
pixel_count = None
prev_img = None
global_frame_counter = 0
file_counter = 0
w = None
h = None
output_img = cv.CreateImage((WIDTH, MAX_FRAMES), cv.IPL_DEPTH_8U, 3)
f = open("shots.txt", "r")
lines = [line for line in f if line] # (start_frame, end_frame, duration)
f.close()
f_frm = open("motion.txt", "w")
f_avg = open("motion_shot-avg.txt", "w")
motion = []
t = time.time()
for nr, line in enumerate(lines):
print (nr+1), "/", len(lines)
duration = int( line.split("\t")[2] )
for frame_counter in range(duration):
img = cv.QueryFrame(cap)
if not img:
print "error?"
print nr, frame_counter
#break
return
if DEBUG:
cv.ShowImage("win", img)
global_frame_counter += 1
if nr == 0 and frame_counter == 0: # first shot, first frame
w = img.width
h = img.height
pixel_count = float( img.width * img.height )
prev_img = cv.CreateImage(cv.GetSize(img), cv.IPL_DEPTH_8U, 3)
cv.Zero(prev_img)
diff = cv.CreateImage(cv.GetSize(img), cv.IPL_DEPTH_8U, 3)
cv.AbsDiff(img, prev_img, diff)
cv.Threshold(diff, diff, 10, 255, cv.CV_THRESH_BINARY)
d_color = 0
for i in range(1, 4):
cv.SetImageCOI(diff, i)
d_color += cv.CountNonZero(diff) / pixel_count
d_color = d_color / 3 # 0..1
#print "%.1f" % (d_color*100), "%"
motion.append(d_color)
cv.Copy(img, prev_img)
# WRITE TEXT FILE
f_frm.write("%f\n" % (d_color))
if frame_counter == duration-1: # last frame of current shot
motion_value = sum(motion) / len(motion)
print "average motion:", motion_value
f_avg.write("%f\t%d\n" % (motion_value, duration))
motion = []
# WRITE IMAGE
if frame_counter == 0: # ignore each first frame -- the diff after a hard cut is meaningless
global_frame_counter -= 1
continue
else:
for i in range(WIDTH):
value = d_color * 255
cv.Set2D(output_img, (global_frame_counter-1) % MAX_FRAMES, i, cv.RGB(value, value, value))
if global_frame_counter % MAX_FRAMES == 0:
cv.SaveImage(OUTPUT_DIR_NAME + "\\motion_%03d.png" % (file_counter), output_img)
file_counter += 1
if DEBUG:
if cv.WaitKey(1) == 27:
break
if global_frame_counter % MAX_FRAMES != 0:
#cv.SetImageROI(output_img, (0, 0, WIDTH-1, (global_frame_counter % MAX_FRAMES)-1))
cv.SetImageROI(output_img, (0, 0, WIDTH-1, (global_frame_counter-1) % MAX_FRAMES))
cv.SaveImage(OUTPUT_DIR_NAME + "\\motion_%03d.png" % (file_counter), output_img)
f_frm.close()
f_avg.close()
if DEBUG:
cv.DestroyWindow("win");
print "%.2f min" % ((time.time()-t) / 60)
#raw_input("- done -")
return
# #########################
if __name__ == "__main__":
main()
# #########################