Skip to content

Commit

Permalink
First working version
Browse files Browse the repository at this point in the history
First working version of component Detector with ipython notebook example included
  • Loading branch information
gayathrimahalingam committed Jul 31, 2017
1 parent d932eac commit 6818557
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 48 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
README.md filter=lfs diff=lfs merge=lfs -text
__init__.py filter=lfs diff=lfs merge=lfs -text
*.caffemodel filter=lfs diff=lfs merge=lfs -text
2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1 +1 @@
recursive-include detector/models
recursive-include detector/models *.*
9 changes: 6 additions & 3 deletions detector/componentDetector.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from PIL import Image, ImageDraw, ImageFont
import argparse
import cv2
import copy, time
import copy, time, math
from . import config

sys.path.insert(0, os.path.join(config.caffe_root, 'python'))
Expand Down Expand Up @@ -53,10 +53,11 @@ def detect(self, image, minComponentSize):
# sliding window
total_boxes = []

print("Computing bounding boxes")
start1 = time.time()
for (x,y,imw) in sliding_window(ims, (515, 515), (minComponentSize, minComponentSize)):
# pass the image window to the classifier network
out = net_full_conv.forward_all(data=np.asarray([transformer.preprocess('data', imw)]))
out = self.net_full_conv.forward_all(data=np.asarray([self.transformer.preprocess('data', imw)]))

# get the probability matrix associated with class 1 (IC here)
outprob = out['prob'][0,1]
Expand Down Expand Up @@ -90,15 +91,17 @@ def detect(self, image, minComponentSize):
end1 = time.time()
#print "Total time take for this image: " % (end1-start1)

print("Performing Non-Maxima Suppression")
# perform nms for the entire set of boxes
boxes_nms = np.array(total_boxes)
true_boxes = nms_max(boxes_nms, overlapThresh=0.2)


print("Clustering bounding boxes")
# Cluster the overlapping bounding boxes
clusters = clusterBoxes(true_boxes)
fCluster = getAvgClusterBoxes(clusters)

print("Finding enclosing boxes")
# group enclosed boxes
finalBoxes = enclosingBoxes(fCluster)

Expand Down
4 changes: 2 additions & 2 deletions detector/helperModules.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,8 @@ def loadNet(deployProto, fullConvProto, caffeModel, mode='CPU'):

conv_params = {pr: (net_full_conv.params[pr][0].data, net_full_conv.params[pr][1].data) for pr in params_full_conv}

for conv in params_full_conv:
print '{} weights are {} dimensional and biases are {} dimensional'.format(conv, conv_params[conv][0].shape, conv_params[conv][1].shape)
#for conv in params_full_conv:
# print '{} weights are {} dimensional and biases are {} dimensional'.format(conv, conv_params[conv][0].shape, conv_params[conv][1].shape)

for pr, pr_conv in zip(cfg.params, params_full_conv):
conv_params[pr_conv][0].flat = fc_params[pr][0].flat # flat unrolls the arrays
Expand Down
33 changes: 16 additions & 17 deletions detector/nms.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@


def match_score(b1, b2):
# sum of the distance between centers of the two bounding
# sum of the distance between centers of the two bounding
# boxes and the intersection area of the boxes

# calculate the centers
xc1 = (b1[0]+b1[2]) / 2
yc1 = (b1[1]+b1[3]) / 2
Expand All @@ -22,22 +22,22 @@ def match_score(b1, b2):
area = dx*dy
else:
area = 0

return dist+area

#def box_merge(b1, b2):


def combine_boxes(boxes, overlapThresh=0.07):
# Combines boxes across scales
if len(boxes) == 0:
return []
# Bs - set of bounding boxes predicted by the regressor network

# Bs - set of bounding boxes predicted by the regressor network
# for each class in Cs across all spatial locations at scale s
# In our case it the boxes variable itself



def nms_max(boxes, overlapThresh=0.3):
if len(boxes) == 0:
Expand Down Expand Up @@ -74,15 +74,15 @@ def nms_max(boxes, overlapThresh=0.3):
# compute the width and height of the bounding box
w = np.maximum(0, xx2 - xx1 + 1)
h = np.maximum(0, yy2 - yy1 + 1)

# area of i.
area_i = np.maximum(0, x2[i] - x1[i] + 1) * np.maximum(0, y2[i] - y1[i] + 1)
area_array = np.zeros(len(idxs) - 1)
area_array.fill(area_i)

# compute the ratio of overlap
overlap = (w * h) / (area[idxs[:last]] - w * h + area_array)

# delete all indexes from the index list that have
idxs = np.delete(idxs, np.concatenate(([last],np.where(overlap > overlapThresh)[0])))

Expand All @@ -94,7 +94,7 @@ def nms_average(boxes, overlapThresh=0.2):
result_boxes = []
if len(boxes) == 0:
return []

