|
| 1 | +######## Object counting using tensorflow on picamera ######### |
| 2 | +# Author: Vineeth Rajendran |
| 3 | +# Date: 4/1/19 |
| 4 | +# Description: |
| 5 | +# This program uses a TensorFlow classifier to perform object detection and counting. |
| 6 | +# It draws boxes and scores around the objects of interest in each frame from the picamera. |
| 7 | +# IT also uses a variable for counting the no. of objects in the frame. |
| 8 | + |
| 9 | +## Some of the code is copied from Evan Juras example at |
| 10 | +## https://github.com/EdjeElectronics/TensorFlow-Object-Detection-on-the-Raspberry-Pi/blob/master/Object_detection_picamera.py |
| 11 | + |
| 12 | + |
| 13 | +# Import packages |
| 14 | +import os |
| 15 | +import cv2 |
| 16 | +import numpy as np |
| 17 | +from picamera.array import PiRGBArray |
| 18 | +from picamera import PiCamera |
| 19 | +import tensorflow as tf |
| 20 | +import argparse |
| 21 | +import sys |
| 22 | + |
| 23 | +# Set up camera constants |
| 24 | +IM_WIDTH = 1280 |
| 25 | +IM_HEIGHT = 720 |
| 26 | +#IM_WIDTH = 640 Use smaller resolution for |
| 27 | +#IM_HEIGHT = 480 slightly faster framerate |
| 28 | + |
| 29 | +# Select camera type (if user enters --usbcam when calling this script, |
| 30 | +# a USB webcam will be used) |
| 31 | +camera_type = 'picamera' |
| 32 | +parser = argparse.ArgumentParser() |
| 33 | +parser.add_argument('--usbcam', help='Use a USB webcam instead of picamera', |
| 34 | + action='store_true') |
| 35 | +args = parser.parse_args() |
| 36 | +if args.usbcam: |
| 37 | + camera_type = 'usb' |
| 38 | + |
| 39 | +# This is needed since the working directory is the object_detection folder. |
| 40 | +sys.path.append('..') |
| 41 | + |
| 42 | +# Import utilites |
| 43 | +from utils import label_map_util |
| 44 | +from utils import visualization_utils as vis_util |
| 45 | + |
| 46 | +# Name of the directory containing the object detection module we're using |
| 47 | +MODEL_NAME = 'ssdlite_mobilenet_v2_coco_2018_05_09' |
| 48 | + |
| 49 | +# Grab path to current working directory |
| 50 | +CWD_PATH = os.getcwd() |
| 51 | + |
| 52 | +# Path to frozen detection graph .pb file, which contains the model that is used |
| 53 | +# for object detection. |
| 54 | +PATH_TO_CKPT = os.path.join(CWD_PATH,MODEL_NAME,'frozen_inference_graph.pb') |
| 55 | + |
| 56 | +# Path to label map file |
| 57 | +PATH_TO_LABELS = os.path.join(CWD_PATH,'data','mscoco_label_map.pbtxt') |
| 58 | + |
| 59 | +# Number of classes the object detector can identify |
| 60 | +NUM_CLASSES = 90 |
| 61 | + |
| 62 | +## Load the label map. |
| 63 | +# Label maps map indices to category names, so that when the convolution |
| 64 | +# network predicts `5`, we know that this corresponds to `airplane`. |
| 65 | +# Here we use internal utility functions, but anything that returns a |
| 66 | +# dictionary mapping integers to appropriate string labels would be fine |
| 67 | +label_map = label_map_util.load_labelmap(PATH_TO_LABELS) |
| 68 | +categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=NUM_CLASSES, use_display_name=True) |
| 69 | +category_index = label_map_util.create_category_index(categories) |
| 70 | + |
| 71 | +# Load the Tensorflow model into memory. |
| 72 | +detection_graph = tf.Graph() |
| 73 | +with detection_graph.as_default(): |
| 74 | + od_graph_def = tf.GraphDef() |
| 75 | + with tf.gfile.GFile(PATH_TO_CKPT, 'rb') as fid: |
| 76 | + serialized_graph = fid.read() |
| 77 | + od_graph_def.ParseFromString(serialized_graph) |
| 78 | + tf.import_graph_def(od_graph_def, name='') |
| 79 | + |
| 80 | + sess = tf.Session(graph=detection_graph) |
| 81 | + |
| 82 | + |
| 83 | +# Define input and output tensors (i.e. data) for the object detection classifier |
| 84 | + |
| 85 | +# Input tensor is the image |
| 86 | +image_tensor = detection_graph.get_tensor_by_name('image_tensor:0') |
| 87 | + |
| 88 | +# Output tensors are the detection boxes, scores, and classes |
| 89 | +# Each box represents a part of the image where a particular object was detected |
| 90 | +detection_boxes = detection_graph.get_tensor_by_name('detection_boxes:0') |
| 91 | + |
| 92 | +# Each score represents level of confidence for each of the objects. |
| 93 | +# The score is shown on the result image, together with the class label. |
| 94 | +detection_scores = detection_graph.get_tensor_by_name('detection_scores:0') |
| 95 | +detection_classes = detection_graph.get_tensor_by_name('detection_classes:0') |
| 96 | + |
| 97 | +# Number of objects detected |
| 98 | +num_detections = detection_graph.get_tensor_by_name('num_detections:0') |
| 99 | + |
| 100 | +# creating a fucntion |
| 101 | +def object_counting() |
| 102 | + # Initialize Picamera and grab reference to the raw capture |
| 103 | + camera = PiCamera() |
| 104 | + camera.resolution = (IM_WIDTH,IM_HEIGHT) |
| 105 | + camera.framerate = 10 |
| 106 | + rawCapture = PiRGBArray(camera, size=(IM_WIDTH,IM_HEIGHT)) |
| 107 | + rawCapture.truncate(0) |
| 108 | + |
| 109 | + for frame1 in camera.capture_continuous(rawCapture, format="bgr",use_video_port=True): |
| 110 | + |
| 111 | + totalcount=0 |
| 112 | + |
| 113 | + # Acquire frame and expand frame dimensions to have shape: [1, None, None, 3] |
| 114 | + # i.e. a single-column array, where each item in the column has the pixel RGB value |
| 115 | + frame = np.copy(frame1.array) |
| 116 | + frame.setflags(write=1) |
| 117 | + frame_expanded = np.expand_dims(frame, axis=0) |
| 118 | + |
| 119 | + # Perform the actual detection by running the model with the image as input |
| 120 | + (boxes, scores, classes, num) = sess.run( |
| 121 | + [detection_boxes, detection_scores, detection_classes, num_detections], |
| 122 | + feed_dict={image_tensor: frame_expanded}) |
| 123 | + |
| 124 | + # Visualizing the results of the detection |
| 125 | + vis_util.visualize_boxes_and_labels_on_image_array( |
| 126 | + frame, |
| 127 | + np.squeeze(boxes), |
| 128 | + np.squeeze(classes).astype(np.int32), |
| 129 | + np.squeeze(scores), |
| 130 | + category_index, |
| 131 | + use_normalized_coordinates=True, |
| 132 | + line_thickness=8, |
| 133 | + min_score_thresh=0.40) |
| 134 | + |
| 135 | + # Updating totalcount |
| 136 | + totalcount=totalcount+num |
| 137 | + |
| 138 | + # Displaying the number of objects detected using the totalcount variable |
| 139 | + cv2.putText(frame,"Count"+str(totalcount) ,(10, 35),font,0.8,(0, 0xFF, 0xFF),2,cv2.FONT_HERSHEY_SIMPLEX,) |
| 140 | + |
| 141 | + # All the results have been drawn on the frame, so it's time to display it. |
| 142 | + cv2.imshow('Object detector', frame) |
| 143 | + |
| 144 | + # Press 'q' to quit |
| 145 | + if cv2.waitKey(1) == ord('q'): |
| 146 | + break |
| 147 | + |
| 148 | + rawCapture.truncate(0) |
| 149 | + |
| 150 | + camera.close() |
| 151 | + |
| 152 | +cv2.destroyAllWindows() |
| 153 | + |
| 154 | +object_counting() |
| 155 | + |
0 commit comments