Only load segment of text file using numpy and itertools - python-3.x

I have a piece of code that initially decodes a .dat file into a .txt file using a binary chipher cycle style decoder. It results in an over 500 line text file of data points with lines 0-65 being titles and other display features and the last few lines, starting from 586, being wrongly decoded text that looks something like:
ßÅBÎheÀœaÜ;sî3TÐêM·Zì?pêI†Q’&×¥ü#ÇPËiPì¿j–hñHžíoî#ˆ[ÿ>BÿÃ#ÌhcP¿_ÔkõOˆEñlÀ‹J–>tò5Ægã_ð: yŽ6aÎ
“uôhaù*°Dý4}Ó´Qá4wÙ
žZôØ
‘~êlHí–’/mÑ=žt
k×£QÉoû·]Ý&õC´Jœ9mû»ZÃ+]þ6ƒ[ቶS;Uö¥Wã
Lè:ÂXÿ4sÈÄAïPó€Dó$EØÙ•dДeïkHâN xÐj#Ø"”eë1aõÅCÒ7ùC–ñiÐCÑP‹Æ
Ñ
]ô†}ÌdDñ
 Ë,WÎÄdó^ã8žDäÓ)Çq9}ùÃfÄP÷ÇzîoiÒ ÁpìeSÖ€ÒMŒÀ“;Bö
I am using the code:
with open (file) as f:
xpoints, ypoints, gradient = np.loadtxt(itertools.islice(f,68, 584), delimiter=',', unpack=True)
in order to load only the lines that contain the data points I am after.
For some reason however, this causes the program to throw an error that it cant decode a byte as it maps to undefined. I have confirmed it is caused by the junk text at the bottom and seems to be thrown in the line shown above but I cannot figure out why this is the case as it shouldn't need to read those lines at all.
Full error:
File "C:\Users\brady\Desktop\Slider_All\Slide-Mobile.py", line 57, in
module
xpoints, ypoints, gradient = np.loadtxt(IT.islice(f,68,
500), delimiter=',', unpack=True) File
"C:\Users\brady\AppData\Local\Programs\Python\Python38-32\lib\site-packag
es\numpy\lib\npyio.py", line 1159, in loadtxt
for x in read_data(_loadtxt_chunksize): File "C:\Users\brady\AppData\Local\Programs\Python\Python38-32\lib\site-packag
es\numpy\lib\npyio.py", line 1075, in read_data
for i, line in enumerate(line_iter): File "C:\Users\brady\AppData\Local\Programs\Python\Python38-32\lib\encodings\c
p1252.py", line 23, in decode
return codecs.charmap_decode(input,self.errors,decoding_table)[0] UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position
7758: cha racter maps to undefined
Does itertools.islice or numpy.loadtxt possibly attempt to read the whole document first before it takes the slice and runs into a problem or is this something else entirely that I'm missing. I will post my entire unedited code below for completions sake, thankyou for any and all help.
import matplotlib.animation as animation
from matplotlib.widgets import Slider, Button
import matplotlib as mpl
from matplotlib import pyplot as plt
import scipy.interpolate as inter
import numpy as np
import itertools as IT
from itertools import cycle
from scipy.interpolate import interp1d
import os
file = 'example.dat'
x1 = 250 #Lower bound Bigger bound leads to lots of lag
x2 = 300 #Upper bound Recommended to remain close to range of 50
#=========================================================================================================================
start = [] #Stores data before given points
end = [] #Stores data after given points
files = [] #Stores text file to be removed when done
#This function decodes and re-encodes the dat files
class Decoder:
def decode(fn_in, fn_out):
CIPHER = cycle([0b01011100, 0b00100111, 0b10111010, 0b01111011, 0b11110010, 0b00110010, 0b10100101])
with open(fn_in, 'rb') as fin, open(fn_out, 'wb') as fout:
fout.write(fin.read(14))
byte = fin.read(1)
while byte:
fout.write( ( int.from_bytes(byte, 'big') ^ next(CIPHER) ).to_bytes(1, 'big') )
byte = fin.read(1)
def to_txt(filename):
#global files
if filename [-3:] == "dat":
Decoder.decode( filename, filename[:-3] + "txt" )
filename = filename[:-3] + "txt"
else:
print("Extension not recognised for input filename \""+str(filename)+"\", skipping...")
return filename
def to_dat(filename):
files.append(filename)
if filename [-3:] == "txt":
Decoder.decode( filename, tempfile[:-3]+ "dat" )
#file.append(filename[:-3] + "dat")
else:
print("Extension not recognised for input filename \""+str(filename)+"\", skipping...")
if file[-3:] == "dat":
file = Decoder.to_txt(file) #Converts .dat to .txt
files.append(file)
#Gets all data points from file
with open (file) as f:
xpoints, ypoints, gradient = np.loadtxt(IT.islice(f,68, 584), delimiter=',', unpack=True)
#get a list of points to fit a spline to as well
xmin = min(xpoints)
xmax = max(xpoints)
#Calculates which lines of data are required to plot
X1 = int(516*((x1 - xmin)/(xmax-xmin))) + 68
X2 = int(516*((x2 - xmin)/(xmax-xmin))) + 68
#Gets specific lines and saves the rest to copy back later
with open (file) as f:
xp, ypoints, gradient = np.loadtxt(IT.islice(f,X1, X2), delimiter=',', unpack=True)
with open(file) as f:
for line in IT.islice(f,0,X1):
start.append(line)
with open (file) as f:
for line in IT.islice(f,X2,584):
end.append(line)
#Sets amount of data points to plot, must be multiple of point range
#The lower the number the more accurate the plot but the slower it will run
N = len(xp)
if N < 200:
j = 1
elif N < 400:
j = 1
else: j = 1
x = xp[::j]
yvals = ypoints[::j]
N = len(x)
xnew = xp
#spline fit
spline = inter.InterpolatedUnivariateSpline (x, yvals)
#set up a plot
fig,axes = plt.subplots(1,1,figsize=(12.0,4.0),sharex=True)
fig,axes.set_position([0.05,0.08,0.93,0.80])
ax1 = axes
pind = None #active point
epsilon = 5 #max pixel distance
#Updates plot when point is dragged
def update(val):
global yvals
global spline
# update curve
for i in np.arange(N):
yvals[i] = sliders[i].val
l.set_ydata(yvals)
spline = inter.InterpolatedUnivariateSpline (x, yvals)
m.set_ydata(spline(X))
# redraw canvas while idle
fig.canvas.draw_idle()
#Resets plot back to original save from when opened
def reset(event):
global yvals
global spline
#reset the values
yvals = ypoints
for i in np.arange(N):
sliders[i].reset()
spline = inter.InterpolatedUnivariateSpline (x, yvals)
l.set_ydata(yvals)
m.set_ydata(spline(X))
# redraw canvas while idle
fig.canvas.draw_idle()
#Overwirtes current save with new plot
def save(event):
f = interp1d(x, yvals, kind='cubic')
ynew = f(xnew)
ax1.plot(xnew,ynew)
newfile = np.vstack((xnew,ynew, gradient)).T
with open(file, 'w') as f:
for item in start:
f.write("%s" % item)
np.savetxt(f, newfile, delimiter = ',')
for item in end:
f.write("%s" % item)
#f.write('""')
Decoder.to_dat(file) #Converts .txt to .dat
#Event handler for mouse click
def button_press_callback(event):
'whenever a mouse button is pressed'
global pind
if event.inaxes is None:
return
if event.button != 1:
return
#print(pind)
pind = get_ind_under_point(event)
#Event handler for mouse release
def button_release_callback(event):
'whenever a mouse button is released'
global pind
if event.button != 1:
return
pind = None
#Gets clicked point number
def get_ind_under_point(event):
'get the index of the vertex under point if within epsilon tolerance'
# display coords
#print('display x is: {0}; display y is: {1}'.format(event.x,event.y))
t = ax1.transData.inverted()
tinv = ax1.transData
xy = t.transform([event.x,event.y])
#print('data x is: {0}; data y is: {1}'.format(xy[0],xy[1]))
xr = np.reshape(x,(np.shape(x)[0],1))
yr = np.reshape(yvals,(np.shape(yvals)[0],1))
xy_vals = np.append(xr,yr,1)
xyt = tinv.transform(xy_vals)
xt, yt = xyt[:, 0], xyt[:, 1]
d = np.hypot(xt - event.x, yt - event.y)
indseq, = np.nonzero(d == d.min())
ind = indseq[0]
#print(d[ind])
if d[ind] >= epsilon:
ind = None
#print(ind)
return ind
#Event handler for mosue movement
def motion_notify_callback(event):
'on mouse movement'
global yvals
if pind is None:
return
if event.inaxes is None:
return
if event.button != 1:
return
#update yvals
#print('motion x: {0}; y: {1}'.format(event.xdata,event.ydata))
yvals[pind] = event.ydata
# update curve via sliders and draw
sliders[pind].set_val(yvals[pind])
fig.canvas.draw_idle()
X = xp
ax1.plot (X, ypoints, 'k--', label='original')
l, = ax1.plot (x,yvals,color='k',linestyle='none',marker='o',markersize=8)
m, = ax1.plot (X, spline(X), 'r-', label='spline')
if max(ypoints) > 0:
yheight = 0.01*max(ypoints)
ylower =0
else:
yheight = -0.1*max(ypoints)
ylower = yheight
ax1.set_yscale('linear')
ax1.set_xlim(x1, x2)
ax1.set_ylim(min(ypoints)-ylower,max(ypoints)+yheight)
ax1.grid(True)
ax1.yaxis.grid(True,which='minor',linestyle='--')
sliders = []
for i in np.arange(N):
axamp = plt.axes([0.84, -1, 0.12, 0.01])
# Slider
s = Slider(axamp, 'p{0}'.format(i), -100, 10, valinit=yvals[i])
sliders.append(s)
for i in np.arange(N):
#samp.on_changed(update_slider)
sliders[i].on_changed(update)
axres = plt.axes([0.84, 0.90, 0.15, 0.08])
bres = Button(axres, 'Reset')
bres.on_clicked(reset)
axsave = plt.axes([0.68, 0.90, 0.15, 0.08])
bsave = Button(axsave, 'Save')
bsave.on_clicked(save)
fig.canvas.mpl_connect('button_press_event', button_press_callback)
fig.canvas.mpl_connect('button_release_event', button_release_callback)
fig.canvas.mpl_connect('motion_notify_event', motion_notify_callback)
plt.show()
for filename in files:
os.remove(filename)
EDIT: I know believe the error is almost definitely tied to the itertools.islice command as I have found a similar issue here: Python 3 itertools.islice continue despite UnicodeDecodeError.
Currently researching alternate way to potentially open the file as changing decode style for .dat is not possible at this stage

