Skip to content

Instantly share code, notes, and snippets.

Last active Mar 17, 2021
What would you like to do?
vqm 2 xlsx
#!/usr/bin/env python
# vqm Run and parse the output of mitsuLinuxMultithread.
# Generate a xlsx-file with all the data as well as a summary sheet.
# Tested on Linux only.
# USAGE: vqm path
# NOTE: YCbcr files needs to be adhere to the following naming convention:
# Example: BQMall_832x480_60.yuv
# NOTE: mitsuLinuxMultithread must reside in the same folder as this python
# program
# Copyright (c) 2015 Fredrik Pihl,
# Licensed under The MIT License (MIT)
# 24-Sep-2015 Fredrik Pihl Created this.
from __future__ import print_function
from StringIO import StringIO
import argparse
import glob
import numpy as np
import operator
import os.path
import pickle
import subprocess
import xlsxwriter
'frame': 0,
'blockiness': 1,
'spatialactivity': 2,
'letterbox': 3,
'pillarbox': 4,
'blockloss': 5,
'blur': 6,
'temporalact': 7,
'blackout': 8,
'freezing': 9,
'exposure': 10,
'contrast': 11,
'brightness': 12,
'interlace': 13,
'noise': 14,
'slice': 15,
'flickering': 16,
class VQM(object):
VQM Class
def __init__(self, path, numframes=None):
self.path = path
self.numframes = numframes
self.files = [] = []
# Uncomment line to generate a simple pickle file with all the data
def __get_files(self):
Do globbing to get all *.yuv files in path
# Sort the file names to have a nice grouping in the output
self.files = sorted(glob.glob(os.path.join(self.path, '*.yuv')))
def __gen_data(self):
Generate data structure for each file in self.files
for i in self.files:
p, w, h, f = self.__extract_param(i)
self.__parse_data(p, self.__run_cmd(i, w, h, f, self.numframes))
def __run_cmd(p, w, h, f, n):
Run binary on each file
p - path
w - width
h - height
f - file
n - numframes
if n is None:
cmd = ['./mitsuLinuxMultithread', str(p), str(w), str(h), str(f)]
cmd = ['./mitsuLinuxMultithread',
str(p), str(w), str(h), str(f), str(n)]
print('Parsing {} ...'.format(os.path.basename(p)))
result = subprocess.check_output(cmd)
return result
def __parse_data(self, key, result):
Parse the output from the binary and put into an array of dictionaries
# Use the basename as the key
(key, np.genfromtxt(
# StringIO(result), skip_header=5,skip_footer=1, unpack=True)
StringIO(result), skip_header=5, skip_footer=1)
def __debug(self):
def __end(self):
Use this method to generate a pickle file of the
parsed data
output = open('data.pkl', 'wb')
# Pickle dictionary using protocol 0.
pickle.dump(, output)
for i in
def __extract_param(path):
Extract basename, width, height and fps from filename
f = os.path.basename(path)
fields = f.split('_')
width, height = map(int, fields[1].split('x'))
fps = fields[2].split('.')[0]
return (f, width, height, fps)
def create_xlsx(self):
Generate a xlsx workbook
# Create an new Excel file and add a worksheet.
workbook = xlsxwriter.Workbook('vqm.xlsx')
header = sorted(MAPPING.items(), key=operator.itemgetter(1))
# loop over all entries in db and create a worksheet
# for all entries
sheets = len(
for sheet in range(sheets):
# Add worksheet
worksheet = workbook.add_worksheet()
# Write filename in cell A1
worksheet.write(0, 0,[sheet][0])
# Write header
for col, x in enumerate(header):
worksheet.write(1, col, x[0])
lines = len([sheet][1])
for row in range(lines):
data =[sheet][1][row]
for col, x in enumerate(data):
worksheet.write(row+2, col, x)
# loop over all entries in db and create a summary worksheet
worksheet = workbook.add_worksheet('summary')
# Widen the first column to make the text clearer.
width = max([len(f[0]) for f in])
worksheet.set_column('A:A', width)
# Write header
for col, x in enumerate(header):
worksheet.write(0, col+1, x[0])
# Write summary data, i.e. average value of all columns
# for each sheet
sheets = len(
for sheet in range(sheets):
# Write filename in cell A1
worksheet.write(sheet+1, 0,[sheet][0])
# Add summation formulas
startrow = 3
lines = len([sheet][1])
for col, x in enumerate(header):
c = chr(ord('A')+col)
formula = "=AVERAGE(Sheet{}{}{}{}:{}{})".format(
sheet+1, '!', c, startrow, c, startrow+lines-1)
worksheet.write_formula(sheet+1, col+1, formula)
# Write number of frames for each sequence
formula = "=MAX(Sheet{}{}{}{}:{}{})+1".format(
sheet+1, '!', 'A', startrow, 'A', startrow+lines-1)
worksheet.write_formula(sheet+1, 1, formula)
def main():
Main function
parser = argparse.ArgumentParser(
description='Extract metrics from all YCbCr files in folder',
epilog="Example: ./ ~/yuvfolder")
help='Source file path, YCbCr 4:2:0')
help='Number of frames to analyze')
args = parser.parse_args()
vqm = VQM(**vars(args))
if __name__ == "__main__":

This comment has been minimized.

Copy link

@jainxy jainxy commented Aug 14, 2020

@line#91 - shouldn't it be "f - fps"?


This comment has been minimized.

Copy link
Owner Author

@figgis figgis commented Aug 28, 2020

Probably. Years since I looked at this code :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment