How to extract text from image - python-3.x

I have tried most of the solutions on the site to extract data from the image,
only this script worked with the format *.tif, and gave me correct data
'''
from PIL import Image
import glob
import pytesseract
image_list = []
for filename in glob.glob(my_image):
im=Image.open(filename)
image_list.append(im)
pytesseract.pytesseract.tesseract_cmd="C:\\Program Files\\Tesseract-OCR\\tesseract.exe"
texts = [pytesseract.image_to_string(img,lang = 'eng') for img in image_list]
'''
However, this is not working with *.png and *.jpg, I tried the following:
'''
import cv2
import numpy as np
image = cv2.imread('1.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
sharpen_kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
sharpen = cv2.filter2D(gray, -1, sharpen_kernel)
thresh = cv2.threshold(sharpen, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
close = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=1)
result = 255 - close
'''
And like,
'''
import os
from PIL import Image
import cv2
import pytesseract
import ftfy
import uuid
filename = img
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)
'''
and such, but not given me data, how can I extract text from image like of invoice?

import pytesseract
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract'
print(pytesseract.image_to_string(r'D:\examplepdf2image.png'))
def escape(html):
"""Returns the given HTML with ampersands, quotes and carets encoded."""
return mark_safe(force_unicode(html).replace('&', '&').replace('<', '<').replace('>', '>').replace('"', '"').replace("'", '''))
this a sample code put instead of trying to print text through many different variables from this to that just try to print the image itself first. Then work on how to improve from there. One last thing is that this will let python work without errors making it easy to understand as well. The second piece of code with the def escape shows how to import an html file which you have to put your pieces of code into so you change it to your liking.

Related

Watermark in the photo

I'm making a watermark in the photo. How to make a watermark for several photos at once? and How to save multiple photos at once? which loop should be and in which part of the code?
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
from PIL import ImageOps
def watermark_text(input_image_path,
output_image_path,
text, pos):
photo = Image.open(input_image_path)
drawing = ImageDraw.Draw(photo)
white = (3, 8, 12)
font = ImageFont.truetype("/Roboto-Regular.ttf", 150)
drawing.text(pos, text, fill=white, font=font)
photo.show()
photo.save(output_image_path)
if __name__ == '__main__':
img = 'new7093.JPG'
watermark_text(img, '11112.JPG',
text='sportves.ru',
pos=(300,500))
How about using multiprocessing.
from concurrent.futures import ProcessPoolExecutor
import os
img_list = os.listdir('path-to-image')
output_img_list = [i +'.output' for i in img_list]
text='sportves.ru'
pos=(300,500)
with ThreadPoolExecutor(max_workers=4) as executor:
futures = [executor.submit(watermark_text, input_image_path, output_image_path, text, pos)
for input_image_path, output_image_path
in zip(img_list, output_img_list)
]
It is should work). Replace a save path and append images to put watermarks.
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
def watermark_text(input_image_path,
output_image_path,
text, pos):
global new_images
photo = Image.open(input_image_path)
drawing = ImageDraw.Draw(photo)
white = (3, 8, 12)
font = ImageFont.truetype("/Roboto-Regular.ttf", 150)
drawing.text(pos, text, fill=white, font=font)
photo.show()
new_images.append(photo)
if __name__ == '__main__':
images = ['new7093.JPG', 'something.phg'] # list of photos without watermark
new_images = [] # list of photos with watermark
for img in images:
watermark_text(img, '11112.JPG',
text='sportves.ru',
pos=(300, 500))
new_images[0].save(r'C:\Users\You\Desktop', save_all=True,
append_images=new_images[1:]) # replace by you path

Looping an OpenCV image inside a Tkinter label - using an esp32-cam

It's a loop understanding problem, I'm new to Tkinter and I don't know how the images are updated
°°°PROBLEM°°°
It is about making a program that captures images of the esp32-cam module and can visualize and use them with the urllib and Opencv libraries, in addition to displaying the images in Tkinter to make a user interface
The image updates correctly but scrolls down as shown in the images
I would like you to help me with the problem and how to anchor it where I want, use the function .place (x = 0, y = 0) in and out of the loop but the image was not updating
°°°IMAGES°°°
starting the program, the image is centered in the Tkinter window, that's fine.
first capture
when the image is refreshed at 500 milliseconds, the image is scrolled down "infinitely", as shown in the following image:
second capture
#Python v3.8.4
import tkinter as *
from PIL import Image, ImageTk
import cv2
import numpy as np
import urllib.request
url='http://192.168.0.24/picture'
delay = 1000
imgtk = [None]
def loopCapture():
imgResponse = urllib.request.urlopen (url)
imgNp =np.array(bytearray(imgResponse.read()),dtype=np.uint8)
image = cv2.imdecode (imgNp, -1)
b,g,r = cv2.split(image)
img = cv2.merge((r,g,b))
im = Image.fromarray(img)
imgtk[0] = ImageTk.PhotoImage(image = im)
capture = Label(root, image = imgtk[0]).pack()
root.after(delay, loopCapture)
root = Tk()
root.geometry("1200x700")
loopCapture()
root.mainloop()
I just needed to learn more about the tkinter library, but if anyone comes across the same question, here is the code:
capture when running the program.
from PIL import Image, ImageTk
import urllib.request
import tkinter as tk
import numpy as np
import cv2
# esp32-cam url
urlCam ='http://192.168.0.24/picture'
panel = None
root = None
def loopCamera():
imgResponse = urllib.request.urlopen (urlCam)
imgNp = np.array(bytearray(imgResponse.read()),dtype=np.uint8)
image = cv2.imdecode (imgNp, -1)
b,g,r = cv2.split(image)
img = cv2.merge((r,g,b))
im = Image.fromarray(img)
imgtk = ImageTk.PhotoImage(image = im)
panel.configure(image = imgtk)
panel.image = imgtk
panel.after(5, loopCamera)
root = tk.Tk()
root.title('car-vision')
root.geometry('1000x600')
panel = tk.Label(root)
panel.pack()
loopCamera()
root.mainloop()

Python cv2.imread() by url

i want to get images by url here on 6 and 7 lines, any help or ideas?
import urllib
import numpy as np
mkembed = ""
ourembed = ""
mkpic = cv2.imread("image.jpg")
ourpic = cv2.imread("image2.jpg")
difference = cv2.subtract(mkpic, ourpic)
b, g, r = cv2.split(difference)
if cv2.countNonZero(b) == 0 and cv2.countNonZero(g) == 0 and cv2.countNonZero(r) == 0:
print("The images are completely Equal")```
Use the following code to get an image by url with cv2:
#import necessary packages
import numpy as np
import urllib.request as urllib
import cv2
#get image by url
resp = urllib.urlopen("https://homepages.cae.wisc.edu/~ece533/images/airplane.png")
image = np.asarray(bytearray(resp.read()), dtype="uint8")
image = cv2.imdecode(image, cv2.IMREAD_COLOR)
#show image
cv2.imshow("Image", image)
cv2.waitKey()

How to speed up this code with Numpy?

Currently I am using the following code to convert all non-black pixels to white:
def convert(self, img):
for i in range(img.shape[0]):
for j in range(img.shape[1]):
if img.item(i, j) != 0:
img.itemset((i, j), 255)
return img
How can I speed it up?
All elements that are not 0 should change to 255:
a[a != 0] = 255
How about using PIL and make the function like this:
def convert (self,image):
return image.convert('1')
Test code:
from PIL import Image
import matplotlib.pyplot as plt
def convert (image):
return image.convert('1')
img = Image.open('./test.png')
plt.figure(); plt.imshow(img)
BW = convert(img)
plt.figure(); plt.imshow(BW)
plt.show()
result :
And btw, in case you needed the numpy array of the PIL image object, you can easily get it using:
matrix_of_img = numpy.asarray(img.convert('L'))

Assertion failed (m.dims >= 2) in Mat

Here is the code for image thresholding I am getting the error at line 22,
which is:-
ret,thresh2 = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)
Here in this code I want to capture image frames from the video camera and then perform various kinds of thresholding operations on the captured image frames.
I have stored image frames at various instances of time. My objective is to segment the moving objects in the video. Hence I am applying thresholding operation.
Does anybody have any idea, how to do it?
Thanks in advance.
import cv2
import numpy as np
import time
from matplotlib import pyplot as plt
import sys
cam = cv2.VideoCapture(0)
while(cam.isOpened()):
ret, frame = cam.read() #Keep on capturing the frames continuously
while (ret==True):
#img = cv2.imread('/home/shrikrishna/Detection&Tracking/OpenCV-Tutorial',6)
cv2.imwrite('At time'+ str(time.clock()) + '.jpg', frame)
img2 = cv2.imread('At time'+ str(time.clock()) + '.jpg',6)
t = str(time.clock())
cv2.imshow('Orignal',frame)
k = cv2.waitKey(0) & 0xffff
if(k==27):
#img = cv2.imread('At time'+ str(time.clock()) + '.jpg',6)
break
if(k==ord('q')):
sys.exit(0)
break
#cv2.imwrite('At time'+ t + '.jpg', frame)
img = cv2.imread('At time'+ t + '.jpg',6)
ret,thresh1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
ret,thresh2 = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)
ret,thresh3 = cv2.threshold(img,127,255,cv2.THRESH_TRUNC)
ret,thresh4 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO)
ret,thresh5 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV)
titles = ['Original Image','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]
for i in xrange(6):
plt.subplot(2,3,i+1),plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()
In the following line, you read in an image as colour image (based on the second parameter -- flags).
img = cv2.imread('At time'+ t + '.jpg',6)
This means that img contains 3 channels, which in Python is represented by a 3-dimensional array.
You immediately use this image as the source for thresholding:
ret,thresh1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
According to the documentation, the first parameter to threshold() is:
src – input array (single-channel, 8-bit or 32-bit floating point).
That means you need a single channel image, e.g. a grayscale image:
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,thresh1 = cv2.threshold(img_gray,127,255,cv2.THRESH_BINARY)
# ...
Another option would be to just read the image as grayscale in first place:
img_gray = cv2.imread('At time'+ t + '.jpg',0)
# ...

Resources