Using tesseract and opencv to extract text from image - tesseract

This is the image in the code above and nothing is outputed
I am using pytesseract and opencv to recognize the text on license plate, however alot of times when i run the code below no text is outputted for the images i use
import cv2
import imutils
import numpy as np
import pytesseract as tess
tess.pytesseract.tesseract_cmd =r'C:\Users\raul__000\AppData\Local\Tesseract-OCR\tesseract.exe'
# read image file
img = cv2.imread("Plate_images/plate14.jpg")
cv2.imshow("Image", img)
cv2.waitKey(0)
# RGB to Gray scale conversion
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow("1 - Grayscale Conversion", gray)
cv2.waitKey(0)
# Noise removal with iterative bilateral filter(removes noise while preserving edges)
gray = cv2.bilateralFilter(gray, 11, 17, 17)
cv2.imshow("2 - Bilateral Filter", gray)
cv2.waitKey(0)
# thresholding the grayscale image
gray = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
cv2.imshow("3 - Thresh Filter", gray)
cv2.waitKey(0)
# Dilation adds pixels to the boundaries of objects in an image
kernel = np.ones((5,5),np.uint8)
gray = cv2.dilate(gray, kernel, iterations = 1)
cv2.imshow("4 - dilation Filter", gray)
cv2.waitKey(0)
# use tesseract to convert image to string
text = tess.image_to_string(gray, lang="eng", config='--psm 6')
print(text)
This is the image in the code above and nothing is outputed

Your 4th step is removing all the text from the image
You should be able to see that when using cv2.imshow("4 - dilation Filter", gray)
If you remove the third step and run tesseract you should see output.

Related

How to apply erosion for only thick lines in images

Need to apply erosion only to the lines in my image which are more thicker using python
Here is my input image
I'm having a image which contains white lines with both thick and thin lines,my goal is to erode only the lines which are more thicker using python.i used normal erosion using opencv when applying this method thin lines are removing from the image.Erosion has to apply only on thick lines
import cv2
import numpy as np
img = cv2.imread('123.png',0)
kernel = np.ones((6,6),np.uint8)
erosion = cv2.erode(img,kernel,iterations = 1)
cv2.imshow("Result", erosion)
cv2.waitKey(0)
cv2.destroyAllWindows()
How can i achieve this any answers will be highly useful for me.Thanks in advance
Here is one way to do that in Python/OpenCV.
Read the input as grayscale
Threshold it
Apply morphology close to remove the thin lines and save as a mask image
Apply morphology dilate to the threshold image again to thin the lines
Use np.where() to combine the threshold and dilated images using the mask
Save the results
Input:
import cv2
import numpy as np
# read the input as grayscale
img = cv2.imread('black_lines.jpg', cv2.IMREAD_GRAYSCALE)
# threshold
thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
# apply morphology close to remove the thin lines and save as mask
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
mask = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
# apply morphology dilate to thin image as desired
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
dilate = cv2.morphologyEx(thresh, cv2.MORPH_DILATE, kernel)
# combine the thresh and dilate using mask
result = np.where(mask==0, dilate, thresh)
# save results
cv2.imwrite('black_lines_mask.jpg', mask)
cv2.imwrite('black_lines_dilate.jpg', dilate)
cv2.imwrite('black_lines_thinned.jpg', result)
# show results
cv2.imshow('mask', mask)
cv2.imshow('dilate', dilate)
cv2.imshow('thinned', result)
cv2.waitKey(0)
Mask Image:
Dilate Image:
Combined Image with thin lines:

Pillow - Adding transparency depending on grayscale values

Based on this post: Converting image grayscale pixel values to alpha values , how could I change an image transparency based on grayscale values with Pillow (6.2.2)?
I would like the brighter a pixel, the more transparent it is. Thus, pixels that are black or close to black would not be transparent.
I found the following script that works fine for white pixels but I don't know how to modify it on order to manage grayscale values. Maybe there is a better or faster way, I'm a real newbie in Python.
from PIL import Image
img = Image.open('Image.jpg')
img_out = img.convert("RGBA")
datas = img.getdata()
target_color = (255, 255, 255)
newData = list()
for item in datas:
newData.append((
item[0], item[1], item[2],
max(
abs(item[0] - target_color[0]),
abs(item[1] - target_color[1]),
abs(item[2] - target_color[2]),
)
))
img_out.putdata(newData)
img_out.save('ConvertedImage', 'PNG')
This is what I finally did:
from PIL import Image, ImageOps
img = Image.open('Image.jpg')
img = img.convert('RGBA') # RGBA = RGB + alpha
mask = ImageOps.invert(img.convert('L')) # 8-bit grey
img.putalpha(mask)
img.save('ConvertedImage', 'PNG')

Extract objects (fingerprint and signature) from an image using OpenCV and python

