I am trying to read some characters that come out on the screen, but none of my attempts is successful. Example image here
And here is my code:
import pytesseract as tess
tess.pytesseract.tesseract_cmd = r'C:\Users\myuser\AppData\Local\Tesseract-OCR\tesseract.exe'
from PIL import Image
img = Image.open(r'E:\images\numbers.PNG')
text = tess.image_to_string(img)
print(text)
The "garbage" output that displays is:
C NCES IC DICIIED)
CK STOO TEED
#©O®D#O#O#O#O®
I suppose this is happening because of the color of the numbers, and the different background image they could appear on.
Unfortunately I do not know how to proceed further and how to get it working.
Can you please help? Your assistance is much appreciated!
Thanks!
I don't have Tesseract installed right now but try with the result of this code:
import cv2
img = cv2.imread('img.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 3, 6)
cv2.imshow('threshold', thresh)
cv2.waitKey(0)
You can fine tune it to achieve your result.
Related
Please check the following image:
Image
I am using the following code to extract text from the image.
img = cv2.imread("img.png")
txt = pytesseract.image_to_string(img)
But the result is showing different than the original one:
It is showing the following result:
+BuFl
But it should be:
+Bu#L
I don't know what the problem is. I am pretty new in Pytesseract.
Is there anyone who can help me to sort out the problem?
Thank you very much.
One way of solving is applying otsu-thresholding
Otsu's method automatically finds the threshold value unlike global thresholding.
The result of applying Otsu's threshold will be:
import cv2
import pytesseract
img = cv2.imread("Tqom8.png") # Load the image
img = cv2.resize(img, (0, 0), fx=0.5, fy=0.5)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Convert to gray
thr = cv2.threshold(gray, 0, 128, cv2.THRESH_OTSU)[1]
txt = pytesseract.image_to_string(gray, config='--psm 6')
print(pytesseract.__version__)
print(txt)
Result:
0.3.8
+Bu#L
Also make sure to read the Improving the quality of the output
I want to extract a particular text from an image, and I already did some filtering in image but still I'm not getting the exact text.Also is there any way to get a specific text alone from the image?
Code for filtering the image and converting to text
import cv2
import pytesseract
image = cv2.imread('original.png', 0)
thresh = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
img = cv2.adaptiveThreshold(thresh, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
cv2.imwrite('filtered.png', img)
data = pytesseract.image_to_data(img)
print(data)
cv2.imshow('thresh', img)
cv2.waitKey()
You can try easyOCR instead of pytesseract
first install by pip install easyocr
import cv2
import easyocr
image = cv2.imread('original.jpg', 0)
reader = easyocr.Reader(['en'])
result = reader.readtext(image)
#You can use regular expression
interested_string = 'Patrol Rewards'
line = [l[1] for l in result if 'Patrol Rewards' in l[1]]
print(line)
You will get list containing interested string like
['Patrol Rewards: Courage Horn X 1']
This will give correct output but it is bit slow compared to pytesseract on CPU but if you have GPU configured then it is faster. But it gives quite good OCR results.
GOAL: I need a cleaned image to use pytesseract and get the text from it.
I pass this image into gray.
I use cv2.adaptiveThreshold to deal with the reflection problematic. But it doesn't work well.
My text became less readable and pytesseract can't read it. I don't know how to upgrade my image.
import cv2
path = "path/to/image.jpg"
rgb_img = cv2.imread(path)
gray_img = cv2.imread(path, 0)
tresholded_img = cv2.adaptiveThreshold(gray_img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 19, 1)
cv2.imshow('rgb', rgb_img)
cv2.imshow('gray', gray_img)
cv2.imshow('tresholded', tresholded_img)
cv2.waitKey(0)
EDIT:
cv2.ADAPTIVE_THRESH_GAUSSIAN_C didn't gave me better result.
Here is a sample.
My boss just gave me 9000 images showing a multi-meter output, and he wants me to read them all and write the voltage output on a text file for Monday morning!
There's no way I can do it manually , so I desperately need your help to automate the process.
I have already done a bit of coding. The multimeter screen position is fixed over the 9000 images, so I just cropped the pictures and zoomed on the screen.
Here's my code so far :
import pytesseract as tess
tess.pytesseract.tesseract_cmd = r'D:\Programs\Tesseract-OCR\tesseract.exe'
from PIL import Image
from matplotlib import pyplot as plt
import cv2
import numpy as np
img = cv2.imread('test1.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (7,7), 0)
ret, BW = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY)
plt.imshow(BW)
plt.show()
print(tess.image_to_string(img,config='digits --oem 3'))
My code outputs this kind of picture:
For this picture, tesseract reads the following number: 138
I have two problems here: the first one is I don't know how to properly pre-process my pictures for tesseract to easily read them.
Second problem: I don't know how to process the decimal dot. In fact, on some picture there is no decimal dot, so I need to find a way to make tesseract read it.
Do you think I'll need to manually "train" tesseract, so that I reach a near 100% accuracy?
Thank you sooo much for your help, I'll continue my research meanwhile on the OpenCv functions!
here's one of the originals:
UPDATED VERSION:
Ok so I updated a bit my code so far :
# Loading the picture
img = cv2.imread('test1.JPG')
# Crop - Rotate - Scale up
x = 1400
y = 1375
h = 325
w = 800
img = img[y:y+h, x:x+w]
image = cv2.rotate(img, cv2.ROTATE_180)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 128, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,10))
close = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=1)
cv2.imshow('close', close)
x = 0
y = 0
h = 300
w = 750
img = close[y:y+h, x:x+w]
plt.imshow(img)
plt.show()
print(tess.image_to_string(img,config='--psm 7 -c tessedit_char_whitelist=0123456789 --oem 0'))
I get a finer image for tesseract to analyse. But still no luck with the decimal dot :/.
you need around 3-4 hours to type them manually, just spend 1 extrahour to write a wrapper that opens the image and let's you input a value.
when automating, my biggest concern would be if all the measurements have the same unit of kilo-ohm, you should really include that check in your open-cv code.
good luck!
I am currently working on a simple task where I have to read characters from simple images. Used tesseract in python to write following code which works on all simple and complex images having English text but fails on a particular image, can anyone tell me why the following python code can not read characters from the following image , as you can see with 6 black sections having 6 characters in each box, character colour is white.
from PIL import Image
import pytesseract
import argparse
import cv2
import os
ap = argparse.ArgumentParser()
ap.add_argument("-i","--image",required=True,help="path to input image to be OCR'd")
ap.add_argument("-p","-- preprocess",type=str,default="thresh",help="type of preprocessing to be done")
args=vars(ap.parse_args())
image = cv2.imread(args["image"])
gray2 = cv2.BackgroundSubtractor()
gray2 = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
gray2 = cv2.threshold(gray2, 100, 255, cv2.THRESH_BINARY_INV)[1]
rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))
sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
if args["preprocess"] == "thresh":
gray2 = cv2.threshold(gray2, 2, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
elif args["preprocess"] == "blur":
gray2 = cv2.medianBlur(gray2,3)
filename = "{}.png".format(os.getpid())
cv2.imwrite(filename,gray2)
text = pytesseract.image_to_string(Image.open(filename))
print(text)
If this image is used, it gives perfect result
0123456789
ABCDEFGHIJKL
MNOPQRSTUV
WXYZ
When I am trying to use the following image ,
Processed Image which does not give result
the code completely ignores all characters in the image. The only difference is the first image does not have boxes like the second image where each black box contains 6 characters
Can someone please help and tell me what am I missing why this code fails for the second image, Thanks.
Here are the original images :
Image1
Image2