I have solved the issue using the solution posted here: https://stackoverflow.com/a/31113251/10475989
My final code is:
types_of_encoding = ["utf8", "cp1252"]
for encoding_type in types_of_encoding:
with open (file, 'r', encoding = encoding_type, errors='ignore') as f:
xpoints, ypoints, gradient = np.loadtxt(IT.islice(f,65, 582), delimiter=',', unpack=True)

Related

texts formatting with maintaining texts alignment

I am using open-source tesseract OCR to extract texts from the images. I need texts with proper space preserved and aligned for some information extraction tasks. I have used the tesseract .image_to_data() method. This method outputs the recognized texts along with its bounding box and confidence score.
After performing sorting I get all the texts on a string in the order they exist in the image but not formatted in the way that I want. One of my test images is
My code:
import cv2
import pytesseract
import argparse
import time
from pytesseract import Output
from utils.config import ENG_CONFIG
def check_confidence(df):
df = df[df['conf'] != -1]
return df
class OCR:
def __init__(self, conf, image):
self.conf = conf
self.image = image
def get_ocr_output(self):
result = pytesseract.image_to_data(self.image, config=self.conf, output_type=Output.DATAFRAME)
result = check_confidence(result)
lines, formatted_string = self.parse_texts(result)
return lines, formatted_string
def parse_texts(self, df):
img = self.image.copy()
parsed_info = []
start = time.time()
for row in df.itertuples(): # for index, row in df.iterrows()
loc = (row.left, row.top, row.width, row.height)
# draw box on the image
cv2.rectangle(img, (loc[0], loc[1]), (loc[0] + loc[2], loc[1] + loc[3]), (255, 255, 0), 2)
text = row.text
conf = row.conf
row_info = {'box': loc, 'text': text, 'conf': conf}
parsed_info.append(row_info)
end = time.time()
print("\n[INFO]: Total time to read the dataframe row by row is : {} seconds.".format(end - start))
print("\n[INFO]: Parsed Information before sorting boxes is: \n{}".format(parsed_info))
parsed_info = self.sort_box_vertically(parsed_info)
lines = self.get_lines_vertically(parsed_info)
lines = self.sort_box_horizontally(lines)
print("\n[INFO]: Parsed Information after sorting boxes horizontally-vertically is : \n{}".format(lines))
# formatted_strings = self.format_texts(lines)
formatted_strings = self.format_texts_by_reserving_spaces(lines)
print("\n[INFO] : Text for the image is : \n{}".format(formatted_strings))
cv2.imshow("text box", img)
cv2.waitKey(0)
return lines, formatted_strings
def sort_box_vertically(self, parsed_info):
"""
Method to sort the boxes vertically
:param parsed_info:
:return:
"""
for counter in range(len(parsed_info) - 1):
for num in range((len(parsed_info) - 1) - counter):
if self.get_box_center(parsed_info[num]['box'])[1] > self.get_box_center(parsed_info[num + 1]['box'])[
1]:
temp = parsed_info[num + 1]
parsed_info[num + 1] = parsed_info[num]
parsed_info[num] = temp
return parsed_info
def get_lines_vertically(self, parsed_info):
"""
Method to separate the lines vertically
:param parsed_info:
:return:
"""
lines = []
while len(parsed_info) != 0:
ref_box = parsed_info[0]['box']
line = [parsed_info[0]]
for i in range(1, len(parsed_info)):
if self.is_intersects(ref_box, parsed_info[i]['box']) or self.is_intersects(parsed_info[i]['box'],
ref_box):
line.append(parsed_info[i])
for i in range(len(line)):
parsed_info.remove(line[i])
lines.append(line)
return lines
def is_intersects(self, box1, box2, margin=0):
x_1, y_1, w_1, h_1 = box1
x_2, y_2, w_2, h_2 = box2
# check if box2 intersect with box1 by height
h1, k1 = self.get_box_center(box1)
h2, k2 = self.get_box_center(box2)
if int(k2) in range(int(y_1 + margin * h_1), int((y_1 + h_1 - h_1 * margin))) or int(k1) in range(
int(y_2 + margin * h_2), int((y_2 + h_2 - h_2 * margin))):
return True
return False
def get_box_center(self, box):
"""
Method to get the center of box (h,k)
:param box: box as tuple (x, y, w, h)
:return:
"""
x, y, w, h = box
x1 = x
y1 = y
x2 = x + w
y2 = y + h
# Find the center of the box
h, k = int((x1 + x2) / 2), int((y1 + y2) / 2)
return h, k
def format_texts(self, lines):
"""
Method to return the formatted texts from the image
:param lines:
:return:
"""
formatted_string = ""
for line in lines:
for word in line:
# print(word)
formatted_string += " " + word['text']
formatted_string += '\n'
return formatted_string
def format_texts_by_reserving_spaces(self, lines):
"""
An efficient Method to return the formatted texts from the image
:param lines:
:return:
"""
formatted_string = ""
for line in lines:
flag = 0
for word in line:
# print(word)
word_start = word['box'][0]
word_end = word['box'][0] + word['box'][2]
formatted_string += " " * (word_start - flag - 1) + word['text']
flag = word_end
formatted_string += '\n'
return formatted_string
def sort_box_horizontally(self, lines):
final_lines = []
for line in lines:
for counter in range(len(line) - 1):
for num in range((len(line) - 1) - counter):
# If x1 of first line is greater than second line
if self.get_box_center(line[num]['box'])[0] > self.get_box_center(line[num + 1]['box'])[0]:
temp = line[num + 1]
line[num + 1] = line[num]
line[num] = temp
final_lines.append(line)
return final_lines
def sort_box_horizontally_example(self, line_boxes):
"""
Method to sort the boxes horizontally
:param boxes: list of tuple of boxes eg:[((,),(,))]
:return:
"""
final_lines = []
for line in line_boxes:
for counter in range(len(line) - 1):
for num in range((len(line) - 1) - counter):
# If x1 of first line is greater than second line
if line[num][0][0] > line[num + 1][0][0]:
temp = line[num + 1]
line[num + 1] = line[num]
line[num] = temp
final_lines.append(line)
return final_lines
def sorting_example(self):
"""
Sorting array using bubble sort
:return:
"""
list_ = [3, 6, 8, 44, 77, 2, 44, 556, 66, 565, 34]
for i in range(len(list_) - 1):
for j in range((len(list_) - 1) - i):
if list_[j] > list_[j + 1]:
temp = list_[j]
list_[j] = list_[j + 1]
list_[j + 1] = temp
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('-i', '--image',
default="./intelligent_information_extractor/images/img5.png",
help="Path to input image to be OCR'd")
args = parser.parse_args()
image = cv2.imread(args.image)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
ocr = OCR(ENG_CONFIG, image)
results = ocr.get_ocr_output()
The output it produces can be found here
While formatting texts which ocr outputs, I have converted a pixel to a single character. But it creates the text string where texts are separated by large whitespace.
So, How to decrease the whitespace to properly format the output texts by preserving all the spaces and alignment?

