texts formatting with maintaining texts alignment - python-3.x

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?

Related

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()

Only load segment of text file using numpy and itertools

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)

Python 3 encoding russian text

I have a dataset with Russian text, which looks like this:
I am trying to pre-process this dataset and split it to train,dev and testing datasets by using the following code:
# coding=utf-8
import os
import argparse
import xml.etree.ElementTree as ET
import random
import math
from collections import Counter
from utils import semeval2014term_to_aspectsentiment_hr
from copy import copy, deepcopy
parser = argparse.ArgumentParser(description='Generate finetuning corpus for restaurants.')
parser.add_argument('--noconfl',
action='store_true',
default=False,
help='Remove conflicting sentiments from labels')
parser.add_argument('--istrain',
action='store_true',
default=False,
help='If is a training set we split of 10% and output train_full, train_split, dev. Default is testset creating no split')
parser.add_argument("--files",
type=str,
nargs='+',
action="store",
help="File that contains the data used for training. Multiple paths will mix the datasets.")
parser.add_argument("--output_dir",
type=str,
action="store",
default="data/transformed/untitled",
help="output dir of the dataset(s)")
parser.add_argument("--upsample",
type=str,
action="store",
default=None,
help="please add a string with 3 numbers like '0.5 0.3 0.2' representing relative numbers of 'POS NEG NEU' adding to 1"
" which represents target distribution - only valid in non-confl case")
parser.add_argument("--seed",
type=int,
action="store",
default=41,
help="random seed, effects on upsampling and validationset")
args = parser.parse_args()
# 1. Load The Dataset
# 2. Create Bert-Pair Style Format
# 3. Save Train, Validation and so on
def split_shuffle_array(ratio, array, rseed):
# split_ratio_restaurant = .076 # for 150 sentence in conflicting case
# split_ratio_laptops = .101 # for 150 sentences in conflicting case
random.Random(rseed).shuffle(array)
m = math.floor(ratio * len(array))
return array[0:m], array[m::]
def create_sentence_pairs(sents, aspect_term_sentiments):
# create sentence_pairs
all_sentiments = []
sentence_pairs = []
labels = []
for ix, ats in enumerate(aspect_term_sentiments):
s = sents[ix]
for k, v in ats:
all_sentiments.append(v)
sentence_pairs.append((s, k))
labels.append(v)
counts = Counter(all_sentiments)
return sentence_pairs, labels, counts
def upsample_data(sentence_pairs, labels, target_ratios={'POS': 0.53, 'NEG': 0.21, 'NEU': 0.26}):
# one question: should we upsample sentencepairs, where the sentence only occurs once?!
print('Upsampling data ...')
# print(sentence_pairs, labels) # is list of pairs -> decide which pair to upsample ...
# 0. compute indeex subsets for every example
# 1. compute how many samples to sample ->
ix_subsets = {
'POS': [],
'NEG': [],
'NEU': []
}
ratios_subsets = {
'POS': 0,
'NEG': 0,
'NEU': 0
}
examples_to_add = {
'POS': 0,
'NEG': 0,
'NEU': 0
}
n = float(len(labels))
for ix, l in enumerate(labels):
ix_subsets[l].append(ix)
ratios_subsets[l] += (1.0 / n)
t_keys = target_ratios.keys()
tmp = [math.floor(target_ratios[k] * n) - len(ix_subsets[k]) for k in t_keys]
class_nothing_to_add = list(t_keys)[tmp.index(min(tmp))]
print(t_keys)
print(ratios_subsets)
print(tmp)
print(class_nothing_to_add)
# print(ix_subsets)
m = len(ix_subsets[class_nothing_to_add]) / target_ratios[class_nothing_to_add]
total_to_add = m - n
print(n, math.floor(m))
examples_to_add = {k: math.floor(target_ratios[k] * m - len(ix_subsets[k])) for k in t_keys}
print(examples_to_add) # so we need to add more neutral examples and more positiev ones
# downsampling would be set 0 the maximum amount of negative ones
# now select all the indices, with replacement because it can be more than double
new_samples = []
for k in t_keys:
new_samples.extend(random.Random(args.seed).choices(ix_subsets[k], k=examples_to_add[k]))
print(len(new_samples))
# now add all new samples to the dataset and shuffle it
new_sentence_pairs = copy(sentence_pairs)
new_labels = labels.copy()
for ix in new_samples:
new_sentence_pairs.append(copy(sentence_pairs[ix]))
new_labels.append(labels[ix])
random.Random(args.seed).shuffle(new_sentence_pairs)
random.Random(args.seed).shuffle(new_labels)
print(len(set(new_sentence_pairs)))
print(len(set(sentence_pairs)))
return new_sentence_pairs, new_labels
def export_dataset_to_xml(fn, sentence_pairs, labels):
# export in format semeval 2014, incomplete though! just for loading with existing dataloaders for ATSC
sentences_el = ET.Element('sentences')
sentimap_reverse = {
'POS': 'positive',
'NEU': 'neutral',
'NEG': 'negative',
'CONF': 'conflict'
}
for ix, (sentence, aspectterm) in enumerate(sentence_pairs):
# print(sentence)
sentiment = labels[ix]
sentence_el = ET.SubElement(sentences_el, 'sentence')
sentence_el.set('id', str(ix))
text = ET.SubElement(sentence_el, 'text')
text.text = str(sentence).strip()
aspect_terms_el = ET.SubElement(sentence_el, 'aspectTerms')
aspect_term_el = ET.SubElement(aspect_terms_el, 'aspectTerm')
aspect_term_el.set('term', aspectterm)
aspect_term_el.set('polarity', sentimap_reverse[sentiment])
aspect_term_el.set('from', str('0'))
aspect_term_el.set('to', str('0'))
def indent(elem, level=0):
i = "\n" + level * " "
j = "\n" + (level - 1) * " "
if len(elem):
if not elem.text or not elem.text.strip():
elem.text = i + " "
if not elem.tail or not elem.tail.strip():
elem.tail = i
for subelem in elem:
indent(subelem, level + 1)
if not elem.tail or not elem.tail.strip():
elem.tail = j
else:
if level and (not elem.tail or not elem.tail.strip()):
elem.tail = j
return elem
indent(sentences_el)
# mydata = ET.dump(sentences_el)
mydata = ET.tostring(sentences_el)
with open(fn, "wb") as f:
# f.write('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>')
f.write(mydata)
f.close()
def save_dataset_to_tsv(fn, data):
pass
sentence_pairs_train_mixed = []
sentence_pairs_trainsplit_mixed = []
sentence_pairs_dev_mixed = []
sentence_pairs_test_mixed = []
labels_train_mixed = []
labels_trainsplit_mixed = []
labels_dev_mixed = []
labels_test_mixed = []
for fn in args.files:
print(args.output_dir)
if not os.path.exists(args.output_dir):
os.makedirs(args.output_dir)
print(fn)
sents_train, ats_train, idx2labels = semeval2014term_to_aspectsentiment_hr(fn,
remove_conflicting=args.noconfl)
sentence_pairs_train, labels_train, counts_train = create_sentence_pairs(sents_train, ats_train)
if args.istrain:
sents_dev, sents_trainsplit = split_shuffle_array(.1, sents_train, 41)
ats_dev, ats_trainsplit = split_shuffle_array(.1, ats_train, 41)
sentence_pairs_dev, labels_dev, counts_dev = create_sentence_pairs(sents_dev, ats_dev)
sentence_pairs_trainsplit, labels_trainsplit, counts_trainsplit = create_sentence_pairs(sents_trainsplit,
ats_trainsplit)
print_dataset_stats('Train', sents_train, sentence_pairs_train, counts_train)
print_dataset_stats('Dev', sents_dev, sentence_pairs_dev, counts_dev)
print_dataset_stats('TrainSplit', sents_trainsplit, sentence_pairs_trainsplit, counts_trainsplit)
sentence_pairs_trainsplit_mixed += sentence_pairs_trainsplit
sentence_pairs_train_mixed += sentence_pairs_train
sentence_pairs_dev_mixed += sentence_pairs_dev
labels_trainsplit_mixed += labels_trainsplit
labels_train_mixed += labels_train
labels_dev_mixed += labels_dev
if len(args.files) == 1:
if args.upsample:
distro_arr = args.upsample.split(' ')
pos = float(distro_arr[0])
neg = float(distro_arr[1])
neu = float(distro_arr[2])
assert pos + neg + neu == 1.0, 'upsampling target distribution does not sum to 1'
target_distro = {'POS': pos, 'NEG': neg, 'NEU': neu}
print('Target Sampling Distribution for Training Set:', target_distro)
sentence_pairs_train, labels_train = upsample_data(sentence_pairs_train, labels_train, target_ratios=target_distro)
export_dataset_to_xml(args.output_dir + '/train.xml', sentence_pairs_train, labels_train)
export_dataset_to_xml(args.output_dir + '/dev.xml', sentence_pairs_dev, labels_dev)
export_dataset_to_xml(args.output_dir + '/train_split.xml', sentence_pairs_trainsplit, labels_trainsplit)
else:
sentence_pairs_test_mixed += sentence_pairs_train
labels_test_mixed += labels_train
print_dataset_stats('Test', sents_train, sentence_pairs_train, counts_train)
if len(args.files) == 1:
export_dataset_to_xml(args.output_dir + '/test.xml', sentence_pairs_train, labels_train)
if len(args.files) > 1:
if args.istrain:
export_dataset_to_xml(args.output_dir + '/train.xml', sentence_pairs_train_mixed, labels_train_mixed)
export_dataset_to_xml(args.output_dir + '/dev.xml', sentence_pairs_dev_mixed, labels_dev_mixed)
export_dataset_to_xml(args.output_dir + '/train_split.xml', sentence_pairs_trainsplit_mixed,
labels_trainsplit_mixed)
else:
export_dataset_to_xml(args.output_dir + '/test.xml', sentence_pairs_test_mixed, labels_test_mixed)
After running the code above I have this result:
For English text it works just fine. Could someone help me to fix this and get normal text?
ET.tostring(sentences_el, encoding='UTF-8')