At my website I receive an image contains the user fingerprint and signature, I wan't to extract these two pieces of information.
for example:
Original Image
import os
import cv2
import numpy as np
def imshow(label, image):
cv2.imshow(label, image)
cv2.waitKey(0)
cv2.destroyAllWindows()
#read image
rgb_img = cv2.imread('path')
rgb_img = cv2.resize(rgb_img, (900, 600))
gray_img = cv2.cvtColor(rgb_img, cv2.COLOR_BGR2GRAY)
Gray Image
#canny edge detection
canny = cv2.Canny(gray_img, 50, 120)
canny edge image
# Morphology Closing
kernel = np.ones((7, 23), np.uint8)
closing = cv2.morphologyEx(canny, cv2.MORPH_CLOSE, kernel)
Morphology Closing
# Find contours
contours, hierarchy = cv2.findContours(closing.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
# Sort Contors by area and then remove the largest frame contour
n = len(contours) - 1
contours = sorted(contours, key=cv2.contourArea, reverse=False)[:n]
copy = rgb_img.copy()
# Iterate through contours and draw the convex hull
for c in contours:
if cv2.contourArea(c) < 750:
continue
hull = cv2.convexHull(c)
cv2.drawContours(copy, [hull], 0, (0, 255, 0), 2)
imshow('Convex Hull', copy)
Image divided to parts
Now my goals are:
Know which part is the signature and which is the fingerprint
Resolve the contours overlapping if exist
P.S: I'm not sure if the previous steps are final so please if you have better steps tell me.
These are some hard examples i may wanna deal with
You can use morphology for finger print and signature selecting.
By example:
import cv2
import numpy as np
img = cv2.imread('fhZCs.png')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
img=cv2.bitwise_not(img) #negate image
#color definition
blue_upper = np.array([130,255,255])
blue_lower = np.array([115,0,0])
#blue color mask (sort of thresholding, actually segmentation)
mask = cv2.inRange(hsv, blue_lower, blue_upper)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (20,20))
finger=cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
mask2=cv2.morphologyEx(finger, cv2.MORPH_DILATE, kernel)
signature=cv2.compare(mask2, mask, cv2.CMP_LT)
signature=cv2.morphologyEx(signature, cv2.MORPH_DILATE, kernel)
signature=cv2.bitwise_and(img, img, mask=signature)
signature=cv2.bitwise_not(signature)
finger=cv2.bitwise_and(img, img, mask=finger)
finger=cv2.bitwise_not(finger)
cv2.imwrite('finger.png', finger)
cv2.imwrite('signature.png',signature)

Is there any way to read Digital Number in the oven using pytesseract OCR?

I'm doing small project using tesseract OCR.
What I want to read is Digital Number which is generated by oven.
I pre-treat the image using openCV
but, tesseract can't read the image correct.
eg. 194 as 794..
let me know is there any way to deal with this.
thanks.
the Image which I want to read is shown below
import cv2
import numpy
img_color = cv2.imread('20190509_103247.jpg', cv2.IMREAD_COLOR)
dst = img_color.copy()
roi = img_color[1600:1800,600:1100]
dst[0:200,0:500]=roi
blur = cv2.GaussianBlur(roi,(5,5),0)
gray_dst = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY)
ret, thr = cv2.threshold(gray_dst, 70, 255,cv2.THRESH_BINARY)
canny = cv2.Canny(roi,100,255)
sobel = cv2.Sobel(gray_dst,cv2.CV_8U,1,0,3)
laplacian = cv2.Laplacian(gray_dst,cv2.CV_8U,ksize=3)
rev = cv2.bitwise_not(canny)
# blur = cv2.GaussianBlur(roi,(5,5),0)
# stencil = numpy.zeros(rev.shape).astype(rev.dtype)
# _, contours, _ = cv2.findContours(rev, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# color = [255, 255, 255]
# cv2.fillPoly(stencil, contours, color)
# result = cv2.bitwise_and(rev, stencil)
cv2.namedWindow('Show Image')
cv2.imshow('Show Image', rev)
cv2.waitKey(0)
cv2.imwrite('savedimage.jpg', rev)
cv2.destroyAllWindows()
You can create training data that will work for your font / glyphs to improve how the numeric display gets transformed to the correct digits.
References:
https://github.com/tesseract-ocr/tesseract/wiki/TrainingTesseract-4.00#creating-training-data
https://github.com/DevashishPrasad/LCD-OCR

Improving Low Contrast Image Segmentation

I have phase-contrast microscopy images that needs to be segmented. It seems very difficult to segment them due to the lack of contrast between the objects from the background (image 1). I used the function adapthisteq to increase the visibility of the cells (image 2). Is there any way I can improve the segmentation of the cells?
normalImage = imread(fileName);
channlImage = rgb2gray(normalImage);
histogramEq = adapthisteq(channlImage,'NumTiles',[50 50],'ClipLimit',0.1);
saturateInt = imadjust(histogramEq);
binaryImage = im2bw(saturateInt,graythresh(saturateInt));
binaryImage = 1 - binaryImage;
normalImage - raw image
histogramEq - increased visibility image
binaryImage - binarized image
Before to apply the threshold, I would separate the different patterns from the background by using a white top-hat. See here the result. Then you stretch the histogram.
Then you can apply what you did.
I would like to build up on FiReTiTi's answer. I have the code below and some screenshots. I have done this using OpenCV 3.0.0
import cv2
x = 'test.jpg'
img = cv2.imread(x, 1)
cv2.imshow("img",img)
#----converting the image to grayscale
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
cv2.imshow('gray', gray)
#----binarization of image
ret,thresh = cv2.threshold(gray,250,255,cv2.THRESH_BINARY)
cv2.imshow("thresh",thresh)
#----performing adaptive thresholding
athresh=cv2.adaptiveThreshold(thresh, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)
cv2.imshow('athresh', athresh)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(7, 7))
#----morphological operation
closing = cv2.morphologyEx(athresh, cv2.MORPH_CLOSE, kernel)
cv2.imshow('closing', closing)
#----masking the obtained result on the grayscale image
result = cv2.bitwise_and(gray, gray, mask= closing)
cv2.imshow('result ', result )