using openCV to open the webcam and take picture with it every five seconds

I tried to use the webcam and take pictures every 5 seconds via openCV but the cam itself didn't work and kept causing the error...
I also tried changing the integer in the cv2.VideoCapture() to -1 and 1 but still that didn't work.
This is the form of the error: "[ WARN:0] global /io/opencv/modules/videoio/src/cap_v4l.cpp (802)
open VIDEOIO ERROR: V4L: can't open camera by index 0
Traceback (most recent call last):
File "webcam_detect.py", line 176, in
raise IOError("Cannot open webcam")
OSError: Cannot open webcam"
import colorsys
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
import cv2
import time
import numpy as np
from keras import backend as K
from keras.models import load_model
from keras.layers import Input
from yolo3.model import yolo_eval, yolo_body, tiny_yolo_body
from yolo3.utils import image_preporcess
class YOLO(object):
_defaults = {
#"model_path": 'logs/trained_weights_final.h5',
"model_path": 'model_data/yolo_weights.h5',
"anchors_path": 'model_data/yolo_anchors.txt',
"classes_path": 'model_data/coco_classes.txt',
"score" : 0.3,
"iou" : 0.45,
"model_image_size" : (416, 416),
"text_size" : 1,
}
#classmethod
def get_defaults(cls, n):
if n in cls._defaults:
return cls._defaults[n]
else:
return "Unrecognized attribute name '" + n + "'"
def __init__(self, **kwargs):
self.__dict__.update(self._defaults) # set up default values
self.__dict__.update(kwargs) # and update with user overrides
self.class_names = self._get_class()
self.anchors = self._get_anchors()
self.sess = K.get_session()
self.boxes, self.scores, self.classes = self.generate()
def _get_class(self):
classes_path = os.path.expanduser(self.classes_path)
with open(classes_path) as f:
class_names = f.readlines()
class_names = [c.strip() for c in class_names]
return class_names
def _get_anchors(self):
anchors_path = os.path.expanduser(self.anchors_path)
with open(anchors_path) as f:
anchors = f.readline()
anchors = [float(x) for x in anchors.split(',')]
return np.array(anchors).reshape(-1, 2)
def generate(self):
model_path = os.path.expanduser(self.model_path)
assert model_path.endswith('.h5'), 'Keras model or weights must be a .h5 file.'
# Load model, or construct model and load weights.
num_anchors = len(self.anchors)
num_classes = len(self.class_names)
is_tiny_version = num_anchors==6 # default setting
try:
self.yolo_model = load_model(model_path, compile=False)
except:
self.yolo_model = tiny_yolo_body(Input(shape=(None,None,3)), num_anchors//2, num_classes) \
if is_tiny_version else yolo_body(Input(shape=(None,None,3)), num_anchors//3, num_classes)
self.yolo_model.load_weights(self.model_path) # make sure model, anchors and classes match
else:
assert self.yolo_model.layers[-1].output_shape[-1] == \
num_anchors/len(self.yolo_model.output) * (num_classes + 5), \
'Mismatch between model and given anchor and class sizes'
print('{} model, anchors, and classes loaded.'.format(model_path))
# Generate colors for drawing bounding boxes.
hsv_tuples = [(x / len(self.class_names), 1., 1.)
for x in range(len(self.class_names))]
self.colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples))
self.colors = list(
map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)),
self.colors))
np.random.shuffle(self.colors) # Shuffle colors to decorrelate adjacent classes.
# Generate output tensor targets for filtered bounding boxes.
self.input_image_shape = K.placeholder(shape=(2, ))
boxes, scores, classes = yolo_eval(self.yolo_model.output, self.anchors,
len(self.class_names), self.input_image_shape,
score_threshold=self.score, iou_threshold=self.iou)
return boxes, scores, classes
def detect_image(self, image):
if self.model_image_size != (None, None):
assert self.model_image_size[0]%32 == 0, 'Multiples of 32 required'
assert self.model_image_size[1]%32 == 0, 'Multiples of 32 required'
boxed_image = image_preporcess(np.copy(image), tuple(reversed(self.model_image_size)))
image_data = boxed_image
out_boxes, out_scores, out_classes = self.sess.run(
[self.boxes, self.scores, self.classes],
feed_dict={
self.yolo_model.input: image_data,
self.input_image_shape: [image.shape[0], image.shape[1]],#[image.size[1], image.size[0]],
K.learning_phase(): 0
})
#print('Found {} boxes for {}'.format(len(out_boxes), 'img'))
thickness = (image.shape[0] + image.shape[1]) // 600
fontScale=1
ObjectsList = []
for i, c in reversed(list(enumerate(out_classes))):
predicted_class = self.class_names[c]
box = out_boxes[i]
score = out_scores[i]
label = '{} {:.2f}'.format(predicted_class, score)
#label = '{}'.format(predicted_class)
scores = '{:.2f}'.format(score)
top, left, bottom, right = box
top = max(0, np.floor(top + 0.5).astype('int32'))
left = max(0, np.floor(left + 0.5).astype('int32'))
bottom = min(image.shape[0], np.floor(bottom + 0.5).astype('int32'))
right = min(image.shape[1], np.floor(right + 0.5).astype('int32'))
mid_h = (bottom-top)/2+top
mid_v = (right-left)/2+left
# put object rectangle
cv2.rectangle(image, (left, top), (right, bottom), self.colors[c], thickness)
# get text size
(test_width, text_height), baseline = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, thickness/self.text_size, 1)
# put text rectangle
cv2.rectangle(image, (left, top), (left + test_width, top - text_height - baseline), self.colors[c], thickness=cv2.FILLED)
# put text above rectangle
cv2.putText(image, label, (left, top-2), cv2.FONT_HERSHEY_SIMPLEX, thickness/self.text_size, (0, 0, 0), 1)
# add everything to list
ObjectsList.append([top, left, bottom, right, mid_v, mid_h, label, scores])
return image, ObjectsList
def close_session(self):
self.sess.close()
def detect_img(self, image):
#image = cv2.imread(image, cv2.IMREAD_COLOR)
original_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
original_image_color = cv2.cvtColor(original_image, cv2.COLOR_BGR2RGB)
r_image, ObjectsList = self.detect_image(original_image_color)
return r_image, ObjectsList
if __name__=="__main__":
yolo = YOLO()
# set start time to current time
#start_time = time.time()
# displays the frame rate every 2 second
#display_time = 2
# Set primarry FPS to 0
#fps = 0
# we create the video capture object cap
cap = cv2.VideoCapture(0)
if not cap.isOpened():
raise IOError("Cannot open webcam")
cap.set(3, 640)
cap.set(4,480)
img_counter=0
frame_set=[]
start_time=time.time()
#if not cap.isOpened():
#raise IOError("We cannot open webcam")
#while True:
#ret, frame = cap.read()
# resize our captured frame if we need
#frame = cv2.resize(frame, None, fx=1.0, fy=1.0,
interpolation=cv2.INTER_AREA)
# detect object on our frame
#r_image, ObjectsList = yolo.detect_img(frame)
# show us frame with detection
#cv2.imshow("Web cam input", r_image)
#if cv2.waitKey(25) & 0xFF == ord("q"):
#cv2.destroyAllWindows()
#break
# calculate FPS
#fps += 1
#TIME = time.time() - start_time
#if TIME > display_time:
#print("FPS:", fps / TIME)
#fps = 0
#start_time = time.time()
while True:
ret, frame = cap.read()
frame = cv2.resize(frame, None, fx=1.0, fy=1.0,
interpolation=cv2.INTER_AREA)
r_image, ObjectsList=yolo.detect_img(frame)
cv2.imshow('Web cam input', r_image)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
if time.time() - start_time >= 5: #<---- Check if 5 sec passed
img_name = "opencv_frame_{}.png".format(img_counter)
cv2.imwrite(img_name, frame)
print("{} written!".format(img_counter))
start_time = time.time()
img_counter += 1
cap.release()
cv2.destroyAllWindows()
yolo.close_session()