How to give x and y labels while plotting a graph in python using networkx module?

How to plot a graph with x and y labels in networkx ?
def particles_visualization(self,neighbour_listx,particles):
G=nx.Graph()
print(particles)
print(neighbour_listx)
for i in range(len(particles)):
G.add_node(particles[i][0], pos=(particles[i][1], particles[i[2]))
for i in range(len(neighbour_listx)):
G.add_edge(neighbour_listx[i][0], neighbour_listx[i][1])
pos = nx.get_node_attributes(G, 'pos')
#nx.draw_networkx_labels(G, pos)
plt.title("CLUSTERING NETWORK'S")
# Limits for the Y axis
plt.ylim(0, 100)
# Create names
plt.xlim(0,100)
plt.xlabel('X-AXIS')
plt.ylabel('Y-AXIS')
nx.draw(G, pos, with_labels=True)
plt.draw()
plt.show()
IMAGE URL: https://cdn-images-1.medium.com/max/1600/0*Jwm3mV92c3qRhqEl.
i want output with grid x and y labels as shown in the picture visit IMAGE URL
import sys
import os
import time
import random
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
class wireless_sensor_networks:
def __init__(self):
self.user_input()
def user_input(self):
print("ENTER THE DIMENSION OF THE FIELD AS (Length Breadth [as Int]) : ")
length,breadth=list(map(int,input().split(" ")))
print("ENTER THE NUMBER OF NODES THAT IS NEEDED TO BE DEPLOYED [as INT] :")
nodes=int(input())
print(length,breadth,nodes)
self.cluster_creation(length,breadth,nodes)
def cluster_creation(self,length,breadth,nodes):
print("""ENTER TYPE OF CLUSTER CREATION:
1. AREA WISE CLUSTER CREATION
2. DEFAULT (NOT KNOWS AS OF NOW) :""")
cluster_option=int(input())
if cluster_option==1:
self.cluster_area_wise(length,breadth,nodes)
elif cluster_option==2:
pass
else:
pass
def cluster_area_wise(self,length,breadth,nodes):
print("ENTER THE NUMBER OF CLUSTERS YOU WANT TO CREATE :")
number_of_clusters=int(input()) #can be changed to user input later on
x=length//(number_of_clusters**0.5)
y=breadth//(number_of_clusters**0.5)
cluster_list=[]
cluster_count=1
x=int(x)
y=int(y)
print(length,breadth,x,y)
#THE CLUSTERING ASSIGNMENT CAUSES ERROR DURING UNEVEN LENGTH AND BREADTH ASSIGNMENT
for x_axis in range(0,length,x):
for y_axis in range(0,breadth,y):
cluster_number="CLUSTER "+str(cluster_count)
cluster_count+=1
cluster_list.append([cluster_number,[],[[x_axis,x_axis+x],[y_axis,y_axis+y]]])
#print(cluster_list)
self.deployment(length,breadth,nodes,cluster_list)
def sergation_of_nodes_in_cluster(self,length,breadth,nodes,cluster_list,particles):
for each_partilcle in particles:
for node_cluster in cluster_list:
if ((each_partilcle[1][0]>=node_cluster[2][0][0] and each_partilcle[1][0]<node_cluster[2][0][1]) and (each_partilcle[1][1]>=node_cluster[2][1][0] and each_partilcle[1][1]<node_cluster[2][1][1])):
node_cluster[1].append(each_partilcle)
break
#print(cluster_list)
for each in cluster_list:
print(each[0],each[1],len(each[1])/nodes)
print(cluster_list)
self.visualization(length,breadth,cluster_list,particles)
def deployment(self,length,breadth,nodes,cluster_list):
print("""CHOOSE A DEPLOYMENT TYPE AS OPTIONS -
1. RANDOM DEPLOYMENT
2. SPIRAL DEPPLYMENT
3. SQUARE DEPLYMENT
4. DEFAULT DEPLOYMENT""")
deployment_option=int(input())
print(deployment_option)
if deployment_option==1:
self.random_deployment(length,breadth,nodes,cluster_list)
elif deployment_option==2:
self.spiral_deployment(length,breadth,nodes,cluster_list)
elif deployment_option==3:
self.square_deployment(length,breadth,nodes,cluster_list)
else:
self.default_deployment(length,breadth,nodes,cluster_list)
def random_deployment(self,length,breadth,nodes,cluster_list):
no_of_particles = nodes
particles = []
for i in range(no_of_particles):
id = i+1 # creates a id of the particles
x_cordinate = round(random.randrange(0,length),2)+round(random.random(),2)# creates the x cordinate of the particle in the range 0-100 units
y_cordinate = round(random.randrange(0,breadth),2)+round(random.random(),2) # creates the y cordinate of the particles in the range 0-100 units
# print(x_cordinate,y_cordinate)
battery=0 #change it later on
particles.append([id,[x_cordinate,y_cordinate],[battery]])
print(particles)
self.sergation_of_nodes_in_cluster(length,breadth,nodes,cluster_list,particles)
def spiral_deployment(self,length,breadth,nodes,cluster_list):
listx = []
particles=[]
def spiralPrint(m, n):
k = 0
l = 0
''' k - starting row index
m - ending row index
l - starting column index
n - ending column index
i - iterator '''
while (k < m and l < n):
# Print the first row from
# the remaining rows
for i in range(l, n):
particles.append([k, i])
#print("({},{})".format(k + 0.5, i + 0.5), end=" ")
k += 1
# Print the last column from
# the remaining columns
for i in range(k, m):
particles.append([i, n - 1])
#print("({},{})".format(i + 0.5, n - 1 + 0.5), end=" ")
n -= 1
# Print the last row from
# the remaining rows
if (k < m):
for i in range(n - 1, (l - 1), -1):
#print("({},{})".format(m - 1 + 0.5, i + 0.5), end=" ")
particles.append([m - 1, i])
m -= 1
# Print the first column from
# the remaining columns
if (l < n):
for i in range(m - 1, k - 1, -1):
#print("({},{})".format(i + 0.5, l + 0.5), end=" ")
particles.append([i, l])
l += 1
spiralPrint(length, breadth)
listx=particles
print("""ENTER THE TIME INTERVAL IN UNITS""")
time_interval=int(input())
time_interval=time_interval/nodes
node_interval=len(listx)//nodes
time=0
id=1
particles=[]
battery=0
for i in range(0,len(listx),node_interval):
particles.append([id,[listx[i][0],listx[i][1]],[battery],time])
time+=time_interval
id+=1
print(particles)
self.sergation_of_nodes_in_cluster(length, breadth, nodes, cluster_list, particles)
def square_deployment(self,length,breadth,nodes,cluster_list):
print("""ENTER THE TIME INTERVAL IN UNITS""")
time_interval = int(input())
time_interval=time_interval/nodes
no_of_particles = nodes
particles = []
timex=0
breadth_sqr=breadth
no_of_clusters=len(cluster_list)
breadth_start=int(breadth_sqr-((breadth_sqr//(no_of_clusters**0.5))//2))
breadth_incx=int(breadth_sqr//(no_of_clusters**0.5))
id=0
flx=0
while(breadth_start>0):
y_cordinate=breadth_start
flx+=1
temp=[]
battery=0 #change it later on
for i in range(0, int(no_of_particles // (no_of_clusters ** 0.5))):
temp.append(random.randrange(0, length))
if (flx % 2 != 0):
temp = sorted(temp)
else:
temp = sorted(temp, reverse=True)
for x_cordinate in temp:
id += 1
timex+=time_interval
particles.append([id, [x_cordinate, y_cordinate], [battery], timex])
breadth_start = breadth_start - breadth_incx
print(particles)
self.sergation_of_nodes_in_cluster(length, breadth, nodes, cluster_list, particles)
def default_deployment(self,length,breadth,nodes,cluster_list):
pass
def visualization(self,length,breadth,cluster_list,particles):
G=nx.Graph()
for each in particles:
G.add_node(each[0],pos=(each[1][0],each[1][1]))
#pos = nx.get_node_attributes(G, 'pos')
pos = {}
for each in particles:
pos[each[0]] = (each[1][0], each[1][1])
#nx.draw_networkx_labels(G, pos)
nx.draw_networkx(G,pos=pos)
plt.title("CLUSTERING NETWORK'S")
plt.xlabel('X-AXIS')
plt.ylabel('Y-AXIS')
# Limits for the Y and Yaxis
incx=(len(cluster_list)**0.5)
#plt.ylim(0, breadth)
#plt.xlim(0, length)
plt.xticks(np.arange(0, length+1, length//incx))
plt.yticks(np.arange(0, breadth+1, breadth//incx))
#plt.plot([lambda x: x[1][0] for x in particles],[lambda y: y[1][1] for y in particles[1][1]],'ro')
plt.grid()
plt.savefig("WSN_labels.png")
plt.show()
for each in cluster_list:
for i in range(0, len(each[1])-1):
for j in range(i + 1, len((each[1]))):
G.add_edge(each[1][i][0], each[1][j][0])
#nx.draw(G,pos, with_labels=True)
nx.draw_networkx(G, pos=pos,with_labels=True)
plt.xticks(np.arange(0, length + 1, length // incx))
plt.yticks(np.arange(0, breadth + 1, breadth // incx))
plt.grid()
plt.savefig("WSN_CLUSTER.png")
plt.show()
obj1=wireless_sensor_networks()

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