Skip to content

Commit 7bace15

Browse files
Updating code, model, and dataset from the project
1 parent 7a1fafd commit 7bace15

33 files changed

+12047
-0
lines changed

code/TFLite_Model_Maker_(Color_Ducky).ipynb

Lines changed: 2793 additions & 0 deletions
Large diffs are not rendered by default.

code/TFLite_Model_Maker_(Ducky_Chicken).ipynb

Lines changed: 2901 additions & 0 deletions
Large diffs are not rendered by default.

code/TFLite_Model_Maker_(Ducky_Frog).ipynb

Lines changed: 2880 additions & 0 deletions
Large diffs are not rendered by default.

code/Test_Image_Data_Augmentation.ipynb

Lines changed: 567 additions & 0 deletions
Large diffs are not rendered by default.

code/Train_Image_Data_Augmentation.ipynb

Lines changed: 797 additions & 0 deletions
Large diffs are not rendered by default.

code/constant.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
"""This module defines constants used in the project"""
2+
3+
LIMIT_CMR_TIME = 10
4+
LIMIT_IR_TIME = 10
5+
LIMIT_DET_TIME = 5

code/detect_and_capture.py

Lines changed: 313 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,313 @@
1+
"""Main script to run the object detection routine."""
2+
import argparse
3+
import os
4+
import sys
5+
import shutil
6+
import time
7+
import datetime
8+
9+
import numpy as np
10+
import cv2
11+
from tflite_support.task import core
12+
from tflite_support.task import processor
13+
from tflite_support.task import vision
14+
import utils
15+
16+
import constant
17+
18+
# Define Image and Video Directory
19+
PARENT_DIR = r'/home/pi/examples/lite/examples/object_detection/raspberry_pi'
20+
IMAGE_DIR = r'/home/pi/examples/lite/examples/object_detection/raspberry_pi/image'
21+
VIDEO_DIR = r'/home/pi/examples/lite/examples/object_detection/raspberry_pi/video'
22+
23+
24+
def run(
25+
is_multiple: bool,
26+
all_images: bool,
27+
true_name: str,
28+
model: str,
29+
camera_id: int,
30+
width: int,
31+
height: int,
32+
num_threads: int,
33+
enable_edgetpu: bool,
34+
detection_threshold: float,
35+
vid_filename: str):
36+
"""Continuously run inference on images acquired from the camera.
37+
Args:
38+
is_multiple: True/False whether there is multiple type of object.
39+
all_images: True/False whether to collect all images.
40+
true_name: true label for detected object name.
41+
model: Name of the TFLite object detection model.
42+
camera_id: The camera id to be passed to OpenCV.
43+
width: The width of the frame captured from the camera.
44+
height: The height of the frame captured from the camera.
45+
num_threads: The number of CPU threads to run the model.
46+
enable_edgetpu: True/False whether the model is a EdgeTPU model.
47+
detection_threshold: Minimum score to be detected by model.
48+
vid_filename: filename of output video.
49+
"""
50+
51+
# Variables to calculate FPS
52+
counter, fps = 0, 0
53+
start_time = time.time()
54+
55+
# Variables to collect detection
56+
detection_counter = 1
57+
frame_counter = 1
58+
old_cmr_time = 0
59+
cmr_time = 0
60+
61+
# Define flags
62+
print_message = False
63+
64+
# Start capturing video input from the camera
65+
cap = cv2.VideoCapture(camera_id)
66+
cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
67+
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
68+
69+
# Define the codec and create VideoWriter Object
70+
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
71+
out = cv2.VideoWriter(vid_filename, fourcc, 2.5, (width, height))
72+
73+
# Visualization parameters
74+
size_ratio = np.sqrt(width**2 + height**2)/np.sqrt(640**2 + 480**2)
75+
x_position = 5 # pixels
76+
y_position = 5 # pixels
77+
font_size = 2*size_ratio
78+
font_thickness = 3*int(size_ratio)
79+
fps_avg_frame_count = 10
80+
81+
# Initialize the object detection model
82+
base_options = core.BaseOptions(
83+
file_name=model, use_coral=enable_edgetpu, num_threads=num_threads)
84+
detection_options = processor.DetectionOptions(
85+
max_results=3, score_threshold=detection_threshold)
86+
options = vision.ObjectDetectorOptions(
87+
base_options=base_options, detection_options=detection_options)
88+
detector = vision.ObjectDetector.create_from_options(options)
89+
90+
# Continuously capture images from the camera and run inference
91+
print("DETECTION STARTED!")
92+
print("")
93+
print(f"Detection Session: {detection_counter}")
94+
95+
# If there is multiple type of object
96+
if is_multiple:
97+
# prompt user to input its true name/label
98+
true_name = input("True label/name of the object: ")
99+
100+
while cap.isOpened():
101+
success, image = cap.read()
102+
if not success:
103+
sys.exit(
104+
'ERROR: Unable to read from webcam. Please verify your webcam settings.'
105+
)
106+
107+
counter += 1
108+
image = cv2.flip(image, 1)
109+
110+
# Convert the image from BGR to RGB as required by the TFLite model.
111+
rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
112+
113+
# Create a TensorImage object from the RGB image.
114+
input_tensor = vision.TensorImage.create_from_array(rgb_image)
115+
116+
# Run object detection estimation using the model.
117+
detection_result = detector.detect(input_tensor)
118+
119+
# If something detected on camera
120+
if (detection_result.detections and
121+
(time.time() - old_cmr_time) >= constant.LIMIT_CMR_TIME):
122+
# Record camera time
123+
cmr_time = time.time()
124+
# update old values
125+
old_cmr_time = cmr_time
126+
# Update flag
127+
print_message = True
128+
129+
# Only print result once every detection session
130+
if ((time.time() > (old_cmr_time + constant.LIMIT_DET_TIME))
131+
and (print_message)):
132+
# print messages
133+
print("Images of object has been collected.")
134+
print("")
135+
# Update counter
136+
detection_counter = detection_counter + 1
137+
frame_counter = 1
138+
print(f"Detection Session: {detection_counter}")
139+
140+
# If there is multiple type of object
141+
if is_multiple:
142+
# prompt user to input its true name/label
143+
true_name = input("True label/name of the object: ")
144+
145+
# Update flag
146+
print_message = False
147+
148+
# Draw keypoints and edges on input image if detected
149+
if detection_result.detections:
150+
image = utils.visualize(image, detection_result, (width, height),
151+
utils.detect_color(detection_result)[2])
152+
# If all images want to be collected
153+
if all_images:
154+
# Change directory and save image
155+
os.chdir(IMAGE_DIR)
156+
current_date = datetime.datetime.now()
157+
img_filename = (
158+
current_date.strftime("%d%m%Y") +
159+
"_" +
160+
utils.categorize(detection_result)[2] +
161+
"_" +
162+
str(detection_counter) +
163+
"_" +
164+
str(frame_counter) +
165+
".jpg")
166+
cv2.imwrite(img_filename, image)
167+
os.chdir(PARENT_DIR)
168+
# update counter
169+
frame_counter = frame_counter + 1
170+
else:
171+
# Collect detection that is True Positive
172+
if utils.categorize(detection_result)[2] == true_name:
173+
# Change directory and save image
174+
os.chdir(IMAGE_DIR)
175+
current_date = datetime.datetime.now()
176+
img_filename = (
177+
current_date.strftime("%d%m%Y") +
178+
"_" +
179+
true_name +
180+
"_" +
181+
str(detection_counter) +
182+
"_" +
183+
str(frame_counter) +
184+
".jpg")
185+
cv2.imwrite(img_filename, image)
186+
os.chdir(PARENT_DIR)
187+
# update counter
188+
frame_counter = frame_counter + 1
189+
else:
190+
image = utils.visualize(image, detection_result)
191+
192+
# Calculate the FPS
193+
if counter % fps_avg_frame_count == 0:
194+
end_time = time.time()
195+
fps = fps_avg_frame_count / (end_time - start_time)
196+
start_time = time.time()
197+
198+
# Show the FPS
199+
fps_text = f"FPS = {round(fps, 1)}"
200+
text_location = (x_position, y_position)
201+
utils.draw_text(img=image, text=fps_text, font_size=font_size,
202+
font_thickness=int(font_thickness), pos=text_location)
203+
204+
# Write Image to Videos
205+
out.write(image)
206+
207+
# Stop the program if the ESC key is pressed.
208+
if cv2.waitKey(1) == 27:
209+
break
210+
cv2.imshow('object_detector', image)
211+
212+
# Release everything if job is finished
213+
cap.release()
214+
out.release()
215+
cv2.destroyAllWindows()
216+
print("")
217+
print("DETECTION STOPPED!")
218+
219+
220+
def move_video(src, dst):
221+
"""Move video file to another directory.
222+
Args:
223+
src: source path for video files
224+
dst: source path for video files
225+
"""
226+
shutil.move(src, dst)
227+
228+
229+
def main():
230+
"""Main function to run detection"""
231+
parser = argparse.ArgumentParser(
232+
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
233+
parser.add_argument(
234+
'--multipleObject',
235+
help='Whether to detect single or multiple types of objects.',
236+
required=False,
237+
default=False)
238+
parser.add_argument(
239+
'--collectAll',
240+
help='Whether to collect all images or only the True Positive one.',
241+
required=False,
242+
default=False)
243+
parser.add_argument(
244+
'--trueObject',
245+
help='Name of the object to be detected if it is a single type.',
246+
required=False,
247+
type=str,
248+
default='yellow_duck')
249+
parser.add_argument(
250+
'--model',
251+
help='Path of the object detection model.',
252+
required=False,
253+
default='./model/frogducky2.tflite')
254+
parser.add_argument(
255+
'--cameraId',
256+
help='Id of camera.',
257+
required=False,
258+
type=int,
259+
default=0)
260+
parser.add_argument(
261+
'--frameWidth',
262+
help='Width of frame to capture from camera.',
263+
required=False,
264+
type=int,
265+
default=640)
266+
parser.add_argument(
267+
'--frameHeight',
268+
help='Height of frame to capture from camera.',
269+
required=False,
270+
type=int,
271+
default=480)
272+
parser.add_argument(
273+
'--numThreads',
274+
help='Number of CPU threads to run the model.',
275+
required=False,
276+
type=int,
277+
default=4)
278+
parser.add_argument(
279+
'--enableEdgeTPU',
280+
help='Whether to run the model on EdgeTPU.',
281+
action='store_true',
282+
required=False,
283+
default=False)
284+
parser.add_argument(
285+
'--detectionThreshold',
286+
help='Threshold score to be detected by model.',
287+
required=False,
288+
type=float,
289+
default=0.55)
290+
parser.add_argument(
291+
'--videoFilename',
292+
help='Name of the output video file with .mp4 extension',
293+
required=False,
294+
default='Deteksi_Objek.mp4')
295+
args = parser.parse_args()
296+
297+
run(bool(args.multipleObject),
298+
bool(args.collectAll),
299+
str(args.trueObject),
300+
args.model,
301+
int(args.cameraId),
302+
args.frameWidth,
303+
args.frameHeight,
304+
int(args.numThreads),
305+
bool(args.enableEdgeTPU),
306+
args.detectionThreshold,
307+
str(args.videoFilename))
308+
move_video(PARENT_DIR + '/' + str(args.videoFilename),
309+
VIDEO_DIR + '/' + str(args.videoFilename))
310+
311+
312+
if __name__ == '__main__':
313+
main()

0 commit comments

Comments
 (0)