Memory problem executing python script that creates arrays and figures [duplicate]

This question already has answers here:
How to clear memory completely of all matplotlib plots
(5 answers)
Closed 3 years ago.
I will first describe the script and later will publish the code and a way to reproduce the problem, in my machine might not be the case for every machine.
So I have a script that build objects, clouds, with specific properties and export the data to files that is the input to a software called SHDOM, this tool analyze radiation properties and can be further read in the following link.
The script is its a bit long, sorry in advance:
import numpy as np
from itertools import product
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from mpl_toolkits.mplot3d import Axes3D
import gc
def writeDomainFile(type, file_name, temp_vec,
lwc, r_effective, dx, dy,
height_vec):
if type == 2:
assert list(lwc.shape) == list(r_effective.shape), "when the file type is 2 the shapes of lwc and r_effective shold be the same"
x_lwc, y_lwc, z_lwc = lwc.shape
x_r_effetive, y_r_effetive, z_r_effetive = r_effective.shape
fp = open(file_name, 'w')
# write the file format
fp.write("{:}\n".format(type))
# write the number of x, y, z points
fp.write("{:} {:} {:}\n".format(x_lwc, y_lwc, z_lwc))
# write the spacing resolution in x and y
fp.write("{:} {:}\n".format(dx, dy))
# write the height vector
fp.write(" ".join(map(str,height_vec)) + "\n")
# write the temprature vector
fp.write(" ".join(map(str,temp_vec)) + "\n")
indices = product(range(x_lwc), range(y_lwc), range(z_lwc))
print_indices = product(range(1, x_lwc + 1), range(1, y_lwc + 1), range(1, z_lwc + 1))
if type == 1: # only lwc
for triplet, print_triplets in zip(indices, print_indices):
# t = tuple(1 + list(triplet))
if not lwc[triplet]:
fp.write("{:} {:} {:} {:}\n".format(*print_triplets, 0))
else:
fp.write("{:} {:} {:} {:6.4f}\n".format(*print_triplets, lwc[triplet]))
elif type == 2:
for triplet, print_triplets in zip(indices, print_indices):
# t = tuple(map(lambda x: x + 1, list(triplet)))
if not lwc[triplet]:
fp.write("{:} {:} {:} {:} {:}\n".format(*print_triplets, 0, 0))
else:
fp.write("{:} {:} {:} {:6.4f} {:4.2f}\n".format(*print_triplets, lwc[triplet], r_effective[triplet]))
fp.close()
return
def lapseRateTemp(base_temp, position):
temp = np.zeros(position.shape)
temp[0] = base_temp
temp[1:] = base_temp - 6.5 * position[1:]
return np.round(temp, 4)
def createCubicCloudDomain(cloud_tick, x_size, y_size,
dx, dy, dz, r_effective_option, lwc_option,
cloud_x_size, cloud_y_size):
# const
temp0 = 300 # kelvin
N_x = x_size / dx # number of x points
N_y = y_size / dy # number of y points
cld_base = 1.0 # the cloud always start from 1[km] above ground
x_center = N_x / 2
y_center = N_y / 2
prog_x = (cloud_x_size / 2) / dx
prog_y = (cloud_y_size / 2) / dy
cloud_x_west = int(x_center - prog_x)
cloud_x_east = int(x_center + prog_x)
cloud_y_south = int(y_center - prog_y)
cloud_y_north = int(y_center + prog_y)
cloud_x_vec = np.arange(cloud_x_west, cloud_x_east, 1)
cloud_y_vec = np.arange(cloud_y_south, cloud_y_north, 1)
for tick in cloud_tick: # cloud_tick might be a vector
cld_top = cld_base + tick
N_z = tick / dz # number of z points
cloud_z_vec = np.round(np.arange(cld_base, cld_top, dz), 4)
# temprature
temp_base = temp0 - 9.8 * cld_base
temp_vec = lapseRateTemp(temp_base, cloud_z_vec - cld_base,)
temp_cloud = np.tile(temp_vec,(int(temp_vec.shape[0]), int(temp_vec.shape[0]), 1))
temp_domain = np.zeros((int(N_x), int(N_y), int(N_z)))
temp_domain[cloud_x_west:cloud_x_east, cloud_y_south: cloud_y_north, :] = temp_cloud
plotTemperatureGradient(temp_domain, 'test.png')
# del temp_cloud
# del temp_domain
# gc.collect()
for r in r_effective_option:
for l in lwc_option:
r_effective_cloud = np.full((cloud_x_vec.shape[0],
cloud_y_vec.shape[0],
cloud_z_vec.shape[0]),
r)
lwc_cloud = np.full((cloud_x_vec.shape[0],
cloud_y_vec.shape[0],
cloud_z_vec.shape[0]),
l)
r_effective_domain = np.zeros((int(N_x), int(N_y), int(N_z)))
lwc_domain = np.zeros((int(N_x), int(N_y), int(N_z)))
# the positions to enter the cloud data
lwc_domain[cloud_x_west:cloud_x_east, cloud_y_south: cloud_y_north, :] = lwc_cloud
r_effective_domain[cloud_x_west:cloud_x_east, cloud_y_south: cloud_y_north, :] = r_effective_cloud
writeDomainFile(2, "test.txt", temp_vec, lwc_domain, r_effective_domain, dx, dy, cloud_z_vec)
plotGeneratedCloud(lwc_domain, r_effective_domain)
return
def plotTemperatureGradient(temp_mat, file_name):
xs, ys, zs = temp_mat.shape
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
X, Y, Z = np.mgrid[:xs, :ys, :zs]
faltten_data = temp_mat.ravel().astype(np.float16)
color_map = np.zeros((faltten_data.shape[0], 4))
# map scalars to colors
minima = np.min(faltten_data[np.nonzero(faltten_data)])
maxima = np.max(faltten_data[np.nonzero(faltten_data)])
norm = matplotlib.colors.Normalize(vmin=minima, vmax=maxima, clip=True)
mapper = cm.ScalarMappable(norm=norm, cmap='jet')
rgba = mapper.to_rgba(faltten_data)
color_map[:,0:3] = rgba[:, 0:3]
color_map[:,3] = np.where(faltten_data > 0, 0.07, 0)
p = ax.scatter(X, Y, Z, c=color_map.astype(np.float16))
ax.set_xlabel('X position [Arb.]')
ax.set_ylabel('Y position [Arb.]')
ax.set_zlabel('Z position [Arb.]')
fig.colorbar(p)
# plt.title(title)
plt.savefig(file_name)
return
def plotGeneratedCloud(lwc, r_effective):
light_blue = np.array([0, 1, 0.7])
matrixPlotter(lwc, 'lwc.png',
'Liquid water content of the cloud',
light_blue)
# gc.collect()
light_pink = np.array([0.9, 0.6, 0.9])
matrixPlotter(r_effective, 'r_effective.png',
'Effective radius of the cloud',
light_pink)
return
def matrixPlotter(mat, file_name, title, c=np.array([0.2, 0.6, 0])):
xs, ys, zs = mat.shape
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
X, Y, Z = np.mgrid[:xs, :ys, :zs]
faltten_data = mat.ravel().astype(np.float16)
color_map = np.zeros((faltten_data.shape[0], 4))
color_map[:,0:3] = c
color_map[:,3] = np.where(faltten_data > 0, 0.07, 0)
ax.scatter(X, Y, Z, c=color_map.astype(np.float16))
ax.set_xlabel('X position [Arb.]')
ax.set_ylabel('Y position [Arb.]')
ax.set_zlabel('Z position [Arb.]')
plt.title(title)
plt.savefig(file_name)
return
# def main():
# return
if __name__ == '__main__':
# main()
createCubicCloudDomain([0.5], 2.02, 2.02, 0.01, 0.01, 0.01, [0.5], [1], 0.5, 0.5)
print("Done")
So the problem occur when:
I try to export all 3 plots, calling the following blocks:
plotGeneratedCloud(lwc_domain, r_effective_domain) or
temp_cloud = np.tile(temp_vec,(int(temp_vec.shape[0]), int(temp_vec.shape[0]), 1))
temp_domain = np.zeros((int(N_x), int(N_y), int(N_z)))
temp_domain[cloud_x_west:cloud_x_east, cloud_y_south: cloud_y_north, :] = temp_cloud
plotTemperatureGradient(temp_domain, 'test.png')
When I try to create more then 1 object (cloud), so calling the function with:
createCubicCloudDomain([0.5, 0.6], 2.02, 2.02, 0.01, 0.01, 0.01, [0.5, 0.4], [1, 0.3], 0.5, 0.5)
increasing the domain size like:
createCubicCloudDomain([0.5], 4.02, 4.02, 0.01, 0.01, 0.01, [0.5], [1], 0.5, 0.5)
The type of error I'm getting is the following:
File
"C:\Users\davidsr\AppData\Local\Programs\Python\Python38-32\lib\site-packages\matplotlib\backends\backend_agg.py",
line 396, in draw
self.figure.draw(self.renderer) File "C:\Users\davidsr\AppData\Local\Programs\Python\Python38-32\lib\site-packages\matplotlib\artist.py",
line 38, in draw_wrapper
return draw(artist, renderer, *args, **kwargs) File "C:\Users\davidsr\AppData\Local\Programs\Python\Python38-32\lib\site-packages\matplotlib\figure.py",
line 1735, in draw
mimage._draw_list_compositing_images( File "C:\Users\davidsr\AppData\Local\Programs\Python\Python38-32\lib\site-packages\matplotlib\image.py",
line 137, in _draw_list_compositing_images
a.draw(renderer) File "C:\Users\davidsr\AppData\Local\Programs\Python\Python38-32\lib\site-packages\matplotlib\artist.py",
line 38, in draw_wrapper
return draw(artist, renderer, *args, **kwargs) File "C:\Users\davidsr\AppData\Local\Programs\Python\Python38-32\lib\site-packages\mpl_toolkits\mplot3d\axes3d.py",
line 291, in draw
sorted(self.collections, File "C:\Users\davidsr\AppData\Local\Programs\Python\Python38-32\lib\site-packages\mpl_toolkits\mplot3d\axes3d.py",
line 292, in
key=lambda col: col.do_3d_projection(renderer), File "C:\Users\davidsr\AppData\Local\Programs\Python\Python38-32\lib\site-packages\mpl_toolkits\mplot3d\art3d.py",
line 538, in do_3d_projection
vxs, vys, vzs, vis = proj3d.proj_transform_clip(xs, ys, zs, renderer.M) File
"C:\Users\davidsr\AppData\Local\Programs\Python\Python38-32\lib\site-packages\mpl_toolkits\mplot3d\proj3d.py",
line 214, in proj_transform_clip
vec = _vec_pad_ones(xs, ys, zs) File "C:\Users\davidsr\AppData\Local\Programs\Python\Python38-32\lib\site-packages\mpl_toolkits\mplot3d\proj3d.py",
line 189, in _vec_pad_ones
return np.array([xs, ys, zs, np.ones_like(xs)]) MemoryError: Unable to allocate array with shape (4, 2040200) and data type float64
I understand the problem is memory issues, so I thought that deleting the arrays once finish with them might solve the problem, so i used del function or even using the garbage collector solution used in the following question: How can I explicitly free memory in Python?
Would appreciate some help
The figure object persists in memory if you don't .close() it first, and it includes all the data it's plotting.
Try putting a plt.close(fig) before the return statement in matrixPlotter. Then your gc.collect() statements should be able to catch it if it's not collected by matplotlib (and I don't think it is).

Python Image Compression

I am using the Pillow library of Python to read in image files. How can I compress and decompress using Huffman encoding? Here is an instruction:
You have been given a set of example images and your goal is to compress them as much as possible without losing any perceptible information –upon decompression they should appear identical to the original images. Images are essentially stored as a series of points of color, where each point is represented as a combination of red, green, and blue (rgb). Each component of the rgb value ranges between 0-255, so for example: (100, 0, 200) would represent a shade of purple. Using a fixed-length encoding, each component of the rgb value requires 8 bits to encode (28= 256) meaning that the entire rgb value requires 24 bits to encode. You could use a compression algorithm like Huffman encoding to reduce the number of bits needed for more common values and thereby reduce the total number of bits needed to encode your image.
# For my current code I just read the image, get all the rgb and build the tree
from PIL import Image
import sys, string
import copy
codes = {}
def sortFreq(freqs):
letters = freqs.keys()
tuples = []
for let in letters:
tuples.append (freqs[let],let)
tuples.sort()
return tuples
def buildTree(tuples):
while len (tuples) > 1:
leastTwo = tuple (tuples[0:2]) # get the 2 to combine
theRest = tuples[2:] # all the others
combFreq = leastTwo[0][0] + leastTwo[1][0] # the branch points freq
tuples = theRest + [(combFreq, leastTwo)] # add branch point to the end
tuples.sort() # sort it into place
return tuples[0] # Return the single tree inside the list
def trimTree(tree):
# Trim the freq counters off, leaving just the letters
p = tree[1] # ignore freq count in [0]
if type (p) == type (""):
return p # if just a leaf, return it
else:
return (trimTree (p[0]), trimTree (p[1]) # trim left then right and recombine
def assignCodes(node, pat=''):
global codes
if type (node) == type (""):
codes[node] = pat # A leaf. Set its code
else:
assignCodes(node[0], pat+"0") # Branch point. Do the left branch
assignCodes(node[1], pat+"1") # then do the right branch.
dictionary = {}
table = {}
image = Image.open('fall.bmp')
#image.show()
width, height = image.size
px = image.load()
totalpixel = width*height
print ("Total pixel: "+ str(totalpixel))
for x in range (width):
for y in range (height):
# print (px[x, y])
for i in range (3):
if dictionary.get(str(px[x, y][i])) is None:
dictionary[str(px[x, y][i])] = 1
else:
dictionary[str(px[x, y][i])] = dictionary[str(px[x, y][i])] +1
table = copy.deepcopy(dictionary)
#combination = len(dictionary)
#for value in table:
# table[value] = table[value] / (totalpixel * combination) * 100
#print(table)
print(dictionary)
sortdic = sortFreq(dictionary)
tree = buildTree(sortdic)
trim = trimTree(tree)
print(trim)
assignCodes(trim)
print(codes)
The class HuffmanCoding takes complete path of the text file to be compressed as parameter. (as its data members store data specific to the input file).
The compress() function returns the path of the output compressed file.
The function decompress() requires path of the file to be decompressed. (and decompress() is to be called from the same object created for compression, so as to get code mapping from its data members)
import heapq
import os
class HeapNode:
def __init__(self, char, freq):
self.char = char
self.freq = freq
self.left = None
self.right = None
def __cmp__(self, other):
if(other == None):
return -1
if(not isinstance(other, HeapNode)):
return -1
return self.freq > other.freq
class HuffmanCoding:
def __init__(self, path):
self.path = path
self.heap = []
self.codes = {}
self.reverse_mapping = {}
# functions for compression:
def make_frequency_dict(self, text):
frequency = {}
for character in text:
if not character in frequency:
frequency[character] = 0
frequency[character] += 1
return frequency
def make_heap(self, frequency):
for key in frequency:
node = HeapNode(key, frequency[key])
heapq.heappush(self.heap, node)
def merge_nodes(self):
while(len(self.heap)>1):
node1 = heapq.heappop(self.heap)
node2 = heapq.heappop(self.heap)
merged = HeapNode(None, node1.freq + node2.freq)
merged.left = node1
merged.right = node2
heapq.heappush(self.heap, merged)
def make_codes_helper(self, root, current_code):
if(root == None):
return
if(root.char != None):
self.codes[root.char] = current_code
self.reverse_mapping[current_code] = root.char
return
self.make_codes_helper(root.left, current_code + "0")
self.make_codes_helper(root.right, current_code + "1")
def make_codes(self):
root = heapq.heappop(self.heap)
current_code = ""
self.make_codes_helper(root, current_code)
def get_encoded_text(self, text):
encoded_text = ""
for character in text:
encoded_text += self.codes[character]
return encoded_text
def pad_encoded_text(self, encoded_text):
extra_padding = 8 - len(encoded_text) % 8
for i in range(extra_padding):
encoded_text += "0"
padded_info = "{0:08b}".format(extra_padding)
encoded_text = padded_info + encoded_text
return encoded_text
def get_byte_array(self, padded_encoded_text):
if(len(padded_encoded_text) % 8 != 0):
print("Encoded text not padded properly")
exit(0)
b = bytearray()
for i in range(0, len(padded_encoded_text), 8):
byte = padded_encoded_text[i:i+8]
b.append(int(byte, 2))
return b
def compress(self):
filename, file_extension = os.path.splitext(self.path)
output_path = filename + ".bin"
with open(self.path, 'r+') as file, open(output_path, 'wb') as output:
text = file.read()
text = text.rstrip()
frequency = self.make_frequency_dict(text)
self.make_heap(frequency)
self.merge_nodes()
self.make_codes()
encoded_text = self.get_encoded_text(text)
padded_encoded_text = self.pad_encoded_text(encoded_text)
b = self.get_byte_array(padded_encoded_text)
output.write(bytes(b))
print("Compressed")
return output_path
""" functions for decompression: """
def remove_padding(self, padded_encoded_text):
padded_info = padded_encoded_text[:8]
extra_padding = int(padded_info, 2)
padded_encoded_text = padded_encoded_text[8:]
encoded_text = padded_encoded_text[:-1*extra_padding]
return encoded_text
def decode_text(self, encoded_text):
current_code = ""
decoded_text = ""
for bit in encoded_text:
current_code += bit
if(current_code in self.reverse_mapping):
character = self.reverse_mapping[current_code]
decoded_text += character
current_code = ""
return decoded_text
def decompress(self, input_path):
filename, file_extension = os.path.splitext(self.path)
output_path = filename + "_decompressed" + ".txt"
with open(input_path, 'rb') as file, open(output_path, 'w') as output:
bit_string = ""
byte = file.read(1)
while(byte != ""):
byte = ord(byte)
bits = bin(byte)[2:].rjust(8, '0')
bit_string += bits
byte = file.read(1)
encoded_text = self.remove_padding(bit_string)
decompressed_text = self.decode_text(encoded_text)
output.write(decompressed_text)
print("Decompressed")
return output_path
Running the program:
Save the above code, in a file huffman.py.
Create a sample text file. Or download a sample file from sample.txt (right click, save as)
Save the code below, in the same directory as the above code, and Run this python code (edit the path variable below before running. initialize it to text file path)
UseHuffman.py
from huffman import HuffmanCoding
#input file path
path = "/home/ubuntu/Downloads/sample.txt"
h = HuffmanCoding(path)
output_path = h.compress()
h.decompress(output_path)
The compressed .bin file and the decompressed file are both saved in the same directory as of the input file.
Result
On running on the above linked sample text file:
Initial Size: 715.3 kB
Compressed file Size: 394.0 kB
Plus, the decompressed file comes out to be exactly the same as the original file, without any data loss.
And that is all for Huffman Coding implementation, with compression and decompression. This was fun to code.
The above program requires the decompression function to be run using the same object that created the compression file (because the code mapping is stored in its data members). We can also make the compression and decompression function run independently, if somehow, during compression we store the mapping info also in the compressed file (in the beginning). Then, during decompression, we will first read the mapping info from the file, then use that mapping info to decompress the rest file.

AssertionError: Format for classes is `<label> file`

This is a python script for detecting features in a set of images for a SVM.
import os
import sys
import argparse
import _pickle as cPickle
import json
import cv2
import numpy as np
from sklearn.cluster import KMeans
def build_arg_parser():
parser = argparse.ArgumentParser(description='Creates features for given images')
parser.add_argument("--samples", dest="cls", nargs="+", action="append",
required=True, help="Folders containing the training images. \
The first element needs to be the class label.")
parser.add_argument("--codebook-file", dest='codebook_file', required=True,
help="Base file name to store the codebook")
parser.add_argument("--feature-map-file", dest='feature_map_file', required=True,
help="Base file name to store the feature map")
parser.add_argument("--scale-image", dest="scale", type=int, default=150,
help="Scales the longer dimension of the image down to this size.")
return parser
def load_input_map(label, input_folder):
combined_data = []
if not os.path.isdir(input_folder):
print ("The folder " + input_folder + " doesn't exist")
raise IOError
for root, dirs, files in os.walk(input_folder):
for filename in (x for x in files if x.endswith('.jpg')):
combined_data.append({'label': label, 'image': os.path.join(root, filename)})
return combined_data
class FeatureExtractor(object):
def extract_image_features(self, img):
kps = DenseDetector().detect(img)
kps, fvs = SIFTExtractor().compute(img, kps)
return fvs
def get_centroids(self, input_map, num_samples_to_fit=10):
kps_all = []
count = 0
cur_label = ''
for item in input_map:
if count >= num_samples_to_fit:
if cur_label != item['label']:
count = 0
else:
continue
count += 1
if count == num_samples_to_fit:
print ("Built centroids for", item['label'])
cur_label = item['label']
img = cv2.imread(item['image'])
img = resize_to_size(img, 150)
num_dims = 128
fvs = self.extract_image_features(img)
kps_all.extend(fvs)
kmeans, centroids = Quantizer().quantize(kps_all)
return kmeans, centroids
def get_feature_vector(self, img, kmeans, centroids):
return Quantizer().get_feature_vector(img, kmeans, centroids)
def extract_feature_map(input_map, kmeans, centroids):
feature_map = []
for item in input_map:
temp_dict = {}
temp_dict['label'] = item['label']
print ("Extracting features for", item['image'])
img = cv2.imread(item['image'])
img = resize_to_size(img, 150)
temp_dict['feature_vector'] = FeatureExtractor().get_feature_vector(
img, kmeans, centroids)
if temp_dict['feature_vector'] is not None:
feature_map.append(temp_dict)
return feature_map
class Quantizer(object):
def __init__(self, num_clusters=32):
self.num_dims = 128
self.extractor = SIFTExtractor()
self.num_clusters = num_clusters
self.num_retries = 10
def quantize(self, datapoints):
kmeans = KMeans(self.num_clusters,
n_init=max(self.num_retries, 1),
max_iter=10, tol=1.0)
res = kmeans.fit(datapoints)
centroids = res.cluster_centers_
return kmeans, centroids
def normalize(self, input_data):
sum_input = np.sum(input_data)
if sum_input > 0:
return input_data / sum_input
else:
return input_data
def get_feature_vector(self, img, kmeans, centroids):
kps = DenseDetector().detect(img)
kps, fvs = self.extractor.compute(img, kps)
labels = kmeans.predict(fvs)
fv = np.zeros(self.num_clusters)
for i, item in enumerate(fvs):
fv[labels[i]] += 1
fv_image = np.reshape(fv, ((1, fv.shape[0])))
return self.normalize(fv_image)
class DenseDetector(object):
def __init__(self, step_size=20, feature_scale=40, img_bound=20):
self.detector = cv2.xfeatures2d.SIFT_create("Dense")
self.detector.setInt("initXyStep", step_size)
self.detector.setInt("initFeatureScale", feature_scale)
self.detector.setInt("initImgBound", img_bound)
def detect(self, img):
return self.detector.detect(img)
class SIFTExtractor(object):
def compute(self, image, kps):
if image is None:
print ("Not a valid image")
raise TypeError
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
kps, des = cv2.SIFT().compute(gray_image, kps)
return kps, des
# Resize the shorter dimension to 'new_size'
# while maintaining the aspect ratio
def resize_to_size(input_image, new_size=150):
h, w = input_image.shape[0], input_image.shape[1]
ds_factor = new_size / float(h)
if w < h:
ds_factor = new_size / float(w)
new_size = (int(w * ds_factor), int(h * ds_factor))
return cv2.resize(input_image, new_size)
if __name__=='__main__':
args = build_arg_parser().parse_args()
input_map = []
for cls in args.cls:
assert len(cls) >= 2, "Format for classes is `<label> file`"
label = cls[0]
input_map += load_input_map(label, cls[1])
downsample_length = args.scale
# Building the codebook
print ("===== Building codebook =====")
kmeans, centroids = FeatureExtractor().get_centroids(input_map)
if args.codebook_file:
with open(args.codebook_file, 'w') as f:
pickle.dump((kmeans, centroids), f)
# Input data and labels
print ("===== Building feature map =====")
feature_map = extract_feature_map(input_map, kmeans, centroids)
if args.feature_map_file:
with open(args.feature_map_file, 'w') as f:
pickle.dump(feature_map, f)
I receive the following error:
Traceback (most recent call last):
File "create_features.py", line 164, in <module>
assert len(cls) >= 2, ("Format for classes is `<label> file`")
AssertionError: Format for classes is `<label> file`
Any idea of what could be wrong? I'm just following the instructions of 'OpenCV with Python by Example' of Prateek Joshi. Pages 494-526
Assertion are used to check a condition. If the condition isn't satisfied, it throes AssertionError. In your case, len(cls) >= 2 isn't satisfied. It means that len(cls) is smaller than 2. Apparently, cls is a list of arguments passed to the programm. And the first element of this list must be a label. And when you add argument (a file), you should specify a label for this file.
For example, if you choose a label name my_label, you must add file with my_label my_file.

Resources