Reputation: 1036
I am trying to use pytesseract to read images like this:
I thought that should be rather easy, but I can't get it to work so far. I tried different sorts of preprocessing but it doesn't work:
image = cv2.imread('number.png')
custom_config = r'-c tessedit_char_whitelist=0123456789 --psm 10'
text_i = pytesseract.image_to_string(img, config=custom_config)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
text_g = pytesseract.image_to_string(img, config=custom_config)
thresh = cv2.threshold(image, 50, 255, cv2.THRESH_BINARY)[1]
text_t = pytesseract.image_to_string(img, config=custom_config)
plt.axis('off')
plt.imshow(image)
plt.show()
print("Recognized number: ", text_i)
plt.axis('off')
plt.imshow(gray)
plt.show()
print("Recognized number: ", text_g)
plt.axis('off')
plt.imshow(thresh)
plt.show()
print("Recognized number: ", text_t)
In all cases, the returned string is empty. Does anyone have an idea, what to do?
Upvotes: 1
Views: 661
Reputation: 1036
Using erode was the key to success. My script looks now as follows:
# Load image
img = cv2.imread('number.png')
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
plt.axis('off')
plt.imshow(img, cmap='gray')
plt.show()
# Set number pool
pool = [31138796, 31130796]
# Set time limit
time_limit = 3
# Set config for pytesseract
custom_config = r'-c tessedit_char_whitelist=0123456789 --psm 10'
while True:
start = time.time()
# Iterate over kernel sizes for erode
for k_erode in range(10, 1, -1):
# Iterate over thresholds
for thresh in range(20, 81, 10):
# Check if time limit is exceeded
if time.time() > start + time_limit:
print("Time limit exceeded. Make a better picture! ;)")
break
# Preprocess image
img_erode = cv2.erode(img, np.ones((k_erode, k_erode), dtype=np.uint8), 1)
img_out = cv2.threshold(img_erode, thresh, 255, cv2.THRESH_BINARY)[1]
number = pytesseract.image_to_string(img_out, config=custom_config)
if number == '\x0c':
continue
# Check if number is in pool
if int(number) in pool:
print("The number is:", str(number))
print("Is this your number? (y/n)")
time_curr1 = time.time()
answer = input()
time_curr2 = time.time()
time_limit += time_curr2 - time_curr1
if answer == "y":
plt.axis('off')
plt.imshow(img_out, cmap='gray')
plt.show()
break
else:
pool.remove(int(number))
continue
else:
continue
break
break
Upvotes: 2