# initialize the list of picked indexes
pick = []

Expand All @@ -117,7 +117,7 @@ def nms_average(boxes, overlapThresh=0.2):
i = idxs[last]
pick.append(i)

# find the largest (x, y) coordinates for the start of the bounding box
# find the largest (x, y) coordinates for the start of the bounding box
# and the smallest (x, y) coordinates for the end of the bounding box
xx1 = np.maximum(x1[i], x1[idxs[:last]])
yy1 = np.maximum(y1[i], y1[idxs[:last]])
Expand All @@ -127,15 +127,15 @@ def nms_average(boxes, overlapThresh=0.2):
# compute the width and height of the bounding box
w = np.maximum(0, xx2 - xx1 + 1)
h = np.maximum(0, yy2 - yy1 + 1)

# area of i.
area_i = np.maximum(0, x2[i] - x1[i] + 1) * np.maximum(0, y2[i] - y1[i] + 1)
area_array = np.zeros(len(idxs) - 1)
area_array.fill(area_i)

# compute the ratio of overlap
overlap = (w * h) / (area[idxs[:last]])

delete_idxs = np.concatenate(([last],np.where(overlap > overlapThresh)[0]))
# print "delete_idxs:", delete_idxs
xmin = 10000
Expand Down Expand Up @@ -165,12 +165,11 @@ def nms_average(boxes, overlapThresh=0.2):
xmax = x2[i] + 0.1 * width
if( ymax - y2[i] > 0.1 * height):
ymax = y2[i] + 0.1 * height

result_boxes.append([xmin, ymin, xmax, ymax, ave_prob / len(delete_idxs)])

# delete all indexes from the index list that have
idxs = np.delete(idxs, delete_idxs)

# return only the bounding boxes that were picked using the integer data type
return result_boxes

5 changes: 2 additions & 3 deletions detector/windowExtractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@
def getWindowDims(image, winSize=[cfg.winSize, cfg.winSize], stride=[cfg.stride,cfg.stride]):
# This function returns the bounding boxes for each window in the given image
windows = []

for y in xrange(0, image.shape[0]-winSize[0], stride[0]):
for x in xrange(0, image.shape[1]-winSize[1], stride[1]):
windows.append([x, y, winSize[0], winSize[1]]) # row, col, width, height

return windows

def extractSubWindows(image, windows, transformer):
# This function extracts the subwindows and puts it in the format required by caffe for batch processing.
# This function extracts the subwindows and puts it in the format required by caffe for batch processing.
# Each window is of the same size

subWindows = np.zeros(np.array([len(windows), 3, windows[0][2], windows[0][3]]))
Expand All @@ -45,4 +45,3 @@ def extractSubImages(image, windows):
subWindows[i] = image[y:y+h, x:x+w]

return subWindows

53 changes: 36 additions & 17 deletions examples/IC_Detector.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -13,48 +13,58 @@
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
"import sys\n",
"import os\n",
"import matplotlib.pyplot as plt\n",
"import cv2\n",
"import config\n",
"import caffe\n",
"\n",
"from detector import componenetDetector as cd"
"from detector import componentDetector as cd\n",
"from detector import helperModules"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[['images/A029F090.jpg', '59']]\n"
]
}
],
"source": [
"# load the image list file - format is full_image_path \\t min_ic_size\n",
"\n",
"imglist = 'imagelist.txt'\n",
"\n",
"with open(imglist, 'r') as f:\n",
" lol = [x.strip().split(',') for x in f]\n",
" lol = [x.strip().split('\\t') for x in f]\n",
"\n",
"print lol"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Computing bounding boxes\n"
]
}
],
"source": [
"# Initialize the detector\n",
"icDetector = cd.componentDetector(\"ic\", \"gpu\")\n",
Expand All @@ -73,6 +83,15 @@
" helperModules.drawBoundingBoxes(im, boundingBoxes, \"Detected Image\")\n",
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
Expand All @@ -91,7 +110,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.13"
"version": "2.7.6"
}
},
"nbformat": 4,
Expand Down
11 changes: 6 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#from distutils.core import setup
from setuptools import setup, find_packages
from distutils.core import setup
#from setuptools import setup, find_packages
import os

datadir = 'models'
datadir = 'detector/models'
datafiles = [(d, [os.path.join(d,f) for f in files])
for d, folders, files in os.walk(datadir)]

Expand All @@ -15,9 +15,10 @@
version='0.1dev0',
author='Gayathri Mahalingam, Kevin Marshall Gay',
author_email='[email protected]',
packages=find_packages(),
package_data={'detector':datafiles},
packages=['detector'],
package_data={'detector':['models/ic/*', 'models/resistor/*', 'models/capacitor/*']},
include_package_data=True,
data_files=datafiles,
install_requires=required,
setup_requires=[],
tests_require=[],
Expand Down

0 comments on commit 6818557

Please sign in to comment.