You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
5.5 KiB
Python
145 lines
5.5 KiB
Python
import numpy as np
|
|
from shapely import geometry
|
|
import cv2
|
|
import imutils
|
|
|
|
def filter_contours_area_of_image(image, contours, hirarchy, max_area, min_area):
|
|
found_polygons_early = list()
|
|
|
|
jv = 0
|
|
for c in contours:
|
|
if len(c) < 3: # A polygon cannot have less than 3 points
|
|
continue
|
|
|
|
polygon = geometry.Polygon([point[0] for point in c])
|
|
area = polygon.area
|
|
if area >= min_area * np.prod(image.shape[:2]) and area <= max_area * np.prod(image.shape[:2]) and hirarchy[0][jv][3] == -1: # and hirarchy[0][jv][3]==-1 :
|
|
found_polygons_early.append(np.array([[point] for point in polygon.exterior.coords], dtype=np.uint))
|
|
jv += 1
|
|
return found_polygons_early
|
|
|
|
def filter_contours_area_of_image_interiors(image, contours, hirarchy, max_area, min_area):
|
|
found_polygons_early = list()
|
|
|
|
jv = 0
|
|
for c in contours:
|
|
if len(c) < 3: # A polygon cannot have less than 3 points
|
|
continue
|
|
|
|
polygon = geometry.Polygon([point[0] for point in c])
|
|
area = polygon.area
|
|
if area >= min_area * np.prod(image.shape[:2]) and area <= max_area * np.prod(image.shape[:2]) and hirarchy[0][jv][3] != -1:
|
|
# print(c[0][0][1])
|
|
found_polygons_early.append(np.array([point for point in polygon.exterior.coords], dtype=np.uint))
|
|
jv += 1
|
|
return found_polygons_early
|
|
|
|
|
|
def filter_contours_area_of_image_tables(image, contours, hirarchy, max_area, min_area):
|
|
found_polygons_early = list()
|
|
|
|
jv = 0
|
|
for c in contours:
|
|
if len(c) < 3: # A polygon cannot have less than 3 points
|
|
continue
|
|
|
|
polygon = geometry.Polygon([point[0] for point in c])
|
|
# area = cv2.contourArea(c)
|
|
area = polygon.area
|
|
##print(np.prod(thresh.shape[:2]))
|
|
# Check that polygon has area greater than minimal area
|
|
# print(hirarchy[0][jv][3],hirarchy )
|
|
if area >= min_area * np.prod(image.shape[:2]) and area <= max_area * np.prod(image.shape[:2]): # and hirarchy[0][jv][3]==-1 :
|
|
# print(c[0][0][1])
|
|
found_polygons_early.append(np.array([[point] for point in polygon.exterior.coords], dtype=np.int32))
|
|
jv += 1
|
|
return found_polygons_early
|
|
|
|
def resize_image(img_in, input_height, input_width):
|
|
return cv2.resize(img_in, (input_width, input_height), interpolation=cv2.INTER_NEAREST)
|
|
|
|
def rotatedRectWithMaxArea(w, h, angle):
|
|
if w <= 0 or h <= 0:
|
|
return 0, 0
|
|
|
|
width_is_longer = w >= h
|
|
side_long, side_short = (w, h) if width_is_longer else (h, w)
|
|
|
|
# since the solutions for angle, -angle and 180-angle are all the same,
|
|
# if suffices to look at the first quadrant and the absolute values of sin,cos:
|
|
sin_a, cos_a = abs(math.sin(angle)), abs(math.cos(angle))
|
|
if side_short <= 2.0 * sin_a * cos_a * side_long or abs(sin_a - cos_a) < 1e-10:
|
|
# half constrained case: two crop corners touch the longer side,
|
|
# the other two corners are on the mid-line parallel to the longer line
|
|
x = 0.5 * side_short
|
|
wr, hr = (x / sin_a, x / cos_a) if width_is_longer else (x / cos_a, x / sin_a)
|
|
else:
|
|
# fully constrained case: crop touches all 4 sides
|
|
cos_2a = cos_a * cos_a - sin_a * sin_a
|
|
wr, hr = (w * cos_a - h * sin_a) / cos_2a, (h * cos_a - w * sin_a) / cos_2a
|
|
|
|
return wr, hr
|
|
|
|
def rotate_max_area_new(image, rotated, angle):
|
|
wr, hr = rotatedRectWithMaxArea(image.shape[1], image.shape[0], math.radians(angle))
|
|
h, w, _ = rotated.shape
|
|
y1 = h // 2 - int(hr / 2)
|
|
y2 = y1 + int(hr)
|
|
x1 = w // 2 - int(wr / 2)
|
|
x2 = x1 + int(wr)
|
|
return rotated[y1:y2, x1:x2]
|
|
|
|
def rotation_image_new(img, thetha):
|
|
rotated = imutils.rotate(img, thetha)
|
|
return rotate_max_area_new(img, rotated, thetha)
|
|
|
|
def rotate_image(img_patch, slope):
|
|
(h, w) = img_patch.shape[:2]
|
|
center = (w // 2, h // 2)
|
|
M = cv2.getRotationMatrix2D(center, slope, 1.0)
|
|
return cv2.warpAffine(img_patch, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)
|
|
|
|
def rotyate_image_different( img, slope):
|
|
# img = cv2.imread('images/input.jpg')
|
|
num_rows, num_cols = img.shape[:2]
|
|
|
|
rotation_matrix = cv2.getRotationMatrix2D((num_cols / 2, num_rows / 2), slope, 1)
|
|
img_rotation = cv2.warpAffine(img, rotation_matrix, (num_cols, num_rows))
|
|
return img_rotation
|
|
|
|
def crop_image_inside_box(box, img_org_copy):
|
|
image_box = img_org_copy[box[1] : box[1] + box[3], box[0] : box[0] + box[2]]
|
|
return image_box, [box[1], box[1] + box[3], box[0], box[0] + box[2]]
|
|
|
|
def otsu_copy(img):
|
|
img_r = np.zeros(img.shape)
|
|
img1 = img[:, :, 0]
|
|
img2 = img[:, :, 1]
|
|
img3 = img[:, :, 2]
|
|
# print(img.min())
|
|
# print(img[:,:,0].min())
|
|
# blur = cv2.GaussianBlur(img,(5,5))
|
|
# ret3,th3 = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
|
|
retval1, threshold1 = cv2.threshold(img1, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
|
|
retval2, threshold2 = cv2.threshold(img2, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
|
|
retval3, threshold3 = cv2.threshold(img3, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
|
|
|
|
img_r[:, :, 0] = threshold1
|
|
img_r[:, :, 1] = threshold1
|
|
img_r[:, :, 2] = threshold1
|
|
return img_r
|
|
|
|
def otsu_copy_binary(img):
|
|
img_r = np.zeros((img.shape[0], img.shape[1], 3))
|
|
img1 = img[:, :, 0]
|
|
|
|
retval1, threshold1 = cv2.threshold(img1, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
|
|
|
|
img_r[:, :, 0] = threshold1
|
|
img_r[:, :, 1] = threshold1
|
|
img_r[:, :, 2] = threshold1
|
|
|
|
img_r = img_r / float(np.max(img_r)) * 255
|
|
return img_r
|
|
|