Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Format code with autopep8 #1

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 33 additions & 33 deletions easyocr/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,40 +233,40 @@ def parse_args():

def main():
args = parse_args()
reader = easyocr.Reader(lang_list=args.lang,\
gpu=args.gpu,\
model_storage_directory=args.model_storage_directory,\
user_network_directory=args.user_network_directory,\
recog_network=args.recog_network,\
download_enabled=args.download_enabled,\
detector=args.detector,\
recognizer=args.recognizer,\
verbose=args.verbose,\
reader = easyocr.Reader(lang_list=args.lang,
gpu=args.gpu,
model_storage_directory=args.model_storage_directory,
user_network_directory=args.user_network_directory,
recog_network=args.recog_network,
download_enabled=args.download_enabled,
detector=args.detector,
recognizer=args.recognizer,
verbose=args.verbose,
quantize=args.quantize)
for line in reader.readtext(args.file,\
decoder=args.decoder,\
beamWidth=args.beamWidth,\
batch_size=args.batch_size,\
workers=args.workers,\
allowlist=args.allowlist,\
blocklist=args.blocklist,\
detail=args.detail,\
rotation_info=args.rotation_info,\
paragraph=args.paragraph,\
min_size=args.min_size,\
contrast_ths=args.contrast_ths,\
adjust_contrast=args.adjust_contrast,\
text_threshold=args.text_threshold,\
low_text=args.low_text,\
link_threshold=args.link_threshold,\
canvas_size=args.canvas_size,\
mag_ratio=args.mag_ratio,\
slope_ths=args.slope_ths,\
ycenter_ths=args.ycenter_ths,\
height_ths=args.height_ths,\
width_ths=args.width_ths,\
y_ths=args.y_ths,\
x_ths=args.x_ths,\
for line in reader.readtext(args.file,
decoder=args.decoder,
beamWidth=args.beamWidth,
batch_size=args.batch_size,
workers=args.workers,
allowlist=args.allowlist,
blocklist=args.blocklist,
detail=args.detail,
rotation_info=args.rotation_info,
paragraph=args.paragraph,
min_size=args.min_size,
contrast_ths=args.contrast_ths,
adjust_contrast=args.adjust_contrast,
text_threshold=args.text_threshold,
low_text=args.low_text,
link_threshold=args.link_threshold,
canvas_size=args.canvas_size,
mag_ratio=args.mag_ratio,
slope_ths=args.slope_ths,
ycenter_ths=args.ycenter_ths,
height_ths=args.height_ths,
width_ths=args.width_ths,
y_ths=args.y_ths,
x_ths=args.x_ths,
add_margin=args.add_margin):
print(line)

Expand Down
72 changes: 36 additions & 36 deletions easyocr/config.py

Large diffs are not rendered by default.

12 changes: 8 additions & 4 deletions easyocr/craft.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from .model.modules import vgg16_bn, init_weights


class double_conv(nn.Module):
def __init__(self, in_ch, mid_ch, out_ch):
super(double_conv, self).__init__()
Expand Down Expand Up @@ -63,18 +64,21 @@ def forward(self, x):
y = torch.cat([sources[0], sources[1]], dim=1)
y = self.upconv1(y)

y = F.interpolate(y, size=sources[2].size()[2:], mode='bilinear', align_corners=False)
y = F.interpolate(y, size=sources[2].size()[
2:], mode='bilinear', align_corners=False)
y = torch.cat([y, sources[2]], dim=1)
y = self.upconv2(y)

y = F.interpolate(y, size=sources[3].size()[2:], mode='bilinear', align_corners=False)
y = F.interpolate(y, size=sources[3].size()[
2:], mode='bilinear', align_corners=False)
y = torch.cat([y, sources[3]], dim=1)
y = self.upconv3(y)

y = F.interpolate(y, size=sources[4].size()[2:], mode='bilinear', align_corners=False)
y = F.interpolate(y, size=sources[4].size()[
2:], mode='bilinear', align_corners=False)
y = torch.cat([y, sources[4]], dim=1)
feature = self.upconv4(y)

y = self.conv_cls(feature)

return y.permute(0,2,3,1), feature
return y.permute(0, 2, 3, 1), feature
120 changes: 79 additions & 41 deletions easyocr/craft_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@

""" auxilary functions """
# unwarp corodinates


def warpCoord(Minv, pt):
out = np.matmul(Minv, (pt[0], pt[1], 1))
return np.array([out[0]/out[2], out[1]/out[2]])


""" end of auxilary functions """


Expand All @@ -28,51 +32,62 @@ def getDetBoxes_core(textmap, linkmap, text_threshold, link_threshold, low_text,
ret, link_score = cv2.threshold(linkmap, link_threshold, 1, 0)

text_score_comb = np.clip(text_score + link_score, 0, 1)
nLabels, labels, stats, centroids = cv2.connectedComponentsWithStats(text_score_comb.astype(np.uint8), connectivity=4)
nLabels, labels, stats, centroids = cv2.connectedComponentsWithStats(
text_score_comb.astype(np.uint8), connectivity=4)

det = []
mapper = []
for k in range(1,nLabels):
for k in range(1, nLabels):
# size filtering
size = stats[k, cv2.CC_STAT_AREA]
if size < 10: continue
if size < 10:
continue

# thresholding
if np.max(textmap[labels==k]) < text_threshold: continue
if np.max(textmap[labels == k]) < text_threshold:
continue

# make segmentation map
segmap = np.zeros(textmap.shape, dtype=np.uint8)
segmap[labels==k] = 255
segmap[labels == k] = 255
if estimate_num_chars:
_, character_locs = cv2.threshold((textmap - linkmap) * segmap /255., text_threshold, 1, 0)
_, character_locs = cv2.threshold(
(textmap - linkmap) * segmap / 255., text_threshold, 1, 0)
_, n_chars = label(character_locs)
mapper.append(n_chars)
else:
mapper.append(k)
segmap[np.logical_and(link_score==1, text_score==0)] = 0 # remove link area
# remove link area
segmap[np.logical_and(link_score == 1, text_score == 0)] = 0
x, y = stats[k, cv2.CC_STAT_LEFT], stats[k, cv2.CC_STAT_TOP]
w, h = stats[k, cv2.CC_STAT_WIDTH], stats[k, cv2.CC_STAT_HEIGHT]
niter = int(math.sqrt(size * min(w, h) / (w * h)) * 2)
sx, ex, sy, ey = x - niter, x + w + niter + 1, y - niter, y + h + niter + 1
# boundary check
if sx < 0 : sx = 0
if sy < 0 : sy = 0
if ex >= img_w: ex = img_w
if ey >= img_h: ey = img_h
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(1 + niter, 1 + niter))
if sx < 0:
sx = 0
if sy < 0:
sy = 0
if ex >= img_w:
ex = img_w
if ey >= img_h:
ey = img_h
kernel = cv2.getStructuringElement(
cv2.MORPH_RECT, (1 + niter, 1 + niter))
segmap[sy:ey, sx:ex] = cv2.dilate(segmap[sy:ey, sx:ex], kernel)

# make box
np_contours = np.roll(np.array(np.where(segmap!=0)),1,axis=0).transpose().reshape(-1,2)
np_contours = np.roll(np.array(np.where(segmap != 0)),
1, axis=0).transpose().reshape(-1, 2)
rectangle = cv2.minAreaRect(np_contours)
box = cv2.boxPoints(rectangle)

# align diamond-shape
w, h = np.linalg.norm(box[0] - box[1]), np.linalg.norm(box[1] - box[2])
box_ratio = max(w, h) / (min(w, h) + 1e-5)
if abs(1 - box_ratio) <= 0.1:
l, r = min(np_contours[:,0]), max(np_contours[:,0])
t, b = min(np_contours[:,1]), max(np_contours[:,1])
l, r = min(np_contours[:, 0]), max(np_contours[:, 0])
t, b = min(np_contours[:, 1]), max(np_contours[:, 1])
box = np.array([[l, t], [r, t], [r, b], [l, b]], dtype=np.float32)

# make clock-wise order
Expand All @@ -84,6 +99,7 @@ def getDetBoxes_core(textmap, linkmap, text_threshold, link_threshold, low_text,

return det, labels, mapper


def getPoly_core(boxes, labels, mapper, linkmap):
# configs
num_cp = 5
Expand All @@ -92,21 +108,25 @@ def getPoly_core(boxes, labels, mapper, linkmap):
max_r = 2.0
step_r = 0.2

polys = []
polys = []
for k, box in enumerate(boxes):
# size filter for small instance
w, h = int(np.linalg.norm(box[0] - box[1]) + 1), int(np.linalg.norm(box[1] - box[2]) + 1)
w, h = int(np.linalg.norm(box[0] - box[1]) +
1), int(np.linalg.norm(box[1] - box[2]) + 1)
if w < 10 or h < 10:
polys.append(None); continue
polys.append(None)
continue

# warp image
tar = np.float32([[0,0],[w,0],[w,h],[0,h]])
tar = np.float32([[0, 0], [w, 0], [w, h], [0, h]])
M = cv2.getPerspectiveTransform(box, tar)
word_label = cv2.warpPerspective(labels, M, (w, h), flags=cv2.INTER_NEAREST)
word_label = cv2.warpPerspective(
labels, M, (w, h), flags=cv2.INTER_NEAREST)
try:
Minv = np.linalg.inv(M)
except:
polys.append(None); continue
polys.append(None)
continue

# binarization for selected label
cur_label = mapper[k]
Expand All @@ -118,15 +138,18 @@ def getPoly_core(boxes, labels, mapper, linkmap):
cp = []
max_len = -1
for i in range(w):
region = np.where(word_label[:,i] != 0)[0]
if len(region) < 2 : continue
region = np.where(word_label[:, i] != 0)[0]
if len(region) < 2:
continue
cp.append((i, region[0], region[-1]))
length = region[-1] - region[0] + 1
if length > max_len: max_len = length
if length > max_len:
max_len = length

# pass if max_len is similar to h
if h * max_len_ratio < max_len:
polys.append(None); continue
polys.append(None)
continue

# get pivot points with fixed length
tot_seg = num_cp * 2 + 1
Expand All @@ -137,12 +160,14 @@ def getPoly_core(boxes, labels, mapper, linkmap):
seg_num = 0
num_sec = 0
prev_h = -1
for i in range(0,len(cp)):
for i in range(0, len(cp)):
(x, sy, ey) = cp[i]
if (seg_num + 1) * seg_w <= x and seg_num <= tot_seg:
# average previous segment
if num_sec == 0: break
cp_section[seg_num] = [cp_section[seg_num][0] / num_sec, cp_section[seg_num][1] / num_sec]
if num_sec == 0:
break
cp_section[seg_num] = [cp_section[seg_num][0] /
num_sec, cp_section[seg_num][1] / num_sec]
num_sec = 0

# reset variables
Expand All @@ -152,10 +177,12 @@ def getPoly_core(boxes, labels, mapper, linkmap):
# accumulate center points
cy = (sy + ey) * 0.5
cur_h = ey - sy + 1
cp_section[seg_num] = [cp_section[seg_num][0] + x, cp_section[seg_num][1] + cy]
cp_section[seg_num] = [cp_section[seg_num]
[0] + x, cp_section[seg_num][1] + cy]
num_sec += 1

if seg_num % 2 == 0: continue # No polygon area
if seg_num % 2 == 0:
continue # No polygon area

if prev_h < cur_h:
pp[int((seg_num - 1)/2)] = (x, cy)
Expand All @@ -164,11 +191,13 @@ def getPoly_core(boxes, labels, mapper, linkmap):

# processing last segment
if num_sec != 0:
cp_section[-1] = [cp_section[-1][0] / num_sec, cp_section[-1][1] / num_sec]
cp_section[-1] = [cp_section[-1][0] /
num_sec, cp_section[-1][1] / num_sec]

# pass if num of pivots is not sufficient or segment width is smaller than character height
# pass if num of pivots is not sufficient or segment width is smaller than character height
if None in pp or seg_w < np.max(seg_height) * 0.25:
polys.append(None); continue
polys.append(None)
continue

# calc median maximum of pivot points
half_char_h = np.median(seg_height) * expand_ratio / 2
Expand All @@ -187,23 +216,27 @@ def getPoly_core(boxes, labels, mapper, linkmap):

# get edge points to cover character heatmaps
isSppFound, isEppFound = False, False
grad_s = (pp[1][1] - pp[0][1]) / (pp[1][0] - pp[0][0]) + (pp[2][1] - pp[1][1]) / (pp[2][0] - pp[1][0])
grad_e = (pp[-2][1] - pp[-1][1]) / (pp[-2][0] - pp[-1][0]) + (pp[-3][1] - pp[-2][1]) / (pp[-3][0] - pp[-2][0])
grad_s = (pp[1][1] - pp[0][1]) / (pp[1][0] - pp[0][0]) + \
(pp[2][1] - pp[1][1]) / (pp[2][0] - pp[1][0])
grad_e = (pp[-2][1] - pp[-1][1]) / (pp[-2][0] - pp[-1][0]) + \
(pp[-3][1] - pp[-2][1]) / (pp[-3][0] - pp[-2][0])
for r in np.arange(0.5, max_r, step_r):
dx = 2 * half_char_h * r
if not isSppFound:
line_img = np.zeros(word_label.shape, dtype=np.uint8)
dy = grad_s * dx
p = np.array(new_pp[0]) - np.array([dx, dy, dx, dy])
cv2.line(line_img, (int(p[0]), int(p[1])), (int(p[2]), int(p[3])), 1, thickness=1)
cv2.line(line_img, (int(p[0]), int(p[1])),
(int(p[2]), int(p[3])), 1, thickness=1)
if np.sum(np.logical_and(word_label, line_img)) == 0 or r + 2 * step_r >= max_r:
spp = p
isSppFound = True
if not isEppFound:
line_img = np.zeros(word_label.shape, dtype=np.uint8)
dy = grad_e * dx
p = np.array(new_pp[-1]) + np.array([dx, dy, dx, dy])
cv2.line(line_img, (int(p[0]), int(p[1])), (int(p[2]), int(p[3])), 1, thickness=1)
cv2.line(line_img, (int(p[0]), int(p[1])),
(int(p[2]), int(p[3])), 1, thickness=1)
if np.sum(np.logical_and(word_label, line_img)) == 0 or r + 2 * step_r >= max_r:
epp = p
isEppFound = True
Expand All @@ -212,7 +245,8 @@ def getPoly_core(boxes, labels, mapper, linkmap):

# pass if boundary of polygon is not found
if not (isSppFound and isEppFound):
polys.append(None); continue
polys.append(None)
continue

# make final polygon
poly = []
Expand All @@ -230,10 +264,13 @@ def getPoly_core(boxes, labels, mapper, linkmap):

return polys


def getDetBoxes(textmap, linkmap, text_threshold, link_threshold, low_text, poly=False, estimate_num_chars=False):
if poly and estimate_num_chars:
raise Exception("Estimating the number of characters not currently supported with poly.")
boxes, labels, mapper = getDetBoxes_core(textmap, linkmap, text_threshold, link_threshold, low_text, estimate_num_chars)
raise Exception(
"Estimating the number of characters not currently supported with poly.")
boxes, labels, mapper = getDetBoxes_core(
textmap, linkmap, text_threshold, link_threshold, low_text, estimate_num_chars)

if poly:
polys = getPoly_core(boxes, labels, mapper, linkmap)
Expand All @@ -242,7 +279,8 @@ def getDetBoxes(textmap, linkmap, text_threshold, link_threshold, low_text, poly

return boxes, polys, mapper

def adjustResultCoordinates(polys, ratio_w, ratio_h, ratio_net = 2):

def adjustResultCoordinates(polys, ratio_w, ratio_h, ratio_net=2):
if len(polys) > 0:
polys = np.array(polys)
for k in range(len(polys)):
Expand Down
Loading