I am developing an application to read the numbers from an image using opencv in Python 3. I first converted the image to gray scale,then Apply dilation and erosion to remove some noise, then Apply threshold to get image with only black and white, then Write the image to local disk to do some ..., then apply tesseract to recognise the number for python.
I need to extract the numbers from the image. I am new to openCV. Does anybody know any other method to get the result??
I have share the image link bellow, i was trying to extract from that image. Thanks in advance
https://drive.google.com/file/d/141y-3okLPGP_STje14ukSqSHcgtwMdRO/view?usp=sharing
import cv2
import numpy as np
import pytesseract
from PIL import Image
from pytesseract import image_to_string
# Path of working folder on Disk
src_path = "/Users/sougata.a.roy/Desktop/Images/"
def get_string(img_path):
# Read image with opencv
img = cv2.imread(img_path)
# Convert to gray
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 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)
# Write image after removed noise
cv2.imwrite(src_path + "removed_noise.jpg", img)
# Apply threshold to get image with only black and white
img = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 31, 2)
# Write the image after apply opencv to do some ...
cv2.imwrite(src_path + 'thres.jpg', img)
# Recognize text with tesseract for python
result = pytesseract.image_to_string(Image.open(src_path + "thres.jpg"), lang='eng')
return result
print('--- Start recognize text from image ---')
print(get_string(src_path + 'abcdefg195.jpg'))
print("------ Done -------")
365
Related
I am trying to count seeds in an image using cv2 thresholding. The test image is below:
When I run the below code to create a mask:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('S__14278933.jpg')
#img = cv2.fastNlMeansDenoisingColored(img,None,10,10,7,21)
mask = cv2.threshold(img[:, :, 0], 255, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
plt.imshow(mask)
I get the following mask:
But ideally it should give a small yellow dot at the centre. I have tried this with other images and it works just fine.
Can someone help?
The lighting in your image seems not uniform. Try using Adaptive Thresholding:
import cv2
import numpy as np
# image path
path = "D://opencvImages//"
fileName = "c6pBO.jpg"
# Reading an image in default mode:
inputImage = cv2.imread(path + fileName)
# Convert the image to grayscale:
grayImage = cv2.cvtColor(inputImage, cv2.COLOR_BGR2GRAY)
# Get binary image via Adaptive Thresholding :
windowSize = 31
windowConstant = 40
binaryImage = cv2.adaptiveThreshold( grayImage, 255, cv2.ADAPTIVE_THRESH_MEAN_C,
cv2.THRESH_BINARY_INV, windowSize, windowConstant )
cv2.imshow("binaryImage", binaryImage)
cv2.waitKey(0)
You might want to apply an Area Filter after this, though, as dark portions on the image will yield noise.
Try it
img=cv2.imread('foto.jpg',0)
mask = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV )[1]
I need to read the highest temperature on thermographic images, as shown below:
IR_1544_INFRA.jpg
IR_1546_INFRA.jpg
IR_1560_INFRA.jpg
IR_1564_INFRA.jpg
I used the following code, this was the best result.
I also tried several other ways, such as: blur, gray scale, binarization, and others but they all failed.
import cv2
import pytesseract
pytesseract.pytesseract.tesseract_cmd = r"C:\Users\User\AppData\Local\Tesseract-OCR\tesseract.exe"
# Load image, grayscale, Otsu's threshold
entrada = cv2.imread('IR_1546_INFRA.jpg')
image = entrada[40:65, 277:319]
#image = cv2.imread('IR_1546_INFRA.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = 255 - cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
# Blur and perform text extraction
thresh = cv2.GaussianBlur(thresh, (3,3), 0)
data = pytesseract.image_to_string(thresh, lang='eng', config='--psm 6')
print(data)
cv2.imshow('thresh', thresh)
cv2.waitKey()
In the first image, I found
this
In the second image, I found this.
The imagem layout is always the same, that is, the temperature is always in the same place, so I cropped the image to isolate only the number. I would like (97.7 here, and 85.2 here).
My code needs to find from these images to always detect this temperature and generate a list indicating from highest to lowest.
What do you indicate for me to improve the assertiveness of pytesseract in the case of these images?
Note 1: When I annalyze the entire image (without cropping), it returns data that is not even present.
Note 2: In some images even with the binary number, pytesseract (image_to_string) does not return any data.
Thank you all and sorry for the typos, writing in english is still a challenge for me.
Because you have same images, you can crop the area you want and then do processing there. The processing is also simple. Change to gray, get threshold, invert, resize, and then do the OCR. You can see it in my code below. It works on all your attached images.
import cv2
import pytesseract
import os
image_path = "temperature"
for nama_file in sorted(os.listdir(image_path)):
print(nama_file)
img = cv2.imread(os.path.join(image_path, nama_file))
crop = img[43:62, 278:319]
gray = cv2.cvtColor(crop, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY)[1]
thresh = cv2.bitwise_not(thresh)
double = cv2.resize(thresh, None, fx=2, fy=2)
custom_config = r'-l eng --oem 3 --psm 7 -c tessedit_char_whitelist="1234567890." '
text = pytesseract.image_to_string(double, config=custom_config)
print("detected: " + text)
cv2.imshow("img", img)
cv2.imshow("double", double)
cv2.waitKey(0)
cv2.destroyAllWindows()
What I tried so far. it's working fine most of image which is text black and background is white.
from PIL import Image
import pytesseract
import nltk
import cv2
imageName = "p9.png"
img = cv2.imread(imageName,cv2.IMREAD_COLOR) #Open the image from which charectors has to be recognized
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #convert to grey to reduce detials
gray = cv2.bilateralFilter(gray, 11, 17, 17) #Blur to reduce noise
original = pytesseract.image_to_string(gray, config='')
print (original)
but below image I do not give right text.
Output:
REMIUM OKING OIL
KETTLE-RENDERED 9s MADE FROM POR siren!
fatworks €)
NET WT. 4 02 (3966)
how to resolve this issue.
What I meant is
imageName = "p9.png"
img = cv2.imread(imageName,cv2.IMREAD_COLOR) #Open the image from which charectors has to be recognized
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #convert to grey to reduce detials
gray = cv2.bilateralFilter(gray, 11, 17, 17) #Blur to reduce noise
img = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,71,2)
#img = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,\
cv2.THRESH_BINARY,11,2)
original = pytesseract.image_to_string(img, config='')
Play around with parameters of this function to find what works for you best
cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst]).
I also keep here a link to original tutorial: https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_thresholding/py_thresholding.html
I'm using pytesseract to extract email id from images, using below code.
import pytesseract as ps
text = ps.image_to_string('./email_id.png')
print(text)
But the extarcted text is not correct. Example for image:
it extracts email id as : adarsh_1493#yahoo.com
Similarly when I'm using below image:
The result is coming as : airiorceschooibegumpet#yahoo.com .
I tried to follow few configs as suggested by different posts but nothing worked. (Tesseract-OCR V5.0.0alpha20190708)
Any help highly appreciated!
You will need to preprocess the image.
I recommend the following types to begin with converting to grayscale and thresholding first:
# get grayscale image
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# threshold gray image
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
Then try variations of noise removal, dilation and erosion.
# noise removal
cv2.medianBlur(thresh,5)
# dilation
kernel = np.ones((5,5),np.uint8)
cv2.dilate(thresh, kernel, iterations = 1)
# erosion
kernel = np.ones((5,5),np.uint8)
cv2.erode(thresh, kernel, iterations = 1)
When I try to convert PNG type PIL Image into OpenCV Image, transparent background at PNG turns into black background. How can I keep the transparent background in OpenCV Image object.
Here is the code piece :
# PIL Image object which holds a transparent background png image.
pil_img = Image.open(ioFile).convert('RGBA')
pil_img.show()
# I use numpy to convert the pil_image into a numpy array
numpy_image = np.array(pil_img)
# I convert to a openCV2 image, notice the COLOR_RGB2BGR which means that
# the color is converted from RGBA to BGR format
opencvImage = cv2.cvtColor(numpy_image, cv2.COLOR_RGBA2BGRA)
#
#(I commented below lines, to show that I tried them but did not work.)
#
# opencvImage = cv2.cvtColor(numpy_image, cv2.IMREAD_UNCHANGED)
# opencvImage = cv2.cvtColor(numpy_image, cv2.COLOR_RGB2BGR)
showImage(opencvImage)
The last line of code piece shows an image with black background. I probably choose the wrong convert method and, could not find the proper one.
You can use this code for save transparency when converting.
To convert (with Alpha) from Pillow image to OpenCv image:
You can manually change the color order.
import cv2
from PIL import Image
import numpy as np
pillowImage = Image.open('picturePath.png').convert('RGBA')
img = np.array(pillowImage) # 'img' Color order: RGBA
red = img[:,:,0].copy() # Copy R from RGBA
img[:,:,0] = img[:,:,2].copy() # Copy B to first order. Color order: BGBA
img[:,:,2] = red # Copy R to the third order. Color order: BGRA
opencvImage = img # img is OpenCV variable