-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtools.py
107 lines (77 loc) · 3.05 KB
/
tools.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import cv2
import imutils
import numpy as np
from skimage.filters import gaussian, threshold_otsu
from skimage.feature import canny
from skimage.transform import probabilistic_hough_line, rotate
# get grayscale image
def get_grayscale(image):
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
return image
# noise removal
def remove_noise(image):
return cv2.medianBlur(image, 5)
# thresholding
def thresholding(image):
return cv2.threshold(image, 249, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
# dilation
def dilate(image):
kernel = np.ones((5, 5), np.uint8)
return cv2.dilate(image, kernel, iterations=1)
# erosion
def erode(image):
kernel = np.ones((5, 5), np.uint8)
return cv2.erode(image, kernel, iterations=1)
# opening - erosion followed by dilation
def opening(image):
kernel = np.ones((5, 5), np.uint8)
return cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel)
# skew correction
def deskew(image):
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# threshold to get rid of extraneous noise
thresh = threshold_otsu(image)
normalize = image > thresh
# gaussian blur
blur = gaussian(normalize, 3)
# canny edges in scikit-image
edges = canny(blur)
# hough lines
hough_lines = probabilistic_hough_line(edges)
# hough lines returns a list of points, in the form ((x1, y1), (x2, y2))
# representing line segments. the first step is to calculate the slopes of
# these lines from their paired point values
slopes = [(y2 - y1) / (x2 - x1) if (x2 - x1) else 0 for (x1, y1), (x2, y2) in hough_lines]
# it just so happens that this slope is also y where y = tan(theta), the angle
# in a circle by which the line is offset
rad_angles = [np.arctan(x) for x in slopes]
# and we change to degrees for the rotation
deg_angles = [np.degrees(x) for x in rad_angles]
# which of these degree values is most common?
histo = np.histogram(deg_angles, bins=180)
# correcting for 'sideways' alignments
rotation_number = histo[1][np.argmax(histo[0])]
if rotation_number > 45:
rotation_number = -(90 - rotation_number)
elif rotation_number < -45:
rotation_number = 90 - abs(rotation_number)
return rotation_number
# template matching
def match_template(image, template):
return cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED)
def process_image(image_path):
image_path = image_path.lower()
if image_path.endswith('.tif') or image_path.endswith('.png') or image_path.endswith('.jpg') or image_path.endswith('.jpeg'):
image = cv2.imread(image_path)
height, width, channels = image.shape
new_width = 640 # pixels
new_height = int(height * (new_width / width))
image = cv2.resize(image, (new_width, new_height))
rotation_angle = deskew(image)
image = imutils.rotate(image, angle=rotation_angle)
gray = get_grayscale(image)
thresh = thresholding(gray)
return image, gray, thresh
else:
print('Invalid image format')
return None, None, None