pritmanvar's picture
created project
bfabfea
# method 4 mix two methods
import cv2
import numpy as np
import os
import re
import pytesseract
from dotenv import load_dotenv
from pathlib import Path
env_path = Path('.') / '.env'
load_dotenv(dotenv_path=env_path)
path = {
'TESSERACT_PATH': str(os.getenv('TESSERACT_PATH')),
}
pytesseract.pytesseract.tesseract_cmd = (path['TESSERACT_PATH'])
def hoffman_transformation(image, verbose=False):
"""
this function performs hoffman transformation method which fixes the rotation of image in 4 angles 0,90,270,360.
Args:
image (ndarray): gets image and perform hoffman tarnsformation
verbose (bool, optional): for seeing image transformation using matplotlib plots. Defaults to False.
Returns:
rotated_image: returns rotated image which can be only 4 angles rotated label
"""
# Define our parameters for Canny
low_threshold = 50
high_threshold = 100
kernel = np.ones((8,8),dtype=np.uint8)
eroded_image = cv2.erode(image,kernel=kernel)
eroded_image = cv2.dilate(eroded_image,kernel)
# perform canny edge detection
edges = cv2.Canny(eroded_image, low_threshold, high_threshold)
edges = cv2.erode(edges,(50,50))
# Define the Hough transform parameters
# Make a blank the same size as our image to draw on
rho = 1
theta = np.pi/180
threshold = 60
min_line_length = 10
max_line_gap = 5
line_image = np.copy(image) #creating an image copy to draw lines on
# Run Hough on the edge-detected image
lines = cv2.HoughLinesP(edges, rho, theta, threshold, np.array([]),
min_line_length, max_line_gap)
# Iterate over the output "lines" and draw lines on the image copy
angles_count = {}
final_angle = 0
if lines is not None:
for line in lines:
if line is not None:
for x1,y1,x2,y2 in line:
cv2.line(line_image,(x1,y1),(x2,y2),(255,0,0),5)
angle = 0
if abs(x1-x2) < 0.000001:
angle = np.pi/2
else:
angle = (y1-y2)/(x1-x2)
angle = np.arctan(angle)
angle = angle*180/np.pi
angle = np.round(angle)
if angle%10 < 5:
angle = angle- angle%10
else:
angle = angle + 10 - angle%10
if angle in angles_count:
angles_count[angle] += 1
else:
angles_count[angle] = 1
final_angle = max(angles_count, key=angles_count.get)
line_image = cv2.putText(line_image, str(final_angle), (20,30), cv2.FONT_HERSHEY_COMPLEX, 1, (0,255,0), 3, cv2.LINE_8, False)
angle= 360
angle-= final_angle
angle = -(90 + angle) if angle < -45 else -angle
# rotate image at final_angle using rotation matrix and warpAffine transformation
h, w = image.shape[:2]
(c_x, c_y) = (w // 2, h // 2)
matrix = cv2.getRotationMatrix2D((c_x, c_y), angle, 1.0)
cos = np.abs(matrix[0, 0])
sin = np.abs(matrix[0, 1])
n_w = int((h * sin) + (w * cos))
n_h = int((h * cos) + (w * sin))
matrix[0, 2] += (n_w / 2) - c_x
matrix[1, 2] += (n_h / 2) - c_y
rotated_image = cv2.warpAffine(image, matrix, (n_w, n_h), borderValue=(255, 255, 255))
return rotated_image,angle
def rotate(
image: np.ndarray, angle: float
) -> np.ndarray:
""" this function rotates the image at given angle and returns the rotated image
Args:
image (np.ndarray): _description_
angle (float): _description_
Returns:
np.ndarray: _description_
"""
h, w = image.shape[:2]
(c_x, c_y) = (w // 2, h // 2)
matrix = cv2.getRotationMatrix2D((c_x, c_y), angle, 1.0)
cos = np.abs(matrix[0, 0])
sin = np.abs(matrix[0, 1])
n_w = int((h * sin) + (w * cos))
n_h = int((h * cos) + (w * sin))
matrix[0, 2] += (n_w / 2) - c_x
matrix[1, 2] += (n_h / 2) - c_y
return cv2.warpAffine(image, matrix, (n_w, n_h), borderValue=(255, 255, 255))
def pytesseractRotate(image,original_image, grid=3):
""" this function takes one image and apply pytesseract osd method and gives orientation and script details and returns 0 degree oriented parcel image.
Args:
image (ndarray): takes image and perform osd
original_image (ndarray): _description_
grid (int, optional): _description_. Defaults to 3.
Returns:
rotated_image (ndarray):
"""
h, w = image.shape[:2]
images_list = []
angles_list = {}
for i in range(1, grid+1):
for j in range(1, grid+1):
tx, ty = (w//grid)*(j-1), (h//grid)*(i-1)
bx, by = (w//grid)*j, (h//grid)*i
img = image[ty:by, tx: bx]
images_list.append(img)
for i in range(len(images_list)):
try:
result = pytesseract.image_to_osd(images_list[i], config="osd --psm 0 -c min_characters_to_try=200", output_type='dict')
pytesseract_angle = result['rotate']
orientation_conf = result['orientation_conf']
script = result['script']
script_conf = result['script_conf']
script_list = ['Latin','Cyrillic']
if script in script_list and script_conf > 0:
if pytesseract_angle in angles_list:
angles_list[pytesseract_angle].append(orientation_conf)
else:
angles_list[pytesseract_angle] = [orientation_conf]
except Exception as error:
print(error)
confidence_list = []
for key in angles_list.keys():
mean = sum(angles_list[key])/len(angles_list[key])
confidence_list.append((len(angles_list[key]), mean, key))
confidence_list = sorted(confidence_list)
final_angle = 360
if len(confidence_list) > 0:
final_angle -= confidence_list[-1][-1]
else:
final_angle -= 0
rotated_image = rotate(original_image, final_angle)
return rotated_image