-
Notifications
You must be signed in to change notification settings - Fork 0
/
char_segmentation.py
128 lines (104 loc) · 3.82 KB
/
char_segmentation.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
__author__ = 'zhangm2'
import cv2
import paper_detection
import imutil
from imutil import show_img
debug = False
def get_rows(img):
# Morph Filter
st = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7, 7))
img = cv2.morphologyEx(img, cv2.MORPH_ERODE, st, iterations=3)
if debug:
show_img(img)
# Find contours
tempImg = img.copy()
mgCont, contrs, hier = cv2.findContours(tempImg, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
# Filter contours
validContrs = []
for i in range(len(contrs)):
if hier[0][i][3] != -1:
validContrs.append(contrs[i])
# Sort contours
validContrs, boundingBoxes = imutil.sort_contours(validContrs, method="top-to-bottom")
return boundingBoxes
def get_chars(img):
paper = paper_detection.get_paper(img)
if debug:
show_img(paper)
# Convert to gray scale
img = cv2.cvtColor(paper, cv2.COLOR_RGB2GRAY)
# Blur
img = cv2.GaussianBlur(img, (3, 3), 0)
# OTSU binarize
img = imutil.otsu(img)
if debug:
show_img(img)
# Find contours
tempImg = img.copy()
mgCont, contrs, hier = cv2.findContours(tempImg, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
# Filter contours
validContrs = []
for i in range(len(contrs)):
if hier[0][i][3] != -1:
validContrs.append(contrs[i])
# Find rows
rowBoundingBoxes = get_rows(img)
# Put characters in rows
charsInRows = []
spaceBetweenLetters = []
for row in rowBoundingBoxes:
a, b, w, h = row
chars = []
for validContr in validContrs:
charBoundingBox = cv2.boundingRect(validContr)
center = (charBoundingBox[0] + charBoundingBox[2] / 2, charBoundingBox[1] + charBoundingBox[3] / 2)
if center[0] > a and center[0] < a + w and center[1] > b and center[1] < b + h:
chars.append(validContr)
charsInRows.append(chars)
# Sort characters
for a in range(len(charsInRows)):
charsInRows[a], tempBoundingBoxes = imutil.sort_contours(charsInRows[a])
# Detect character i or j and merge it (threshold +-2px)
charBoundingBoxes = []
b = 0
lastI = 0
while b < len(tempBoundingBoxes) - 1:
currBox = tempBoundingBoxes[b]
nextBox = tempBoundingBoxes[b + 1]
currBoxCenterX = currBox[0] + (currBox[2] / 2)
print currBoxCenterX
print nextBox
if currBoxCenterX > nextBox[0] and currBoxCenterX < nextBox[0] + nextBox[2]:
x = currBox[0]
y = min(currBox[1], nextBox[1])
w = max(currBox[0] + currBox[2], nextBox[0] + nextBox[2]) - x
h = max(currBox[1] + currBox[3], nextBox[1] + nextBox[3]) - y
charBoundingBoxes.append((x, y, w, h))
lastI = b
b += 2
else:
charBoundingBoxes.append(currBox)
b += 1
if lastI != len(tempBoundingBoxes) - 2:
charBoundingBoxes.append(tempBoundingBoxes[len(tempBoundingBoxes) - 1])
charsInRows[a] = charBoundingBoxes
# Draw bounding boxes
if debug:
for row in charsInRows:
for char in row:
x, y, w, h = char
cv2.rectangle(paper, (x, y), (x + w, y + h), (0, 255, 0))
show_img(paper)
for j in range(len(charsInRows)):
spaceRow = []
for i in range(len(charsInRows[j])-1):
# print charsInRows[0][i]
# print "Dist cal."
distance = charsInRows[j][i+1][0] - charsInRows[j][i][0] - charsInRows[j][i][2]
if distance >= 7:
spaceRow.append(1)
else:
spaceRow.append(0)
spaceBetweenLetters.append(spaceRow)
spaceRow = []
return charsInRows, paper, spaceBetweenLetters