Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Python script for creating a bar code from any a video source
#sudo pip install pafy
import pafy
#sudo apt-get install python-numpy
import numpy as np
#sudo apt-get install python-opencv
import cv2
#sudo pip install -U scikit-learn
from sklearn.cluster import KMeans
from sklearn import metrics as metrics
import matplotlib.pyplot as plt
import sys
import time
from argparse import ArgumentParser
from argparse import RawDescriptionHelpFormatter
# Credits: Alan Zucconi and Adrian Rosebrock
# http://www.alanzucconi.com/2015/05/24/how-to-find-the-main-colours-in-an-image/
# http://www.pyimagesearch.com/2014/05/26/opencv-python-k-means-color-clustering/
def resize_image (image, size=10):
# Resize it
h, w, _ = image.shape
w_new = int(size * w / max(w, h) )
h_new = int(size * h / max(w, h) )
image = cv2.resize(image, (w_new, h_new));
return image
def process_frame (frame):
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# Resize down
resized = resize_image(frame, 100)
# Reshape the image to be a list of pixels
image_array = resized.reshape((resized.shape[0] * resized.shape[1], 3))
bestSilhouette = -1
bestClusters = 0;
# ------ FIND THE BEST CLUSTERING NUMBER ------- #
for clusters in range(3, 6):
# Cluster colours
clt = KMeans(n_clusters = clusters)
clt.fit(image_array)
# Validate clustering result
silhouette = metrics.silhouette_score(image_array, clt.labels_, metric='euclidean')
# Find the best one
if silhouette > bestSilhouette:
bestSilhouette = silhouette;
bestClusters = clusters;
# ------ CREATE IMAGE ------ #
clt = KMeans(n_clusters = bestClusters)
clt.fit(image_array)
# Finds how many pixels are in each cluster
hist = centroid_histogram(clt)
# Sort the clusters according to how many pixel they have
zipped = zip (hist, clt.cluster_centers_)
zipped.sort(reverse=True, key=lambda x : x[0])
hist, clt.cluster_centers = zip(*zipped)
return [val/255.0 for val in clt.cluster_centers[0]]
def centroid_histogram(clt):
# grab the number of different clusters and create a histogram
# based on the number of pixels assigned to each cluster
numLabels = np.arange(0, len(np.unique(clt.labels_)) + 1)
(hist, _) = np.histogram(clt.labels_, bins = numLabels)
# normalize the histogram, such that it sums to one
hist = hist.astype("float")
hist /= hist.sum()
# return the histogram
return hist
def process_video (title, input_movie):
print '---- Processing video:', title
colours = []
toolbar_width = 100
sys.stdout.write("[%s]" % (" " * toolbar_width))
sys.stdout.flush()
sys.stdout.write("\b" * (toolbar_width+1)) # return to start of line, after '['
# Takes the frames of the video
cap = cv2.VideoCapture(input_movie)
length = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT))
wanted_increment = int(length / 1000)
perc = int( length / 100)
for i in range(length): #cap.isOpened():
flag, frame = cap.read()
if not flag:
continue
if i % wanted_increment is 0:
#print 'processing frame', str(i)
# Processes the frame
try:
frame_color = process_frame(frame)
colours.append(frame_color)
except:
pass
#print frame_color
if i % perc is 0:
sys.stdout.write("-")
sys.stdout.flush()
return colours
def save_bar_code(title, colors):
lines = []
height = 200
vert_line_width = 3
for i in range(height):
line = []
for color in colors:
for j in range(vert_line_width):
line += [color]
lines += [line]
img = np.array(lines, dtype=np.float32)
fig = plt.figure(figsize=((len(colors)*vert_line_width)/100.0, height/100.0))
imgplot = plt.imshow(img, interpolation='nearest')
plt.axis('off')
plt.savefig(title)
plt.close()
#Setup parameters
parser = ArgumentParser(
formatter_class=RawDescriptionHelpFormatter,
description='Movie bar code',
epilog='Use one of the following examples: \n\t test.py -path <input_file> \n\t test.py -url <youtube_video_url>\n')
parser.add_argument('-path', default='', help='Path of a video file to analyze.')
parser.add_argument('-url', default='', help='URL of a Youtube video to download and analyze.')
args = parser.parse_args()
if len(args.path) and len(args.url):
print 'Use this script with a local video path or a Youtube URL, not both! (-h for help)'
exit()
if not len(args.path) and not len(args.url):
print 'Use this script with a local video path or a Youtube URL. (-h for help)'
exit()
if len(args.url):
# Download the video
video = pafy.new(args.url)
#resolution = video.getbest(preftype="mp4")
input_movie = resolution.download(quiet=True)
title = video.title
else: #local video
input_movie = args.path
title = args.path.split('/')[-1]
title = title.split('.')[0]
# Process the video
colors = process_video(title, input_movie)
# Create final image
save_bar_code(title, colors)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment