Skip to content

Commit 7aee630

Browse files
committed
Added existing Part 1 code and test video.
1 parent cce5476 commit 7aee630

File tree

2 files changed

+109
-0
lines changed

2 files changed

+109
-0
lines changed

examples/part1-threshold.py

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#
2+
# Scene Detection with Python and OpenCV - Example Program
3+
# Part 1: Threshold/Fade-to-Black Detection By: Brandon Castellano
4+
#
5+
# http://www.bcastell.com/tech-articles/pyscenedetect-tutorial-part-1/
6+
#
7+
# This Python program implements a simple threshold-based scene detection
8+
# algorithm using a set threshold compared to the average pixel intensity
9+
# of each frame. Usage:
10+
#
11+
# > python part1-threshold.py [video-file] [intensity = 16]
12+
#
13+
# Where [video-file] is a path to the video to be parsed, and [intensity]
14+
# is the average pixel intensity from 0 to 255 to be used as a cut-off
15+
# (if unspecified, the default value of 16 is used). Example:
16+
#
17+
# > python part1-threshold.py testvideo.mp4 8
18+
#
19+
# For each fade/cut that is detected, the timecodes and frame numbers
20+
# are printed to stdout. Note that this program depends on the Python
21+
# OpenCV bindings and NumPy.
22+
#
23+
# Copyright (C) 2013-2014 Brandon Castellano <http://www.bcastell.com>.
24+
# I hereby release this file into the public domain.
25+
#
26+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
29+
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
30+
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
31+
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
32+
# OTHER DEALINGS IN THE SOFTWARE.
33+
#
34+
35+
36+
import sys
37+
import cv2
38+
import numpy as np
39+
40+
def main():
41+
if len(sys.argv) < 2:
42+
print "Error - file name must be specified as first argument."
43+
return
44+
45+
cap = cv2.VideoCapture()
46+
cap.open(sys.argv[1])
47+
48+
if not cap.isOpened():
49+
print "Fatal error - could not open video %s." % sys.argv[1]
50+
return
51+
else:
52+
print "Parsing video %s..." % sys.argv[1]
53+
54+
# Do stuff with cap here.
55+
56+
width = cap.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)
57+
height = cap.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)
58+
print "Video Resolution: %d x %d" % (width, height)
59+
60+
# Allow the threshold to be passed as an optional, second argument to the script.
61+
threshold = 16
62+
if len(sys.argv) > 2 and int(sys.argv[2]) > 0:
63+
threshold = int(sys.argv[2])
64+
print "Detecting scenes with threshold = %d.\n" % threshold
65+
66+
67+
last_mean = 0 # Mean intensity of the *last* frame processed.
68+
start_time = cv2.getTickCount() # Used for benchmarking/statistics after loop.
69+
70+
while True:
71+
(rv, im) = cap.read() # im is a valid image if and only if rv is true
72+
if not rv:
73+
break
74+
75+
# im.mean() and numpy.mean(im) run at roughly the same speed
76+
#frame_mean = im.mean()
77+
#frame_mean = np.mean(im)
78+
79+
# dividing np.sum(im) by the image size increases speed by ~35-40%
80+
frame_mean = np.sum(im) / float(im.shape[0] * im.shape[1] * im.shape[2])
81+
82+
# Detect fade in from black.
83+
if frame_mean >= threshold and last_mean < threshold:
84+
print "Detected fade in at %dms (frame %d)." % (
85+
cap.get(cv2.cv.CV_CAP_PROP_POS_MSEC),
86+
cap.get(cv2.cv.CV_CAP_PROP_POS_FRAMES) )
87+
88+
# Detect fade out to black.
89+
elif frame_mean < threshold and last_mean >= threshold:
90+
print "Detected fade out at %dms (frame %d)." % (
91+
cap.get(cv2.cv.CV_CAP_PROP_POS_MSEC),
92+
cap.get(cv2.cv.CV_CAP_PROP_POS_FRAMES) )
93+
94+
last_mean = frame_mean # Store current mean to compare in next iteration.
95+
96+
# get # of frames in video as position in video we ended at
97+
frame_count = cap.get(cv2.cv.CV_CAP_PROP_POS_FRAMES)
98+
# compute runtime and average framerate
99+
total_runtime = float(cv2.getTickCount() - start_time) / cv2.getTickFrequency()
100+
avg_framerate = float(frame_count) / total_runtime
101+
102+
print "Read %d frames from video in %4.2f seconds (avg. %4.1f FPS)." % (
103+
frame_count, total_runtime, avg_framerate)
104+
105+
cap.release()
106+
107+
108+
if __name__ == "__main__":
109+
main()

examples/testvideo.mp4

2.32 MB
Binary file not shown.

0 commit comments

Comments
 (0)