|
import numpy as np |
|
import cv2 |
|
|
|
import sys |
|
import os |
|
import logging |
|
|
|
logging.basicConfig( |
|
level=logging.INFO, |
|
format='%(asctime)s - %(levelname)s - %(message)s' |
|
) |
|
logger = logging.getLogger(__name__) |
|
|
|
|
|
cordinates = [] |
|
|
|
def remove_shadow(image): |
|
try: |
|
rgb_planes = cv2.split(image) |
|
result_planes = [] |
|
result_norm_planes = [] |
|
|
|
for plane in rgb_planes: |
|
dilated_img = cv2.dilate(plane, np.ones((7,7), np.uint8)) |
|
bg_img = cv2.medianBlur(dilated_img, 21) |
|
diff_img = 255 - cv2.absdiff(plane, bg_img) |
|
norm_img = cv2.normalize(diff_img, None, alpha=0, beta=255, |
|
norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8UC1) |
|
result_planes.append(diff_img) |
|
result_norm_planes.append(norm_img) |
|
|
|
result = cv2.merge(result_planes) |
|
result_norm = cv2.merge(result_norm_planes) |
|
|
|
return result, result_norm |
|
except Exception as e: |
|
logger.error(f"Error in remove_shadow: {str(e)}") |
|
return image, image |
|
|
|
x_scaling = 0 |
|
y_scaling = 0 |
|
binary_image1 = 0 |
|
line = 0 |
|
line_length = 0 |
|
count = 0 |
|
|
|
def analise(image): |
|
try: |
|
global line, binary_image1, x_scaling, y_scaling |
|
line = [] |
|
kernel = np.ones((1,250), np.uint8) |
|
dilation = cv2.dilate(image, kernel, iterations=2) |
|
|
|
contours, _ = cv2.findContours(dilation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) |
|
|
|
for i in reversed(contours): |
|
x, y, w, h = cv2.boundingRect(i) |
|
if cv2.contourArea(i) < 20 or h < 8: |
|
continue |
|
|
|
scaling_factor_in_y = 0.5 |
|
scaling_factor_in_x = 0 |
|
resized_contour = i.copy() |
|
|
|
resized_contour = i * [x_scaling, y_scaling] |
|
resized_contour = resized_contour.astype(int) |
|
final_image__ = np.zeros_like(binary_image1) |
|
cv2.drawContours(final_image__, [resized_contour], 0, (255), -1) |
|
|
|
kernel_dil = np.ones((3,3), np.uint8) |
|
final_image__ = cv2.dilate(final_image__, kernel_dil, iterations=3) |
|
|
|
line_image_final = cv2.bitwise_and(final_image__, binary_image1) |
|
line.append(line_image_final) |
|
|
|
except Exception as e: |
|
logger.error(f"Error in analise: {str(e)}") |
|
return [] |
|
|
|
def image_resize_and_erosion(image): |
|
try: |
|
height, width = image.shape[:2] |
|
height = height + 1 * height |
|
height = int(height) |
|
|
|
resized_image = cv2.resize(image, (width, height)) |
|
kernel = np.ones((13,1), np.uint8) |
|
erosion = cv2.erode(resized_image, kernel, iterations=1) |
|
return erosion |
|
except Exception as e: |
|
logger.error(f"Error in image_resize_and_erosion: {str(e)}") |
|
return image |
|
|
|
def convert_image(img): |
|
try: |
|
global x_scaling, y_scaling, binary_image1, line, line_length, count |
|
img_copy = np.copy(img) |
|
line_length = 250 |
|
rect_image = img |
|
|
|
|
|
image1, image2_ = remove_shadow(rect_image) |
|
gray_ = cv2.cvtColor(image2_, cv2.COLOR_BGR2GRAY) |
|
|
|
|
|
_, binary_image_ = cv2.threshold(gray_, 200, 255, cv2.THRESH_BINARY) |
|
inverted_binary_image_ = 255 - binary_image_ |
|
binary_image1 = np.copy(inverted_binary_image_) |
|
|
|
|
|
y_height, x_width = rect_image.shape[:2] |
|
new_width = 500 * 5 |
|
new_height = 705 * 5 |
|
x_scaling = x_width / new_width |
|
y_scaling = y_height / new_height |
|
|
|
|
|
rect_image = cv2.resize(rect_image, (new_width, new_height), interpolation=cv2.INTER_NEAREST) |
|
|
|
|
|
image1, image2 = remove_shadow(rect_image) |
|
gray = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY) |
|
_, binary_image = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY) |
|
inverted_binary_image = 255 - binary_image |
|
|
|
|
|
kernel = np.ones((2,2), np.uint8) |
|
erosion = cv2.erode(inverted_binary_image, kernel, iterations=1) |
|
dilation = cv2.dilate(erosion, kernel, iterations=1) |
|
new_image = np.copy(dilation) |
|
new_image = 255 - new_image |
|
|
|
|
|
kernel = np.ones((1,250), np.uint8) |
|
dilation_1 = cv2.dilate(dilation, kernel, iterations=2) |
|
contours, _ = cv2.findContours(dilation_1, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) |
|
|
|
line = [] |
|
for i in reversed(contours): |
|
x, y, w, h = cv2.boundingRect(i) |
|
if cv2.contourArea(i) < 20 or h < 10: |
|
continue |
|
cv2.drawContours(new_image, [i], -1, (0), 2) |
|
final_image_ = np.zeros_like(binary_image) |
|
cv2.drawContours(final_image_, [i], 0, (255), -1) |
|
line_image = cv2.bitwise_and(final_image_, dilation) |
|
analise(line_image) |
|
|
|
|
|
count = 0 |
|
kernel1 = np.ones((8,8), np.uint8) |
|
word__image = [] |
|
|
|
for line_image in line: |
|
dilation_2 = cv2.dilate(line_image, kernel1, iterations=2) |
|
contours1, _ = cv2.findContours(dilation_2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) |
|
sorted_contours = sorted(contours1, key=lambda c: cv2.boundingRect(c)[0]) |
|
|
|
for j in sorted_contours: |
|
x1, y1, w1, h1 = cv2.boundingRect(j) |
|
final_image = line_image[y1:y1+h1, x1:x1+w1] |
|
final_image = 255 - final_image |
|
word__image.append(final_image) |
|
count += 1 |
|
|
|
logger.info(f"Successfully processed {count} word images") |
|
return word__image |
|
|
|
except Exception as e: |
|
logger.error(f"Error in convert_image: {str(e)}") |
|
return [] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|