-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdetect_objects.py
executable file
·208 lines (153 loc) · 5.47 KB
/
detect_objects.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
'''
INFORMATION
===========
This script detects objects in images using Mask r-CNN pre-trained on COCO
dataset. It requires that you have a pickled dataframe with paths to images
stored and installed Mask r-CNN (see below) with the appropriate weights and
labels files.
The script outputs a pickled dataframe containing object detections, confidences
unique objects and object counts.
USAGE
=====
Run this script by typing:
python detect_objects.py -w file.h5 -l file.txt -i input.pkl -o output.pkl
NOTES
=====
This script is a lightly modified version of the Mask r-CNN scripts
from https://www.pyimagesearch.com/2019/06/10/keras-mask-r-cnn/ to better
suit the purposes of our article.
Running this script with a GPU is recommended as it speeds up the detection
considerably.
INSTALL MASK R-CNN
==================
To use this script you have to clone and install the Mask r-CNN repository
by typing:
git clone https://github.com/matterport/Mask_RCNN.git
cd Mask_RCNN
python setup.py install
@author: Adrian Rosebrock of PyImageSearch, Tuomas Väisänen
'''
# import the necessary packages
from mrcnn.config import Config
from mrcnn import model as modellib
import pandas as pd
import progressbar
import colorsys
import argparse
import imutils
import random
import cv2
import os
# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-w", "--weights", required=True,
help="path to Mask R-CNN model weights pre-trained on COCO")
ap.add_argument("-l", "--labels", required=True,
help="path to class labels file")
ap.add_argument("-i", "--input", required=True,
help="path to input dataframe to apply Mask R-CNN to")
ap.add_argument("-o", "--output", required=True,
help="path to output pickle")
args = vars(ap.parse_args())
# load the class label names from disk, one label per line
CLASS_NAMES = open(args['labels']).read().strip().split("\n")
# generate random (but visually distinct) colors for each class label
# (thanks to Matterport Mask R-CNN for the method!)
hsv = [(i / len(CLASS_NAMES), 1, 1.0) for i in range(len(CLASS_NAMES))]
COLORS = list(map(lambda c: colorsys.hsv_to_rgb(*c), hsv))
random.seed(42)
random.shuffle(COLORS)
# configuration of Mask r-CNN
class SimpleConfig(Config):
# give the configuration a recognizable name
NAME = "coco_inference"
# set the number of GPUs to use along with the number of images
# per GPU
GPU_COUNT = 1
IMAGES_PER_GPU = 1
# number of classes (we would normally add +1 for the background
# but the background class is *already* included in the class
# names)
NUM_CLASSES = len(CLASS_NAMES)
# initialize the inference configuration
config = SimpleConfig()
# initialize the Mask R-CNN model for inference and then load the weights
print("[INFO] - loading Mask R-CNN model...")
model = modellib.MaskRCNN(mode="inference", config=config,
model_dir=os.getcwd())
model.load_weights(args['weights'], by_name=True)
# read pickle in
df = pd.read_pickle(args['input'])
# reset index from umap clustering
df = df.reset_index(drop=True)
# grab list of imagepaths
print('[INFO] - Loading image paths..')
imagePaths = df['imagepath'].values.tolist()
# initialize progressbar widgets
widgets = ['Predicting objects: ',
progressbar.Percentage(),' ', progressbar.Bar(), ' ', progressbar.ETA()]
# start progressbar
pbar = progressbar.ProgressBar(maxval=len(df), widgets=widgets).start()
# empty list for predictions
predprobs = []
# loop over images in batches
for i in range(len(imagePaths)):
# get path of image
imagePath = df['imagepath'][i]
# load input image
image = cv2.imread(imagePath)
# convert color scheme to RGB
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# resize to 512 x 512
image = imutils.resize(image, width=512)
# detect objects in image
predictions = model.detect([image])
# loop predictions
for pred in predictions:
# empty list for detected objects
objects = []
# get detected objects and append to list
for c in pred['class_ids']:
obj = CLASS_NAMES[c]
objects.append(obj)
# empty list for prediction confidences
probs = []
# get detection confidences and append to list
for p in pred['scores']:
probs.append(p)
# combine detections with confidences and append to list
preds = list(zip(objects, probs))
predprobs.append(preds)
# update progress
pbar.update(i)
# save predictions to dataframe
df['obj_preds'] = predprobs
# finish progressbar
pbar.finish()
print("[INFO] - Object detection done!")
# count objects per picture
print("[INFO] - Saving detection results to dataframe...")
for i, row in df.iterrows():
df.at[i, 'obj_count'] = len(row['obj_preds'])
# empty list for detected objects
detobjs = []
# get objects and append to list
for i, row in df.iterrows():
objs = [x[0] for x in row['obj_preds']]
detobjs.append(objs)
# save detected objects to dataframe
df['detected_objs'] = detobjs
# empty list for unique objects
uniqlist = []
# get unique objects and append to list
for i, row in df.iterrows():
uniq = set(row['detected_objs'])
uniqlist.append(uniq)
# save unique objects to dataframe
df['unique_objs'] = uniqlist
# count unique objects per picture
for i, row in df.iterrows():
df.at[i, 'unique_obj_count'] = len(row['unique_objs'])
# save dataframe
df.to_pickle(args['output'])
print("[INFO] - ... done!")