Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Tree: 32189fead2
Fetching contributors…

Cannot retrieve contributors at this time

173 lines (137 sloc) 4.924 kB
# -*- coding: utf-8 -*-
import sys
import cv
import time
import winsound
import win32api, win32con
import os.path
import xml.etree.ElementTree as et
DEBUG = False
#DEBUG = True
DEBUG_INTERACTIVE = False
OUTPUT_DIR_NAME = "shot_snapshots"
soundfile = "ton.wav"
def main():
BLACK_AND_WHITE = False
THRESHOLD = 0.48
BW_THRESHOLD = 0.4
os.chdir(sys.argv[1])
try:
os.mkdir(OUTPUT_DIR_NAME)
except:
pass
if len(sys.argv) > 2:
if sys.argv[2] == "bw":
BLACK_AND_WHITE = True
THRESHOLD = BW_THRESHOLD
print "##########"
print " B/W MODE"
print "##########"
tree = et.parse("project.xml")
movie = tree.getroot()
file_path = movie.attrib["path"]
cap = cv.CreateFileCapture(file_path)
if DEBUG:
cv.NamedWindow("win", cv.CV_WINDOW_AUTOSIZE)
cv.MoveWindow("win", 200, 200)
hist = None
prev_hist = None
prev_img = None
pixel_count = None
frame_counter = 0
last_frame_black = False
black_frame_start = -1
t = time.time()
while 1:
img_orig = cv.QueryFrame(cap)
if not img_orig: # eof
cv.SaveImage(OUTPUT_DIR_NAME + "\\%06d.png" % (frame_counter-1), prev_img)
"""movie.set("frames", str(frame_counter))
tree.write("project.xml")"""
break
img = cv.CreateImage((int(img_orig.width/4), int(img_orig.height/4)), cv.IPL_DEPTH_8U, 3)
cv.Resize(img_orig, img, cv.CV_INTER_AREA)
if frame_counter == 0: # erster frame
cv.SaveImage(OUTPUT_DIR_NAME + "\\%06d.png" % (0), img)
pixel_count = img.width * img.height
prev_img = cv.CreateImage(cv.GetSize(img), cv.IPL_DEPTH_8U, 3)
cv.Zero(prev_img)
if DEBUG and frame_counter % 2 == 1:
cv.ShowImage("win", img)
img_hsv = cv.CreateImage(cv.GetSize(img), cv.IPL_DEPTH_8U, 3)
cv.CvtColor(img, img_hsv, cv.CV_BGR2HSV)
# #####################
# METHOD #1: find the number of pixels that have (significantly) changed since the last frame
diff = cv.CreateImage(cv.GetSize(img), cv.IPL_DEPTH_8U, 3)
cv.AbsDiff(img_hsv, 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 += float(cv.CountNonZero(diff)) / float(pixel_count)
if not BLACK_AND_WHITE:
d_color = float(d_color/3.0) # 0..1
# #####################
# METHOD #2: calculate the amount of change in the histograms
h_plane = cv.CreateMat(img.height, img.width, cv.CV_8UC1)
s_plane = cv.CreateMat(img.height, img.width, cv.CV_8UC1)
v_plane = cv.CreateMat(img.height, img.width, cv.CV_8UC1)
cv.Split(img_hsv, h_plane, s_plane, v_plane, None)
planes = [h_plane, s_plane, v_plane]
hist_size = [50, 50, 50]
hist_range = [[0, 360], [0, 255], [0, 255]]
if not hist:
hist = cv.CreateHist(hist_size, cv.CV_HIST_ARRAY, hist_range, 1)
cv.CalcHist([cv.GetImage(i) for i in planes], hist)
cv.NormalizeHist(hist, 1.0)
if not prev_hist:
prev_hist = cv.CreateHist(hist_size, cv.CV_HIST_ARRAY, hist_range, 1)
# wieso gibt es kein cv.CopyHist()?!
cv.CalcHist([cv.GetImage(i) for i in planes], prev_hist)
cv.NormalizeHist(prev_hist, 1.0)
continue
d_hist = cv.CompareHist(prev_hist, hist, cv.CV_COMP_INTERSECT)
# combine both methods to make a decision
if ((0.4*d_color + 0.6*(1-d_hist))) >= THRESHOLD:
if DEBUG:
if frame_counter % 2 == 0:
cv.ShowImage("win", img)
winsound.PlaySound(soundfile, winsound.SND_FILENAME|winsound.SND_ASYNC)
print "%.3f" % ((0.4*d_color + 0.6*(1-d_hist))), "%.3f" % (d_color), "%.3f" % (1-d_hist), frame_counter
if DEBUG and DEBUG_INTERACTIVE:
if win32api.MessageBox(0, "cut?", "", win32con.MB_YESNO) == 6: #yes
cv.SaveImage(OUTPUT_DIR_NAME + "\\%06d.png" % (frame_counter), img)
else:
cv.SaveImage(OUTPUT_DIR_NAME + "\\%06d.png" % (frame_counter), img)
cv.CalcHist([cv.GetImage(i) for i in planes], prev_hist)
cv.NormalizeHist(prev_hist, 1.0)
# #####################
# METHOD #3: detect series of (almost) black frames as an indicator for "fade to black"
average = cv.Avg(v_plane)[0]
if average <= 0.6:
if not last_frame_black: # possible the start
print "start", frame_counter
black_frame_start = frame_counter
last_frame_black = True
else:
if last_frame_black: # end of a series of black frames
cut_at = black_frame_start + int( (frame_counter - black_frame_start) / 2 )
print "end", frame_counter, "cut at", cut_at
img_black = cv.CreateImage((img_orig.width/4, img_orig.height/4), cv.IPL_DEPTH_8U, 3)
cv.Set(img_black, cv.RGB(0, 255, 0))
cv.SaveImage(OUTPUT_DIR_NAME + "\\%06d.png" % (cut_at), img_black)
last_frame_black = False
cv.Copy(img_hsv, prev_img)
frame_counter += 1
if DEBUG:
if cv.WaitKey(1) == 27:
break
if DEBUG:
cv.DestroyWindow("win");
print "%.2f min" % ((time.time()-t) / 60)
#raw_input("- done -")
return
# #########################
if __name__ == "__main__":
main()
# #########################
Jump to Line
Something went wrong with that request. Please try again.