Skip to content
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
2 changes: 1 addition & 1 deletion modulesettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"RuntimeLocation": "Local", // Can be Local, Shared or System
"PostStartPauseSecs": 1, // Generally 1 if using GPU, 0 for CPU
"Queue": "objectdetection_queue", // We make all Object detectors use the same queue.
"Parallelism": 16 // Should probably be TPU count * 2; I don't see harm in overprovisioning threads
"Parallelism": 2 // Should probably be TPU count * 2; I don't see harm in overprovisioning threads
},

"ModelRequirements" : [{
Expand Down
1 change: 1 addition & 0 deletions more_examples.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ python3 examples/classify_image.py \
--model test_data/mobilenet_v2_1.0_224_inat_bird_quant_edgetpu.tflite \
--labels test_data/inat_bird_labels.txt \
--input test_data/parrot.jpg

5 changes: 3 additions & 2 deletions objectdetection_coral_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,13 +179,14 @@ def _do_detection(self, img: any, score_threshold: float):
result = do_detect(opts, img, score_threshold)

if not result['success']:
error = result["error"] if "error" in result else "Unable to perform detection"
return {
"success" : False,
"error" : result["error"] if "error" in result else "Unable to perform detection",
"error" : error,
"inferenceMs" : result['inferenceMs'],
"processMs" : int((time.perf_counter() - start_process_time) * 1000),
"predictions" : [],
"message" : '',
"message" : error,
"count" : 0
}

Expand Down
100 changes: 53 additions & 47 deletions objectdetection_coral_singletpu.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,58 +270,64 @@ def do_detect(options: Options, img: Image, score_threshold: float = 0.5):
std = 128 # args.input_std
top_k = 1

# Once in a while refresh the interpreter
(device, error) = periodic_check(options)
# The periodic (re)check/refresh of the interpreter, input setup, invoke and
# output extraction must all happen under the same lock: periodic_check can
# tear down and rebuild the shared `interpreter` (reset_detector/init_detect),
# and doing that concurrently with another thread's invoke()/get_objects() on
# the old interpreter corrupts its internal tensor buffers ("There is at least
# 1 reference to internal data in the interpreter..." from TF-Lite).
with inference_lock:
# Once in a while refresh the interpreter
(device, error) = periodic_check(options)

if not interpreter:
return {
"success" : False,
"error" : error,
"count" : 0,
"predictions" : [],
"inferenceMs" : 0
}
if not interpreter:
return {
"success" : False,
"error" : error,
"count" : 0,
"predictions" : [],
"inferenceMs" : 0
}

w,h = img.size
# print("Debug: Input(height, width): ", h, w)
w,h = img.size
# print("Debug: Input(height, width): ", h, w)

_, scale = common.set_resized_input(
interpreter, img.size, lambda size: img.resize(size, Image.Resampling.LANCZOS))
_, scale = common.set_resized_input(
interpreter, img.size, lambda size: img.resize(size, Image.Resampling.LANCZOS))

"""
size = common.input_size(interpreter)
resize_im = img.convert('RGB').resize(size, Image.ANTIALIAS)

# numpy_image = np.array(img)
# input_im = cv2.cvtColor(numpy_image, cv2.COLOR_BGR2RGB)
# resize_im = cv2.resize(input_im, size)

# Image data must go through two transforms before running inference:
# 1. normalization: f = (input - mean) / std
# 2. quantization: q = f / scale + zero_point
# The following code combines the two steps as such:
# q = (input - mean) / (std * scale) + zero_point
# However, if std * scale equals 1, and mean - zero_point equals 0, the input
# does not need any preprocessing (but in practice, even if the results are
# very close to 1 and 0, it is probably okay to skip preprocessing for better
# efficiency; we use 1e-5 below instead of absolute zero).

params = common.input_details(interpreter, 'quantization_parameters')
scale = params['scales']
zero_point = params['zero_points']

if abs(scale * std - 1) < 1e-5 and abs(mean - zero_point) < 1e-5:
# Input data does not require preprocessing.
common.set_input(interpreter, resize_im)
else:
# Input data requires preprocessing
normalized_input = (np.asarray(resize_im) - mean) / (std * scale) + zero_point
np.clip(normalized_input, 0, 255, out=normalized_input)
common.set_input(interpreter, normalized_input.astype(np.uint8))
"""
"""
size = common.input_size(interpreter)
resize_im = img.convert('RGB').resize(size, Image.ANTIALIAS)

# numpy_image = np.array(img)
# input_im = cv2.cvtColor(numpy_image, cv2.COLOR_BGR2RGB)
# resize_im = cv2.resize(input_im, size)

# Image data must go through two transforms before running inference:
# 1. normalization: f = (input - mean) / std
# 2. quantization: q = f / scale + zero_point
# The following code combines the two steps as such:
# q = (input - mean) / (std * scale) + zero_point
# However, if std * scale equals 1, and mean - zero_point equals 0, the input
# does not need any preprocessing (but in practice, even if the results are
# very close to 1 and 0, it is probably okay to skip preprocessing for better
# efficiency; we use 1e-5 below instead of absolute zero).

params = common.input_details(interpreter, 'quantization_parameters')
scale = params['scales']
zero_point = params['zero_points']

if abs(scale * std - 1) < 1e-5 and abs(mean - zero_point) < 1e-5:
# Input data does not require preprocessing.
common.set_input(interpreter, resize_im)
else:
# Input data requires preprocessing
normalized_input = (np.asarray(resize_im) - mean) / (std * scale) + zero_point
np.clip(normalized_input, 0, 255, out=normalized_input)
common.set_input(interpreter, normalized_input.astype(np.uint8))
"""

# Run inference
with inference_lock:
# Run inference
start_inference_time = time.perf_counter()
try:
interpreter.invoke()
Expand Down