OCR not Extracting any Text - python

I am trying to extract text from an image that looks like OCR should be able to easily extract but it just extracting nothing or garbage in some cases.
I have tried the following OpenCV techniques from other stackoverflow resources but nothing seems to help.
Image Resisizing
GrayScaling
Dilation and Erosion
adaptiveThreshold
If someone could help me how to extract text from the attached image using OpenCV that would be really helpful
My Code
import pytesseract
import cv2
import numpy as np
# Configuration
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
image_path = "C:/Users//opencv_test/images/"
ocr_path = "C:/Users//opencv_test/ocr/"
doc_file_name = "Image.jpeg"
ocr_file_name = doc_file_name[:-4] + "txt"
# To read image from disk, we use
# cv2.imread function, in below method,
img = cv2.imread(image_path + doc_file_name, 1)
# Creating GUI window to display an image on screen
# first Parameter is windows title (should be in string format)
# Second Parameter is image array
cv2.imshow("Actual Image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
def remove_noise(img):
filtered = cv2.adaptiveThreshold(img.astype(np.uint8), 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 199, 5)
cv2.imshow("Noise Free Image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
return filtered
def remove_noise_2(img):
img = cv2.resize(img, None, fx=.9, fy=.8, interpolation=cv2.INTER_CUBIC)
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
kernel = np.ones((1, 1), np.uint8)
img = cv2.dilate(img, kernel, iterations=1)
img = cv2.erode(img, kernel, iterations=1)
cv2.imshow("Pre-Processed Image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
return img
noise_free_img = remove_noise_2(img)
# Run Tesseract
f = open(ocr_path + ocr_file_name, 'w')
text = str((pytesseract.image_to_string(noise_free_img, config='--psm 3')))
text = text.replace('-\n', '')
f.write(text)

Related

Get text from image using tesseract and cv2 in python

I am trying to get text from image I have image something like this
All other text I have got but I am unable to get File return > button text from image. I have tried this.
import pytesseract
import cv2
from pytesseract import Output
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
filepath = 'Capture.png'
image = cv2.imread(filepath, 1)
# converting image to grayscale image
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
threshold_img = cv2.threshold(gray_image, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
# displays the image
# cv2.imshow('threshold image', threshold_img)
status = cv2.imwrite('many_1.png',threshold_img)
# Holds the output window until the user presses a key
# cv2.waitKey(0)
# Destroying windows present on the screen
# cv2.destroyAllWindows()
# setting parameters for tesseract
custom_config = r'--oem 3 --psm 6'
# now feeding image to tesseract
details = pytesseract.image_to_data(threshold_img, output_type=Output.DICT, config=custom_config, lang='eng')
boxes = len(details['level'])
for i in range(boxes):
if details['text'][i] != '':
# print(data['left'][i], data['top'][i], data['width'][i], data['height'][i], data['text'][i])
# print(details['text'][i])
if details['text'][i] == 'File':
print(details['left'][i], details['top'][i], details['width'][i], details['height'][i], details['text'][i])

Why does Tesseract not recognize the text on the licence plate while easyocr does?

I am working on automatic licence plate recognition. I could cropped the Plate from inital image. But, Tesseract does not recognize the text on this plate while easyocr does. What is the reason? Thanks in advance for the answers. I used the code extract the plate from a car and recognize.
import cv2 as cv
import pytesseract
import imutils
import numpy as np
import easyocr
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
img3 = cv.imread("4.png")
cv.imshow("Car", img3)
img3 = cv.cvtColor(img3, cv.COLOR_BGR2RGB)
gray = cv.cvtColor(img3, cv.COLOR_RGB2GRAY)
bfilter_img3 = cv.bilateralFilter(img3, 11, 17, 17)
edged_img3 = cv.Canny(bfilter_img3, 30, 200)
keypoints = cv.findContours(edged_img3.copy(), cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
contours = imutils.grab_contours(keypoints)
contours = sorted(contours, key=cv.contourArea, reverse=True)[:10]
location = None
for contour in contours:
approx = cv.approxPolyDP(contour, 10, True)
if len(approx) == 4:
location = approx
break
mask = np.zeros(gray.shape, np.uint8)
new_img = cv.drawContours(mask, [location], 0, 255, -1)
new_img = cv.bitwise_and(img3, img3, mask=mask)
print(location)
cv.imshow("Plate", new_img)
(x,y)=np.where(mask==255)
(x1,y1)=(np.min(x),np.min(y))
(x2,y2)=(np.max(x),np.max(y))
cropped_img=gray[x1:x2+1, y1:y2+1]
ret, cropped_img=cv.threshold(cropped_img,127,255,cv.THRESH_BINARY)
cv.imshow("Plate3", cropped_img)
cropped_img = cv.resize(cropped_img, None, fx=2/3, fy=2/3, interpolation=cv.INTER_AREA)
#"cropped_img= the plate image in the question"***********
text = pytesseract.image_to_string(cropped_img)
print("Text by tesseract: ",text)
""""
reader=easyocr.Reader(['en'])
text2=reader.readtext(cropped_img)
print(text2)
"""
k = cv.waitKey(0)
I'm kind of curious why did you use bilateralFilter, Canny, findContours etc.? Did you see the result of each method?
Anyway, if you set the page-segmentation-mode to 6 which is:
Assume a single uniform block of text.
The result will be:
34 DUA34
Code:
import cv2
import pytesseract
# Load the image
img = cv2.imread("vHQ5q.jpg")
# Convert to the gray-scale
gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# OCR
print(pytesseract.image_to_string(gry, config="--psm 6"))
# Display
cv2.imshow("", gry)
cv2.waitKey(0)
You should know the Page segmentation method.
I've got the result using pytesseract-version-0.3.7.
You can try PaddleOCR, they publish a license plate recognition model and also provide a training guide for license plate recognition.
link: https://github.com/PaddlePaddle/PaddleOCR/blob/dygraph/applications/%E8%BD%BB%E9%87%8F%E7%BA%A7%E8%BD%A6%E7%89%8C%E8%AF%86%E5%88%AB.md

Read all images from folder and detect faces, crop and save to new folder

I'm trying to build a model in which it will read all the images from a given folder and detects the face, crop and save cropped face to a new folder!
Can anyone help me with code as I am receiving an error:
cv2.imshow(str(img) , img)
TypeError: mat is not a numpy array, neither a scalar
code:
import glob
import cv2
import sys
while 1 :
filename = input("Enter the file name in which images are present =")
for img in glob.glob(filename+'/*.*'):
#try :
var_img = cv2.imread(img)
cv2.imshow(str(img) , var_img)
def detect_face(img):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
face_cascade = cv2.CascadeClassifier('opencv-files/lbpcascade_frontalface.xml')
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5);
if (len(faces) == 0):
return None, None
(x, y, w, h) = faces[0]
return gray[y:y+w, x:x+h], faces[0]
cv2.imshow(str(img) , img)
cv2.waitKey(0)
cv2.destroyAllWindows()
It looks like you're trying to imshow the filename instead of the actual array. glob.glob returns a list of filenames so your img that you're trying to imshow is just a string. You need to read in the image first before you imshow it. You did that in this line: var_img = cv2.imread(img) so that means your array is var_img. But later you tried to imshow again using just img. You can only imshow var_img which is an array and not img which is a string.
try this
import glob
import cv2
import sys
import os
def detect_face(img):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
face_cascade = cv2.CascadeClassifier('opencvfiles/lbpcascade_frontalface.xmlv')
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5)
return faces
filename = input("Enter the file name in which images are present =")
for img in glob.glob(filename+'/*.*'):
var_img = cv2.imread(img)
face = detect_face(var_img)
print(face)
if (len(face) == 0):
continue
for(ex, ey, ew, eh) in face:
crop_image = var_img[ey:ey+eh, ex:ex+ew]
cv2.imshow("cropped", crop_image)
cv2.waitKey(0)
cv2.imwrite(os.path.join("outputs/",str(img)),crop_image)

Extracting text out of images

I am working on extracting text out of images.
Initially images are colored with text placed in white, On further processing the images, the text is shown in black and other pixels are white (with some noise), here is a sample:
Now when I try OCR using pytesseract (tesseract) on it, I still am not getting any text.
Is any solution possible to extract text from colored images?
from PIL import Image
import pytesseract
import argparse
import cv2
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True, help="Path to the image")
args = vars(ap.parse_args())
# load the image and convert it to grayscale
image = cv2.imread(args["image"])
cv2.imshow("Original", image)
# Apply an "average" blur to the image
blurred = cv2.blur(image, (3,3))
cv2.imshow("Blurred_image", blurred)
img = Image.fromarray(blurred)
text = pytesseract.image_to_string(img, lang='eng')
print (text)
cv2.waitKey(0)
As as result i get = "Stay: in an Overwoter Bungalow $3ยป"
What about using Contour and taking unnecessary blobs from it ? might work
Try this one -
import os
from PIL import Image
import cv2
import pytesseract
import ftfy
import uuid
filename = 'uTGi5.png'
image = cv2.imread(os.path.join(filename))
gray = cv2.threshold(image, 200, 255, cv2.THRESH_BINARY)[1]
gray = cv2.resize(gray, (0, 0), fx=3, fy=3)
gray = cv2.medianBlur(gray, 9)
filename = str(uuid.uuid4())+".jpg"
cv2.imwrite(os.path.join(
filename), gray)
config = ("-l eng --oem 3 --psm 11")
text = pytesseract.image_to_string(Image.open(os.path.join(
filename)), config=config)
text = ftfy.fix_text(text)
text = ftfy.fix_encoding(text)
text = text.replace('-\n', '')
print(text)

how to callpython function through button in web2py?

I am creating a web2py app; I want a button that can call a Python function available in controller folder in default.py and show the text result.
The function is:
src_path =
"/home/globalstat/web2py/applications/image_resize/controllers/"
def get_string(img_path):
# Read image with opencv
img_0 = cv2.imread(img_path)
# Convert to gray
img = cv2.cvtColor(img_0, cv2.COLOR_BGR2GRAY)
# thresh = 127
# im_bw = cv2.threshold(img, thresh, 255, cv2.THRESH_BINARY)[1]
# cv2.imwrite('bw_image.png', im_bw)
# Apply threshold to get image with only black and white
#img = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, v2.THRESH_BINARY, 11, 2)
# Write the image after apply opencv to do some ...
#cv2.imwrite(src_path + "thres.png", img)
# Apply dilation and erosion to remove some noise
kernel = np.ones((1, 1), np.uint8)
img = cv2.dilate(img, kernel, iterations=1)
img = cv2.erode(img, kernel, iterations=1)
cv2.imwrite(src_path + "removednoise.jpg", img)
# Apply threshold to get image with only gray scaled
img = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
cv2.imwrite(src_path + "thres.jpg", img)
# Recognize text with tesseract for python
#img_ref=Image.open(src_path + "removednoise.jpg")
img_ref=Image.open(src_path + "thres.jpg")
img_ref.save("test-600.png",doing=(600,600))
result = pytesseract.image_to_string(img_ref)
return result
and the code I'm using in view file for button is:
<Button type="button" name ="seeting_button" onclick =
'window.location="{{=URL('default', 'get_string',)}}";'>
How can I pass argument so it displays result?
Try changing
def get_string(img_path):
img_0 = cv2.imread(img_path)
Into
def get_string():
img_path = request.args[0]
img_0 = cv2.imread(img_path)
Any function with parameters inside a controller file is ignored by web2py. Arguments are passed through request.args

Categories