I am trying to build my own Bubble sheet OMR engine with Python 3.8 and OpenCV.
Despite several days of debugging, I can't beat that error which occurs when I am cropping the bubbles individualy:
Traceback (most recent call last):
File "C:\Users\hsolatges\AppData\Local\Programs\Python\Python38\lib\site-packages\numpy\lib\shape_base.py", line 867, in split
len(indices_or_sections)
TypeError: object of type 'int' has no len()
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "c:/autoQuiz/omr.py", line 80, in <module>
anwsers_array = tb.parse_anwsers(anwsers_field, MCQ.get('QUESTIONS'), MCQ.get('CHOICES'))
bubbles = get_bubbles(padded_img, questions, choices)
File "c:\autoQuiz\toolbox.py", line 81, in get_bubbles
rows = np.vsplit(img, questions)
File "<__array_function__ internals>", line 5, in vsplit
File "C:\Users\hsolatges\AppData\Local\Programs\Python\Python38\lib\site-packages\numpy\lib\shape_base.py", line 991, in vsplit
return split(ary, indices_or_sections, 0)
File "<__array_function__ internals>", line 5, in split
File "C:\Users\hsolatges\AppData\Local\Programs\Python\Python38\lib\site-packages\numpy\lib\shape_base.py", line 872, in split
raise ValueError(
ValueError: array split does not result in an equal division
As the size of the bubbles region is arbitrary, I tried to edge-pad it so that its width and height are both a multiple of the number of questions / number of choices (A B C D E). Unfortunately, it doesn't work properly. Except for tests/omr-1.jpg, the others fail.
Here an excerpt of the code:
def to_next_multiple(n,b):
return int(ceil(n/b) * b)
def pad_image(img, questions, choices):
w, h = img.shape[:2]
w_final, h_final, = to_next_multiple(w, choices), to_next_multiple(h, questions)
w_padding, h_padding = max(0, w-w_final), max(0, h-h_final)
padded_img = np.pad(img, ((0, h_padding), (0, w_padding)), 'edge')
return padded_img
def get_bubbles(img, questions, choices):
bubbles = []
rows = np.vsplit(img, questions)
for row in rows:
cells = np.hsplit(row, choices)
bubbles.append(cells)
return bubbles
def parse_anwsers(img, questions, choices):
# Otsu's thresholding after Gaussian filtering
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
blurred = cv.GaussianBlur(gray, (5,5), 0)
retValue, thresh = cv.threshold(blurred, 0, 255, cv.THRESH_BINARY+cv.THRESH_OTSU)
padded_img = pad_image(thresh, questions, choices)
w, h = padded_img.shape[:2]
# Debugging
print(f'width: {w}, w_division: {w/choices}')
print(f'height: {h}, h_division: {h/questions}')
bubbles = get_bubbles(padded_img, questions, choices)
answers_array = bubbles
return answers_array
The repo can be found here: https://github.com/hsolatges/autoQuiz
How can I consistently get a ready to be np.vsplit/np.hsplit image ?
So the issues came from the following lines:
w_padding, h_padding = max(0, w-w_final), max(0, h-h_final)
padded_img = np.pad(img, ((0, h_padding), (0, w_padding)), 'edge')
Becomes:
w_padding, h_padding = w_final-w, h_final-h
padded_img = np.pad(img, ((0, w_padding), (0, h_padding)), 'edge')
I was doing crappy math and missfigured the numpy axis system. I thought padding on axis #0 was padding more rows and padding on axis #1 was padding more column; though it was the other way.
Related
I am a beginner with coding.I am try to call the function fitData on another script (main code).
I called the function fitData with this sintax, at the end of the script:
# If the experiments stops before a default response is inserted
stairs.addResponse(0)
stairs.saveAsExcel(outputfile)
df.to_excel(outputfile + '_trials_summary.xlsx')
win.close()
raise
#analyzeStaircases(stairs, stairInfo['AverageReversals'])
fitData(stairs, 75)
################################
# The experiment starts here #
###############################
if __name__ == "__main__":
startExperiment()
fitData code
from psychopy import data
import pylab
from numpy import average,std
def fitData(stairs,percent):
allIntensities, allResponses = [],[]
for s in stairs.staircases:
allIntensities.append( s.intensities )
allResponses.append( s.data )
for s in stairs.staircases:
print ("Mean for condition"),s.condition['label'],"=",average(s.reversalIntensities),"std=",std(s.reversalIntensities)
#plot each condition
pylab.subplot(221)
#for stairNumber, thisStair in enumerate(allIntensities):
pylab.plot(allIntensities[0], 'o-', label=stairs.staircases[0].condition['label'] )
pylab.xlabel('Trials')
pylab.ylabel('Speed [cm/s]')
pylab.legend()
# Get combined data
combinedInten, combinedResp, combinedN = data.functionFromStaircase(allIntensities, allResponses, 10)
# Fit curve - in this case using a Weibull function
fit = data.FitWeibull('weibullTAFC',combinedInten, combinedResp, guess=None)
#fit = data.FitCumNormal(combinedInten,combinedResp)
intensitiesDomainInterp = pylab.arange(min(allIntensities[0]), max(allIntensities[0]), 0.01)
smoothResponses = fit.eval(intensitiesDomainInterp)
thresh = fit.inverse(percent)
#Plot fitted curve
pylab.subplot(222)
pylab.axis(xmin=min(allIntensities[0]),xmax=max(allIntensities[0]))
pylab.xlabel('Speed [cm/s]')
pylab.ylabel('Probability')
pylab.plot(intensitiesDomainInterp, smoothResponses, '-')
pylab.plot([thresh, thresh],[0,percent],'--')
pylab.plot([0, thresh],[percent,percent],'--')
pylab.title('Threshold at ' + str(percent) + '= %0.3f' % (thresh) )
# Plot points
pylab.plot(combinedInten, combinedResp, 'o')
pylab.ylim([0,1])
# SECOND CONDITION, the plots are in a second row, under
pylab.subplot(223)
#for stairNumber, thisStair in enumerate(allIntensities):
pylab.plot(allIntensities[1], 'o-', label=stairs.staircases[1].condition['label'] )
pylab.xlabel('Trials')
pylab.ylabel('Speed [cm/s]')
pylab.legend()
# Get combined data
combinedInten, combinedResp, combinedN = data.functionFromStaircase(allIntensities[1], allResponses[1], 10)
#fit curve - in this case using a Weibull function
#fit = data.FitFunction('weibullTAFC',combinedInten, combinedResp, guess=None)
fit = data.FitCumNormal(combinedInten,combinedResp)
intensitiesDomainInterp = pylab.arange(min(allIntensities[1]), max(allIntensities[1]), 0.01)
smoothResponses = fit.eval(intensitiesDomainInterp)
thresh = fit.inverse(percent)
#print "Threshold at " + str(percent) +"% with Cumulative Normal= ",thresh
#Plot fitted curve
pylab.subplot(224)
pylab.axis(xmin=min(allIntensities[1]),xmax=max(allIntensities[1]))
pylab.xlabel('Speed [cm/s]')
pylab.ylabel('Probability')
pylab.plot(intensitiesDomainInterp, smoothResponses, '-')
pylab.plot([thresh, thresh],[0,percent],'--')
pylab.plot([0, thresh],[percent,percent],'--')
pylab.title('Threshold at ' + str(percent) + '= %0.3f' % (thresh) )
# Plot points
pylab.plot(combinedInten, combinedResp, 'o')
pylab.ylim([0,1])
pylab.show()
When I call the function fitData on the main code I get this output errore:
Traceback (most recent call last):
File "C:\Users\OneDrive\Desktop\py2convers\psychoflicker-master\src\trackingExperiment2Staircase - py3 - FITDATA.py", line 627, in <module>
startExperiment()
File "C:\Users\OneDrive\Desktop\py2convers\psychoflicker-master\src\trackingExperiment2Staircase - py3 - FITDATA.py", line 621, in startExperiment
fitData(stairs, 75)
File "C:\Users\OneDrive\Desktop\py2convers\psychoflicker-master\src\common\fitData.py", line 39, in fitData
fit = data.FitWeibull('weibullTAFC',combinedInten, combinedResp, guess=None, display=1, expectedMin=0.5, optimize_kws=None)
File "C:\Users\OneDrive\Desktop\py2convers\psychoflicker-master\src\venv\lib\site-packages\psychopy\data\fit.py", line 36, in __init__
self._doFit()
File "C:\Users\OneDrive\Desktop\py2convers\psychoflicker-master\src\venv\lib\site-packages\psychopy\data\fit.py", line 55, in _doFit
self.params, self.covar = optimize.curve_fit(
File "C:\Users\OneDrive\Desktop\py2convers\psychoflicker-master\src\venv\lib\site-packages\scipy\optimize\_minpack_py.py", line 743, in curve_fit
xdata = np.asarray_chkfinite(xdata, float)
File "C:\Users\OneDrive\Desktop\py2convers\psychoflicker-master\src\venv\lib\site-packages\numpy\lib\function_base.py", line 601, in asarray_chkfinite
a = asarray(a, dtype=dtype, order=order)
ValueError: could not convert string to float: 'weibullTAFC'
Could you give me some suggestion on how can I fix this error?
Also I am not sure that the arguments of the function fitData on the main script are correct.
My code isn't able to read faces in images from the folder. It is showing Value error. Here is my code:
# Definition for extracting faces:
def extract_faces(filename, required_size=(224, 224)):
pixels = pyplot.imread(filename)
detector = MTCNN()
results = detector.detect_faces(pixels)
x1, y1, width, height = results[0]['box']
x2, y2 = x1 + width, y1 + height
face = pixels[y1:y2, x1:x2]
image = Image.fromarray(face)
image = image.resize(required_size)
face_array = asarray(image)
return face_array
# Definition for the face embedding:
def get_embeddings(filenames):
faces = [extract_faces(f) for f in filenames]
samples = asarray(faces, 'float32')
samples = preprocess_input(samples, version=2)
model = VGGFace(model = 'resnet50', include_top = False, input_shape = (224, 224, 3), pooling = 'avg')
yhat = model.predict(samples)
return yhat
# For getting the face embeddings:
embeddings = get_embeddings(faces)
The error is:
File "c:/Users/Adarsh Narayanan/Realtime_FR_With_VGGFace2/retrainfaces.py", line 69, in <module>
embeddings = get_embeddings(faces)
File "c:/Users/Adarsh Narayanan/Realtime_FR_With_VGGFace2/retrainfaces.py", line 29, in get_embeddings
faces = [extract_faces(f) for f in filenames]
File "c:/Users/Adarsh Narayanan/Realtime_FR_With_VGGFace2/retrainfaces.py", line 29, in <listcomp>
faces = [extract_faces(f) for f in filenames]
File "c:/Users/Adarsh Narayanan/Realtime_FR_With_VGGFace2/retrainfaces.py", line 22, in extract_faces
image = Image.fromarray(face)
File "C:\Users\Adarsh Narayanan\Anaconda3\lib\site-packages\PIL\Image.py", line 2666, in fromarray
return frombuffer(mode, size, obj, "raw", rawmode, 0, 1)
File "C:\Users\Adarsh Narayanan\Anaconda3\lib\site-packages\PIL\Image.py", line 2609, in frombuffer
return frombytes(mode, size, data, decoder_name, args)
File "C:\Users\Adarsh Narayanan\Anaconda3\lib\site-packages\PIL\Image.py", line 2542, in frombytes
im.frombytes(data, decoder_name, args)
File "C:\Users\Adarsh Narayanan\Anaconda3\lib\site-packages\PIL\Image.py", line 825, in frombytes
d.setimage(self.im)
ValueError: tile cannot extend outside image
Does anybody know what I should do?
What if face detector results in 0 face(s) detected, you are not check for it.
You can check for number of faces detected should be >=1. Another point, bilinear interpolation resize for small detected face compared to 244x244, would hamper the CNN results, you need another check here.
trying to recreate that by using valuetrackers
Here is my code and the err is also inside that pastebin
Thank you for all the help since I cannot yet create an animation I thought about using this to make by
linking the dots and lines both to some lists of valuetrackers and then finally storing the updation of these value trackers in an animation list and finally playing them was my goal
class Network3(Scene):
def construct(self):
screen_grid = ScreenGrid()
self.add(screen_grid)
#function to just random the x and y coordinates
def randomize_xy():
for i in range(0,no_of_dots):
x_coord[i]=random.randint(-7,+7)
y_coord[i]=random.randint(-4,+4)
print(x_coord)
print(y_coord)
no_of_dots=20
#make some dots
dots=[]
for i in range(0,no_of_dots):
dots.append(Dot())
#make initial list of coordinates
x_coord=[]
y_coord=[]
for i in range(0,no_of_dots):
x_coord.append(random.randint(-7,7))
y_coord.append(random.randint(-4,4))
# #make sure all the lengths are ok
# print(f"length of dots lenght={len(dots)} of x_coord={len(x_coord)}") error of int base 10 is coming from here
print("length of dots=",end="")
print(str(len(dots))) #print(len(dots)) still causes an error !!!
#add all dots at one point
self.add(*dots)
#make anim list to move everything to their position from origin
animlist=[]
for i in range(0,no_of_dots):
animlist.extend([dots[i].move_to,[x_coord[i],y_coord[i],0]])
#play
self.play(*animlist)
#make a list of value trackers
x_trackers=[]
y_trackers=[]
for i in range(0,no_of_dots):
x_tracker=ValueTracker(x_coord[i])
y_tracker=ValueTracker(y_coord[i])
x_trackers.append(x_tracker)
y_trackers.append(y_tracker)
#making lines
lines=[]
for i in range(0,no_of_dots-1):
t1=[x_coord[i],y_coord[i],0]
t2=[x_coord[i+1],y_coord[i+1],0]
line=Line(t1,t2)
lines.append(line)
def update_func1(obj,i):
temp1=np.array([x_trackers[i],y_trackers[i],0])
temp2=np.array([x_trackers[i+1],y_trackers[i+1],0])
line=Line(start=temp1,end=temp2)
obj.become(line)
#making a link between each line and value tracker
for i in range(0,no_of_dots-1):
lines[i].add_updater(lambda m:update_func1(m,i))
#adding again
self.add(*lines)
#making a link between each dot and value tracker
for i in range(0,no_of_dots):
dots[i].add_updater(lambda m:m.move_to([x_trackers[i],y_trackers[i],0]))
#now somehow have to change all the value tracker at once
animlist2=[]
for i in range(0,no_of_dots):
animlist2.extend([x_trackers[i].set_value,random.randint(-7,+7)])
animlist2.extend([y_trackers[i].set_value,random.randint(-4,+4)])
#now play
self.play(*animlist2)
#end
self.wait(3)
Current error I am getting is:
Traceback (most recent call last):
File "C:\manim\manimlib\extract_scene.py", line 155, in main
scene = SceneClass(**scene_kwargs)
File "C:\manim\manimlib\scene\scene.py", line 53, in __init__
self.construct()
File "network_graphic.py", line 584, in construct
lines[i].add_updater(lambda m:update_func1(m,i))
File "C:\manim\manimlib\mobject\mobject.py", line 192, in add_updater
self.update(0)
File "C:\manim\manimlib\mobject\mobject.py", line 159, in update
updater(self)
File "network_graphic.py", line 584, in <lambda>
lines[i].add_updater(lambda m:update_func1(m,i))
File "network_graphic.py", line 578, in update_func1
line=Line(start=temp1,end=temp2)
File "C:\manim\manimlib\mobject\geometry.py", line 431, in __init__
self.set_start_and_end_attrs(start, end)
File "C:\manim\manimlib\mobject\geometry.py", line 471, in set_start_and_end_attrs
vect = normalize(rough_end - rough_start)
TypeError: unsupported operand type(s) for -: 'ValueTracker' and 'ValueTracker'
I think your best option is to use the functions with "dt", then watch my video if you have any doubts. This is a basic example Grant made in one of his very old videos, but I think you can use it for your idea.
class RandomMove(Scene):
CONFIG = {
"amplitude": 0.4,
"jiggles_per_second": 1,
}
def construct(self):
points = VGroup(*[
Dot(radius=0.2) for _ in range(9)
])
points.arrange_in_grid(buff=1)
for submob in points:
submob.jiggling_direction = rotate_vector(
RIGHT, np.random.random() * TAU *1.5,
)
submob.jiggling_phase = np.random.random() * TAU *1.5
def update_mob(mob, dt):
for submob in mob:
submob.jiggling_phase += dt * self.jiggles_per_second * TAU
submob.shift(
self.amplitude *
submob.jiggling_direction *
np.sin(submob.jiggling_phase) * dt
)
points.add_updater(update_mob)
self.add(points)
self.wait(10)
Result here
I have this code and it runs two times fine, while on third call I get an error, as if I would have passed Timestamp. I only ever pass Tuple or None.
from pprint import pprint
from gpiozero import RGBLED
def signal(pri, newcolor):
signal.priority[pri] = newcolor
pprint(signal.priority)
try: signal.led.color = next(color for color in signal.priority if color is not None)
except StopIteration: signal.led.color = (0,0,0)
signal.led = RGBLED(red=11, green=9, blue=10)
signal.priority = 2*[None]
Output is following
[None, (0, 1, 0)]
[None, (0, 0, 1)]
[None, (1, 1, 0)]
Traceback (most recent call last):
File "/home/pi/zrcrasp.py", line 137, in <module>
signal(1, (1,1,0))
File "/home/pi/zrcrasp.py", line 10, in signal
try: signal.led.color = next(color for color in signal.priority if color is not None)
TypeError: 'Timestamp' object is not callable
Background
Function is used by various part of program to signal any kind of error, but if high priority short red blink ends, the lower priority green should continue. If there is no lower priority - None , then led will be turned off (this is the except statement for)
Lowest index is the highest priority.
I am attempting to add image distortion to my ConvNet model and am getting a really odd error. My data is in TFRecords format and I am using the color_distorter() function from the CFIAR10 code. Below is some dummy code I threw together to see that everything was doing what I expected it to do. When I view the images after they are distorted there is no problem. The problem appears to arise after flattening the tensor or after it is run. For some reason, it will execute once, but the second time it throws an error. Below is my code and the error it returns. My current suspicion is that it might be the tf.map_fn() but I don't know.
def color_distorer(image, thread_id=0, scope=None):
with tf.op_scope([image], scope, 'distort_color'):
color_ordering = thread_id % 2
if color_ordering == 0:
image = tf.image.random_brightness(image, max_delta=32. / 255.)
image = tf.image.random_saturation(image, lower=0.5, upper=1.5)
image = tf.image.random_hue(image, max_delta=0.2)
image = tf.image.random_contrast(image, lower=0.5, upper=1.5)
elif color_ordering == 1:
image = tf.image.random_brightness(image, max_delta=32. / 255.)
image = tf.image.random_contrast(image, lower=0.5, upper=1.5)
image = tf.image.random_saturation(image, lower=0.5, upper=1.5)
image = tf.image.random_hue(image, max_delta=0.2)
# The random_* ops do not necessarily clamp.
image = tf.clip_by_value(image, 0.0, 1.0)
return image
X_test_batch, y_test_batch = inputs(FLAGS.train_dir,
FLAGS.test_file,
FLAGS.batch_size,
FLAGS.n_epochs,
FLAGS.n_classes,
one_hot_labels=True,
imshape=160*160*3)
with tf.Session() as sess:
init_op = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer())
sess.run(init_op)
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
# X = sess.run([X_test_batch])
for i in range(5): #epochs
image = tf.reshape(X_test_batch, [-1, 160, 160, 3])
result = tf.map_fn(lambda img: color_distorer(img), image)
X, y = sess.run([result, y_test_batch]) #to see what the distortion did
for i in range(50): #all the images look distorted..
if i%25 ==0:
plt.title(y[i])
plt.imshow(X[i])
plt.show()
print('******************') #This runs once... then breaks. Why?
result = tf.reshape(result, [-1, 76800])
dX, dy = sess.run([result, y_test_batch])
print(dX)
Error:
******************
[[ 1. 1. 1. ..., 1. 1. 1.]
[ 1. 1. 1. ..., 1. 1. 1.]
[ 1. 1. 1. ..., 1. 1. 1.]
...,
[ 1. 1. 1. ..., 1. 1. 1.]
[ 1. 1. 1. ..., 1. 1. 1.]
[ 1. 1. 1. ..., 1. 1. 1.]]
WARNING:tensorflow:tf.op_scope(values, name, default_name) is deprecated, use tf.name_scope(name, default_name, values)
Traceback (most recent call last):
File "/home/mcamp/anaconda3/lib/python3.5/site-packages/tensorflow/python/client/session.py", line 1021, in _do_call
return fn(*args)
File "/home/mcamp/anaconda3/lib/python3.5/site-packages/tensorflow/python/client/session.py", line 1003, in _run_fn
status, run_metadata)
File "/home/mcamp/anaconda3/lib/python3.5/contextlib.py", line 66, in __exit__
next(self.gen)
File "/home/mcamp/anaconda3/lib/python3.5/site-packages/tensorflow/python/framework/errors_impl.py", line 469, in raise_exception_on_not_ok_status
pywrap_tensorflow.TF_GetCode(status))
tensorflow.python.framework.errors_impl.InvalidArgumentError: The tensor returned for map_1/TensorArrayPack_1/TensorArrayGatherV2:0 was not valid.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/media/mcamp/Local SSHD/Python Projects/Garage Door Project/FreshStart/ReadTFREcords.py", line 80, in <module>
dX, dy = sess.run([result, y_test_batch])
File "/home/mcamp/anaconda3/lib/python3.5/site-packages/tensorflow/python/client/session.py", line 766, in run
run_metadata_ptr)
File "/home/mcamp/anaconda3/lib/python3.5/site-packages/tensorflow/python/client/session.py", line 964, in _run
feed_dict_string, options, run_metadata)
File "/home/mcamp/anaconda3/lib/python3.5/site-packages/tensorflow/python/client/session.py", line 1014, in _do_run
target_list, options, run_metadata)
File "/home/mcamp/anaconda3/lib/python3.5/site-packages/tensorflow/python/client/session.py", line 1034, in _do_call
raise type(e)(node_def, op, message)
tensorflow.python.framework.errors_impl.InvalidArgumentError: The tensor returned for map_1/TensorArrayPack_1/TensorArrayGatherV2:0 was not valid.
Ok so what I believe was happening was I resized X_test_batch back to the shape of an image. I then ran my distortion on it and called it result. It was this that I ran and viewed. After viewing, I resized it for the model back to being a flat image. During this, I change the names of some things calling it first image and then result. If the code just red from top to bottom I think it would have been fine but Tensorflow has the graph that it works from and so it was expecting result to be a 3d tensor when it got to the second iteration, but it was really a flat tensor that was trying to be put through tf.map_fn. tf.map_fn is something that resides on the graph and does not get executed until sess.run() and so this would be the cause of the error that I was seeing. I hope this makes sense and helps someone else down the road.
with tf.name_scope('TestingData'):
X_test_batch, y_test_batch = inputs(FLAGS.train_dir,
FLAGS.test_file,
FLAGS.batch_size,
FLAGS.n_epochs,
FLAGS.n_classes,
one_hot_labels=True,
imshape=160*160*3)
image = tf.reshape(X_test_batch, [-1, 160, 160, 3])
image = tf.map_fn(lambda img: color_distorer(img), image)
with tf.Session() as sess:
init_op = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer())
sess.run(init_op)
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
# X = sess.run([X_test_batch])
for i in range(5):
# dX, dy = sess.run([result, y_test_batch])
print('******************')
image = tf.reshape(image, [-1, 76800])
dX, dy = sess.run([image, y_test_batch])
distorted = np.reshape(dX, (-1, 160, 160, 3))
print(dX.shape)
print(distorted.shape)
for i in range(50):
if i%25 ==0:
print(distorted[i], dy[i])
plt.title(dy[i])
plt.imshow(distorted[i])
plt.show()
print(dX.shape)