This repository has been archived by the owner on Feb 26, 2021. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #50 from unarxiv/dev
Merge Object Detection API into codebase
- Loading branch information
Showing
31 changed files
with
1,071 additions
and
178 deletions.
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 |
---|---|---|
@@ -0,0 +1,46 @@ | ||
[[source]] | ||
|
||
name = "pypi" | ||
url = "https://pypi.python.org/simple" | ||
verify_ssl = true | ||
|
||
|
||
[dev-packages] | ||
|
||
|
||
|
||
[packages] | ||
|
||
bleach = "==2.1.3" | ||
certifi = "==2018.4.16" | ||
chardet = "==3.0.4" | ||
cycler = "==0.10.0" | ||
decorator = "==4.3.0" | ||
"enum34" = "==1.1.6" | ||
"html5lib" = "==1.0.1" | ||
idna = "==2.6" | ||
markdown = "==2.6.11" | ||
networkx = "==2.1" | ||
numpy = "==1.14.3" | ||
pillow = "==5.1.0" | ||
pkginfo = "==1.4.2" | ||
protobuf = "==3.5.2" | ||
pyparsing = "==2.2.0" | ||
python-dateutil = "==2.7.3" | ||
pytz = "==2018.4" | ||
pywavelets = "==0.5.2" | ||
requests = "==2.18.4" | ||
requests-toolbelt = "==0.8.0" | ||
scikit-image = "==0.14.0" | ||
scipy = "==1.1.0" | ||
tensorflow-gpu = "==1.8.0" | ||
tensorflow-tensorboard = "==1.5.1" | ||
tensorlayer = "==1.8.5" | ||
tqdm = "==4.23.4" | ||
twine = "==1.11.0" | ||
"urllib3" = "==1.23" | ||
werkzeug = "==0.14.1" | ||
coverage = "*" | ||
easydict = "*" | ||
logbook = "*" | ||
lxml = "*" |
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,2 @@ | ||
object_detection/* | ||
!object_detection/install-ubuntu.sh |
Submodule tf-models
added at
7367d4
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
Large diffs are not rendered by default.
Oops, something went wrong.
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
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
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
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
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,55 @@ | ||
import os | ||
import zipfile | ||
|
||
from tqdm import tqdm | ||
|
||
from cvtron.utils.logger.Logger import logger | ||
|
||
|
||
class ArchiveFile(object): | ||
def __init__(self, filepath): | ||
if zipfile.is_zipfile(filepath): | ||
self._af = zipfile.ZipFile(filepath, 'r') | ||
self.filepath = filepath | ||
logger.info("Successfully load file" + filepath) | ||
else: | ||
logger.error("Cannot load file" + filepath) | ||
|
||
def getInfo(self): | ||
return self._af.infolist() | ||
|
||
def unzip(self, extractTo, deleteOrigin=False): | ||
uncompress_size = sum((file.file_size for file in self._af.infolist())) | ||
extracted_size = 0 | ||
pbar = tqdm(total=uncompress_size, initial=extracted_size, unit='B', unit_scale=True, desc="uncompressing " + self.filepath) | ||
for file in self._af.infolist(): | ||
self._af.extract(file, extractTo) | ||
extracted_size += file.file_size | ||
pbar.update(extracted_size) | ||
self._af.extractall(extractTo) | ||
logger.info("Successfully unzip file") | ||
if deleteOrigin: | ||
os.remove(self.filepath) | ||
logger.info("Successfully delete original file") | ||
|
||
class ToArchiveFolder(object): | ||
def __init__(self, folderPath): | ||
if not os.path.exists(folderPath): | ||
logger.error("Folder Path Not Found") | ||
else: | ||
self.folderPath = folderPath | ||
def zip(self, target): | ||
if self.folderPath is None: | ||
logger.error("Folder Path Not Specified") | ||
return False | ||
else: | ||
abs_src = os.path.abspath(self.folderPath) | ||
contents = os.walk(self.folderPath) | ||
self._af = zipfile.ZipFile(target, 'w', zipfile.ZIP_DEFLATED) | ||
for root, dirs, files in contents: | ||
for file in files: | ||
abs_name = os.path.abspath(os.path.join(root, file)) | ||
arcname = abs_name[len(abs_src) + 1:] | ||
logger.info('adding file' + abs_name) | ||
self._af.write(abs_name, arcname) | ||
self._af.close() |
Empty file.
Empty file.
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,9 @@ | ||
""" | ||
Files in this directory is used to handle dataset from Visual Label | ||
(https://github.com/unarxiv/visual-label) | ||
The dataset format documentation could be found at | ||
(https://cvtron.unarxiv.org/guide/data-format.html) | ||
""" | ||
|
||
from cvtron.data_zoo.compress_util import ArchiveFile |
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 |
---|---|---|
@@ -1,11 +1,14 @@ | ||
''' | ||
ORIGINAL URL | ||
''' | ||
INCEPTION_CKPT_URL = 'https://deepbase-1251068397.cos.ap-guangzhou.myqcloud.com/inception_v3.ckpt' | ||
VGG_NPY_URL = 'https://deepbase-1251068397.cos.ap-guangzhou.myqcloud.com/vgg19.npy' | ||
LAPSRN_URL = 'https://deepbase-1251068397.cos.ap-guangzhou.myqcloud.com/lapsrn.npz' | ||
YOLO_TINY_CKPT_URL = 'https://deepbase-1251068397.cos.ap-guangzhou.myqcloud.com/yolo_tiny.ckpt' | ||
''' | ||
CDN URL | ||
INCEPTION_CKPT_URL = 'http://cdn.zhitantech.com/static/inception_v3.ckpt' | ||
VGG_NPY_URL = 'http://cdn.zhitantech.com/static/vgg19.npy' | ||
LAPSRN_URL = 'http://cdn.zhitantech.com/static/lapsrn.npz' | ||
YOLO_TINY_CKPT_URL = 'http://cdn.zhitantech.com/static/yolo_tiny.ckpt' | ||
''' |
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
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,115 @@ | ||
#coding:utf-8 | ||
import numpy as np | ||
from PIL import Image | ||
import tensorflow as tf | ||
from object_detection.utils import label_map_util | ||
|
||
from cvtron.Base.decorator import singleton | ||
from cvtron.utils.logger.Logger import logger | ||
from cvtron.utils.image_loader import get_image_size | ||
from cvtron.utils.image_loader import load_image_into_numpy_array | ||
|
||
@singleton | ||
class SlimObjectDetector(object): | ||
def __init__(self): | ||
self.hasInitialized = False | ||
|
||
|
||
def set_label_map(self, label_map_file): | ||
self.label_map = label_map_file | ||
|
||
def init(self, model_path): | ||
if not self.hasInitialized: | ||
self._init_model_(model_path) | ||
else: | ||
logger.info('model has initialized, skipping') | ||
|
||
def _init_model_(self, model_path): | ||
logger.info('initiating model') | ||
detection_graph = tf.Graph() | ||
with detection_graph.as_default(): | ||
od_graph_def = tf.GraphDef() | ||
with tf.gfile.GFile(model_path, 'rb') as fid: | ||
serialized_graph = fid.read() | ||
od_graph_def.ParseFromString(serialized_graph) | ||
tf.import_graph_def(od_graph_def, name='') | ||
self.graph = detection_graph | ||
logger.info('model initialized') | ||
|
||
def format_output(self, results, im_width, im_height, threshold): | ||
label_map = label_map_util.load_labelmap(self.label_map) | ||
categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=90, use_display_name=True) | ||
category_index = label_map_util.create_category_index(categories) | ||
vis_results = [] | ||
for i in range(len(results)): | ||
output_dict = results[i] | ||
boxes = output_dict['detection_boxes'] | ||
classes = output_dict['detection_classes'] | ||
scores = output_dict['detection_scores'] | ||
for j in range(boxes.shape[0]): | ||
if scores[i] > threshold: | ||
result = {} | ||
ymin, xmin, ymax, xmax = tuple(boxes[i].tolist()) | ||
result['x_min'] = xmin * im_width | ||
result['x_max'] = xmax * im_width | ||
result['y_min'] = ymin * im_height | ||
result['y_max'] = ymax * im_height | ||
result['score'] = float(scores[i]) | ||
if classes[i] in category_index.keys(): | ||
class_name = category_index[classes[i]]['name'] | ||
else: | ||
class_name = 'N/A' | ||
result['class_name'] = str(class_name) | ||
if result not in vis_results: | ||
vis_results.append(result) | ||
return vis_results | ||
|
||
def detect(self, img_file, threshold = 0.7): | ||
# read image | ||
image_np = load_image_into_numpy_array(img_file) | ||
(im_width, im_height) = get_image_size(img_file) | ||
# Inference process | ||
with self.graph.as_default(): | ||
with tf.Session() as sess: | ||
## Get handles to input and output tensors | ||
ops = tf.get_default_graph().get_operations() | ||
all_tensor_names = { | ||
output.name for op in ops for output in op.outputs | ||
} | ||
tensor_dict = {} | ||
for key in [ | ||
'num_detections', 'detection_boxes', 'detection_scores', | ||
'detection_classes', 'detection_masks' | ||
]: | ||
tensor_name = key + ':0' | ||
if tensor_name in all_tensor_names: | ||
tensor_dict[key] = tf.get_default_graph().get_tensor_by_name(tensor_name) | ||
if 'detection_masks' in tensor_dict: | ||
# The following processing is only for single image | ||
detection_boxes = tf.squeeze(tensor_dict['detection_boxes'], [0]) | ||
detection_masks = tf.squeeze(tensor_dict['detection_masks'], [0]) | ||
# Reframe is required to translate mask from box coordinates to image coordinates and fit the image size. | ||
real_num_detection = tf.cast(tensor_dict['num_detections'][0], tf.int32) | ||
detection_boxes = tf.slice(detection_boxes, [0, 0], [real_num_detection, -1]) | ||
detection_masks = tf.slice(detection_masks, [0, 0, 0], [real_num_detection, -1, -1]) | ||
detection_masks_reframed = ops.reframe_box_masks_to_image_masks( | ||
detection_masks, detection_boxes, image_np.shape[0], image_np.shape[1]) | ||
detection_masks_reframed = tf.cast( | ||
tf.greater(detection_masks_reframed, 0.5), tf.uint8) | ||
# Follow the convention by adding back the batch dimension | ||
tensor_dict['detection_masks'] = tf.expand_dims( | ||
detection_masks_reframed, 0) | ||
image_tensor = tf.get_default_graph().get_tensor_by_name('image_tensor:0') | ||
## Run inference | ||
output_dict = sess.run(tensor_dict, feed_dict={ | ||
image_tensor: np.expand_dims(image_np, 0) | ||
}) | ||
output_dict['num_detections'] = int(output_dict['num_detections'][0]) | ||
output_dict['detection_classes'] = output_dict[ | ||
'detection_classes'][0].astype(np.uint8) | ||
output_dict['detection_boxes'] = output_dict['detection_boxes'][0] | ||
output_dict['detection_scores'] = output_dict['detection_scores'][0] | ||
if 'detection_masks' in output_dict: | ||
output_dict['detection_masks'] = output_dict['detection_masks'][0] | ||
results = [output_dict] | ||
return self.format_output(results, im_width, im_height, threshold) |
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
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 |
---|---|---|
|
@@ -37,5 +37,4 @@ def get_segmentor_trainer(config): | |
return dlt | ||
|
||
def get_defaultConfig(): | ||
print(config) | ||
return config |
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,5 @@ | ||
class BaseTrainer(object): | ||
def __init__(self): | ||
pass | ||
def start(self): | ||
pass |
Empty file.
Empty file.
Oops, something went wrong.