-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcentre.py
More file actions
154 lines (120 loc) · 4.75 KB
/
Copy pathcentre.py
File metadata and controls
154 lines (120 loc) · 4.75 KB
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
## This contains functions which are used to find the centres from an RGB image.
## We use watershed algorithm for detecting the circles.
## The HSV values for thresholding are taken from trial and error, and are also somewhat ## dependent on external lighting conditions. The thresholded image and the image with
## centre is written as new files to help debug in the thresholding process, as the ## thresholded values are set manuall only, which is a limitation of our code.
from __future__ import division
import cv2
import numpy as np
from math import cos, sin
from skimage.feature import peak_local_max
from skimage.morphology import watershed
from scipy import ndimage
import timeit
def show(image):
#figure size in inches
plt.figure(figsize=[10,10])
plt.imshow(image, interpolation='nearest')
def overlay_mask(mask, image):
#make the mask rgb
rgb_mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2RGB)
img = cv2.addWeighted(rgb_mask, 0.2, image, 0.8, 0)
return img
def watershed_centroids(image):
## Find centroids of segments using watershed algorithm
# Apply distance transform on the binary image
D = ndimage.distance_transform_edt(image)
# find local maximas
localMax = peak_local_max(D, indices=False, min_distance=60, labels=image)
# define markers for watershed
markers = ndimage.label(localMax, structure=np.ones((3, 3)))[0]
# create lables to find unique segments
labels = watershed(-D, markers, mask=image)
print("[INFO] {} unique segments found".format(len(np.unique(labels)) - 1))
# initialise empty list to store centroids
ripe_oranges = []
# for each label/segment
for label in np.unique(labels):
if label ==0:
continue
# initialise zero matrix
mask = np.zeros(image.shape, dtype="uint8")
# copy each label into buffer variable
mask[labels == label] = 255
# find countour of the label to extract centroid
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
# take the largest countour
c = max(cnts, key=cv2.contourArea)
if cv2.contourArea(c) < 10000:
continue
# calculate moment of the contour
M = cv2.moments(c)
# calculate centroid
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
# crete list of centroids
ripe_oranges.append((cX, cY))
return ripe_oranges
def circle_centroids(image, centroids):
image_with_centroids = image.copy()
#add centroids
for centroid in centroids:
cv2.circle(image_with_centroids, centroid, 7, (0, 0, 0), -1)
return image_with_centroids
def find_orange(image):
# RGB is red green blue
# BGR is blue green red
# convert to the correct color scheme
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# clean image
image_blur = cv2.GaussianBlur(image, (21,21), 0)
# separates the color from the brightness of it. Luma from chroma.
image_blur_hsv = cv2.cvtColor(image_blur, cv2.COLOR_RGB2HSV)
# defining our filters
# filter by the color
# orange filter
min_red = np.array([9,90,80])
max_red = np.array([19,255,255])
mask1 = cv2.inRange(image_blur_hsv, min_red, max_red)
# green filter
min_green = np.array([19, 90, 60])
max_green = np.array([32, 255, 206])
mask2 = cv2.inRange(image_blur_hsv, min_green, max_green)
#combine our mas
masks = [mask1, mask2]
centroids = []
location = ['mask_orange_.jpg', 'mask_green_.jpg']
color = ['orange_centers_.jpg', 'green_centers_.jpg']
kernel1 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (17,17))
kernel2 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (31,31))
kernel = [kernel1, kernel2]
# for both the filters
for i in range(2):
# perform segmentation
# kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (25,25))
# dilation
mask_closed = cv2.morphologyEx(masks[i], cv2.MORPH_CLOSE, kernel[i])
# erosion
mask_clean = cv2.morphologyEx(mask_closed, cv2.MORPH_OPEN, kernel[i])
cv2.imwrite(location[i], cv2.cvtColor(mask_clean, cv2.COLOR_GRAY2BGR))
centers = watershed_centroids(mask_clean)
# pass thresholded image to find centroids
overlay = overlay_mask(mask_clean, image)
centroids.append(centers)
print centers
#step8 - circle the biggest orange
centroids_added = circle_centroids(overlay, centers)
#show(centroids_added)
#step9 - convert back to original color scheme
bgr = cv2.cvtColor(centroids_added, cv2.COLOR_RGB2BGR)
cv2.imwrite(color[i], bgr)
return centroids
#input_str = 'images/correct' + str(23) + '.jpg'
#image = cv2.imread('image27.jpg')
#centroids = find_orange(image)
#print centroids
# image = cv2.imread('output_images/correct3.jpg')
# centroids = find_orange(image, 31)
# print centroids
# image = cv2.imread('output_images/correct4.jpg')
# centroids = find_orange(image, 41)
# print centroids