forked from xiaofengShi/CHINESE-OCR
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d81c921
commit 71fdbef
Showing
52 changed files
with
38,359 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,7 +17,6 @@ dist/ | |
downloads/ | ||
eggs/ | ||
.eggs/ | ||
lib/ | ||
lib64/ | ||
parts/ | ||
sdist/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import fast_rcnn |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
# _Author_: xiaofeng | ||
# Date: 2018-04-08 14:41:12 | ||
# Last Modified by: xiaofeng | ||
# Last Modified time: 2018-04-08 14:41:12 | ||
|
||
from .imdb import imdb | ||
# from pascal_voc import pascal_voc | ||
from .pascal_voc import pascal_voc | ||
from . import factory | ||
|
||
def _which(program): | ||
import os | ||
def is_exe(fpath): | ||
return os.path.isfile(fpath) and os.access(fpath, os.X_OK) | ||
|
||
fpath, fname = os.path.split(program) | ||
if fpath: | ||
if is_exe(program): | ||
return program | ||
else: | ||
for path in os.environ["PATH"].split(os.pathsep): | ||
path = path.strip('"') | ||
exe_file = os.path.join(path, program) | ||
if is_exe(exe_file): | ||
return exe_file | ||
|
||
return None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
# _Author_: xiaofeng | ||
# Date: 2018-04-08 14:46:05 | ||
# Last Modified by: xiaofeng | ||
# Last Modified time: 2018-04-08 14:46:05 | ||
|
||
import numpy as np | ||
|
||
def unique_boxes(boxes, scale=1.0): | ||
"""Return indices of unique boxes.""" | ||
v = np.array([1, 1e3, 1e6, 1e9]) | ||
hashes = np.round(boxes * scale).dot(v) | ||
_, index = np.unique(hashes, return_index=True) | ||
return np.sort(index) | ||
|
||
def xywh_to_xyxy(boxes): | ||
"""Convert [x y w h] box format to [x1 y1 x2 y2] format.""" | ||
return np.hstack((boxes[:, 0:2], boxes[:, 0:2] + boxes[:, 2:4] - 1)) | ||
|
||
def xyxy_to_xywh(boxes): | ||
"""Convert [x1 y1 x2 y2] box format to [x y w h] format.""" | ||
return np.hstack((boxes[:, 0:2], boxes[:, 2:4] - boxes[:, 0:2] + 1)) | ||
|
||
def validate_boxes(boxes, width=0, height=0): | ||
"""Check that a set of boxes are valid.""" | ||
x1 = boxes[:, 0] | ||
y1 = boxes[:, 1] | ||
x2 = boxes[:, 2] | ||
y2 = boxes[:, 3] | ||
assert (x1 >= 0).all() | ||
assert (y1 >= 0).all() | ||
assert (x2 >= x1).all() | ||
assert (y2 >= y1).all() | ||
assert (x2 < width).all() | ||
assert (y2 < height).all() | ||
|
||
def filter_small_boxes(boxes, min_size): | ||
w = boxes[:, 2] - boxes[:, 0] | ||
h = boxes[:, 3] - boxes[:, 1] | ||
keep = np.where((w >= min_size) & (h > min_size))[0] | ||
return keep |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
__sets = {} | ||
from .pascal_voc import pascal_voc | ||
|
||
|
||
def _selective_search_IJCV_top_k(split, year, top_k): | ||
imdb = pascal_voc(split, year) | ||
imdb.roidb_handler = imdb.selective_search_IJCV_roidb | ||
imdb.config['top_k'] = top_k | ||
return imdb | ||
|
||
|
||
# Set up voc_<year>_<split> using selective search "fast" mode | ||
for year in ['2007', '2012', '0712']: | ||
for split in ['train', 'val', 'trainval', 'test']: | ||
name = 'voc_{}_{}'.format(year, split) | ||
# __sets[name] = (lambda split=split, year=year: pascal_voc(split, year)) | ||
__sets[name] = (lambda split=split, year=year: pascal_voc(split, year)) | ||
|
||
|
||
def get_imdb(name): | ||
"""Get an imdb (image database) by name.""" | ||
# print('__Sets', __sets) | ||
if name not in __sets: | ||
raise KeyError('Unknown dataset: {}'.format(name)) | ||
return __sets[name]() | ||
|
||
|
||
def list_imdbs(): | ||
"""List all registered imdbs.""" | ||
return list(__sets.keys()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
import os | ||
import os.path as osp | ||
import PIL | ||
import numpy as np | ||
import scipy.sparse | ||
|
||
from ..utils.bbox import bbox_overlaps | ||
from ..fast_rcnn.config import cfg | ||
|
||
|
||
class imdb(object): | ||
def __init__(self, name): | ||
self._name = name | ||
self._num_classes = 0 | ||
self._classes = [] | ||
self._image_index = [] | ||
self._obj_proposer = 'selective_search' | ||
self._roidb = None | ||
print(self.default_roidb) | ||
self._roidb_handler = self.default_roidb | ||
# Use this dict for storing dataset specific config options | ||
self.config = {} | ||
|
||
@property | ||
def name(self): | ||
return self._name | ||
|
||
@property | ||
def num_classes(self): | ||
return len(self._classes) | ||
|
||
@property | ||
def classes(self): | ||
return self._classes | ||
|
||
@property | ||
def image_index(self): | ||
return self._image_index | ||
|
||
@property | ||
def roidb_handler(self): | ||
return self._roidb_handler | ||
|
||
@roidb_handler.setter | ||
def roidb_handler(self, val): | ||
self._roidb_handler = val | ||
|
||
def set_proposal_method(self, method): | ||
method = eval('self.' + method + '_roidb') | ||
self.roidb_handler = method | ||
|
||
@property | ||
def roidb(self): | ||
# A roidb is a list of dictionaries, each with the following keys: | ||
# boxes | ||
# gt_overlaps | ||
# gt_classes | ||
# flipped | ||
if self._roidb is not None: | ||
return self._roidb | ||
self._roidb = self.roidb_handler() | ||
return self._roidb | ||
|
||
@property | ||
def cache_path(self): | ||
cache_path = osp.abspath(osp.join(cfg.DATA_DIR, 'cache')) | ||
if not os.path.exists(cache_path): | ||
os.makedirs(cache_path) | ||
return cache_path | ||
|
||
@property | ||
def num_images(self): | ||
return len(self.image_index) | ||
|
||
def image_path_at(self, i): | ||
raise NotImplementedError | ||
|
||
def default_roidb(self): | ||
raise NotImplementedError | ||
|
||
def _get_widths(self): | ||
return [ | ||
PIL.Image.open(self.image_path_at(i)).size[0] | ||
for i in range(self.num_images) | ||
] | ||
|
||
def append_flipped_images(self): | ||
num_images = self.num_images | ||
widths = self._get_widths() | ||
for i in range(num_images): | ||
boxes = self.roidb[i]['boxes'].copy() | ||
oldx1 = boxes[:, 0].copy() | ||
oldx2 = boxes[:, 2].copy() | ||
boxes[:, 0] = widths[i] - oldx2 - 1 | ||
boxes[:, 2] = widths[i] - oldx1 - 1 | ||
for b in range(len(boxes)): | ||
if boxes[b][2] < boxes[b][0]: | ||
boxes[b][0] = 0 | ||
assert (boxes[:, 2] >= boxes[:, 0]).all() | ||
entry = { | ||
'boxes': boxes, | ||
'gt_overlaps': self.roidb[i]['gt_overlaps'], | ||
'gt_classes': self.roidb[i]['gt_classes'], | ||
'flipped': True | ||
} | ||
|
||
if 'gt_ishard' in self.roidb[i] and 'dontcare_areas' in self.roidb[i]: | ||
entry['gt_ishard'] = self.roidb[i]['gt_ishard'].copy() | ||
dontcare_areas = self.roidb[i]['dontcare_areas'].copy() | ||
oldx1 = dontcare_areas[:, 0].copy() | ||
oldx2 = dontcare_areas[:, 2].copy() | ||
dontcare_areas[:, 0] = widths[i] - oldx2 - 1 | ||
dontcare_areas[:, 2] = widths[i] - oldx1 - 1 | ||
entry['dontcare_areas'] = dontcare_areas | ||
|
||
self.roidb.append(entry) | ||
|
||
self._image_index = self._image_index * 2 | ||
|
||
def create_roidb_from_box_list(self, box_list, gt_roidb): | ||
assert len(box_list) == self.num_images, \ | ||
'Number of boxes must match number of ground-truth images' | ||
roidb = [] | ||
for i in range(self.num_images): | ||
boxes = box_list[i] | ||
num_boxes = boxes.shape[0] | ||
overlaps = np.zeros( | ||
(num_boxes, self.num_classes), dtype=np.float32) | ||
|
||
if gt_roidb is not None and gt_roidb[i]['boxes'].size > 0: | ||
gt_boxes = gt_roidb[i]['boxes'] | ||
gt_classes = gt_roidb[i]['gt_classes'] | ||
gt_overlaps = bbox_overlaps( | ||
boxes.astype(np.float), gt_boxes.astype(np.float)) | ||
argmaxes = gt_overlaps.argmax(axis=1) | ||
maxes = gt_overlaps.max(axis=1) | ||
I = np.where(maxes > 0)[0] | ||
overlaps[I, gt_classes[argmaxes[I]]] = maxes[I] | ||
|
||
overlaps = scipy.sparse.csr_matrix(overlaps) | ||
roidb.append({ | ||
'boxes': | ||
boxes, | ||
'gt_classes': | ||
np.zeros((num_boxes, ), dtype=np.int32), | ||
'gt_overlaps': | ||
overlaps, | ||
'flipped': | ||
False, | ||
'seg_areas': | ||
np.zeros((num_boxes, ), dtype=np.float32), | ||
}) | ||
return roidb | ||
|
||
@staticmethod | ||
def merge_roidbs(a, b): | ||
assert len(a) == len(b) | ||
for i in range(len(a)): | ||
a[i]['boxes'] = np.vstack((a[i]['boxes'], b[i]['boxes'])) | ||
a[i]['gt_classes'] = np.hstack((a[i]['gt_classes'], | ||
b[i]['gt_classes'])) | ||
a[i]['gt_overlaps'] = scipy.sparse.vstack( | ||
[a[i]['gt_overlaps'], b[i]['gt_overlaps']]) | ||
a[i]['seg_areas'] = np.hstack((a[i]['seg_areas'], | ||
b[i]['seg_areas'])) | ||
return a |
Oops, something went wrong.