-
Notifications
You must be signed in to change notification settings - Fork 0
/
final.py
136 lines (107 loc) · 5.19 KB
/
final.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
import math
import cv2
import imutils
import numpy as np
def grab_points(x1, y1, width_box, height_box, image):
def auto_canny(image, sigma=0.33):
# compute the median of the single channel pixel intensities
v = np.median(image)
# apply automatic Canny edge detection using the computed median
lower = int(max(0, (1.0 - sigma) * v))
upper = int(min(255, (1.0 + sigma) * v))
edged = cv2.Canny(image, lower, upper)
# return the edged image
return edged
# applies Gaussian blur and canny edge detection to the image
# parameters are the image file, the midpoint, and canny edge
# thresholds
def canny_edge(image_file, width, height):
# convert image to grayscale and run canny edge detection on it
grayscale = cv2.cvtColor(image_file, cv2.IMREAD_GRAYSCALE)
# blur the grayscale image
blurred = cv2.GaussianBlur(grayscale, (5, 5), cv2.BORDER_DEFAULT)
edge = auto_canny(grayscale)
# find contours on the grayscale image
cnts = cv2.findContours(edge, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
# apply Gaussian blur on source image
blurred = cv2.GaussianBlur(image_file, (5, 5), cv2.BORDER_DEFAULT)
# apply contrast to the blurred image
l, a, b = cv2.split(blurred)
clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8, 8))
cl = clahe.apply(l)
# -----Merge the CLAHE enhanced L-channel with the a and b channel-----------
limg = cv2.merge((cl, a, b))
# -----Converting image from LAB Color model to RGB model--------------------
final = cv2.cvtColor(limg, cv2.COLOR_LAB2BGR)
# apply edge detection to the contrast image
edge = auto_canny(final)
cv2.drawContours(edge, cnts, -1, (255, 0, 0), 5)
# add more contours to the grayscale canny image from the contrast image
cnts = cv2.findContours(edge, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)[0]
k = np.zeros(shape=[height, width, 3], dtype=np.uint8)
# Draw the largest contour on an all-black image
cv2.drawContours(k, [cnts], -1, (255, 255, 255), 1)
M = cv2.moments(cnts)
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
return k, [cX, cY]
def distance(x1, y1, x2, y2):
return math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
# uses the canny edge image and the midpoint to determine the two points
# that the robot arm needs to grab
def shortest_path(original, edge, mid_contour, w, h):
pix_val = []
half_cols = w//2
total_cols = w
total_rows = h
# range goes from halfway through the x direction and
# the whole way in the y direction
for i in range(half_cols):
for j in range(total_rows):
g = edge[j][i][1]
if g == 255:
pix_val.append([i, j])
min_distance = float("inf")
val_x1, val_y1, val_x2, val_y2 = -1, -1, -1, -1
for coor in pix_val:
col, row = coor[0], coor[1]
theta = math.atan2((mid_contour[0] - col), (mid_contour[1] - row))
for radius in range(int(min(total_rows, total_cols)/2)):
new_col = min(mid_contour[0] +
math.sin(theta)*radius, total_cols-1)
new_row = min(mid_contour[1] +
math.cos(theta)*radius, total_rows-1)
g = edge[int(new_row)][int(new_col)][1]
if g == 255:
dist = distance(new_col, new_row, col, row)
if dist < min_distance:
val_x1 = col
val_y1 = row
val_x2 = new_col
val_y2 = new_row
min_distance = dist
# changed edge to original to draw on original img
cv2.circle(original, (int(val_x1), int(val_y1)), 3, (255, 0, 255), -1)
cv2.circle(original, (int(val_x2), int(val_y2)), 3, (255, 0, 255), -1)
cv2.circle(original, (int(mid_contour[0]), int(
mid_contour[1])), 3, (255, 0, 255), -1)
cv2.circle(edge, (int(val_x1), int(val_y1)), 3, (255, 0, 255), -1)
cv2.circle(edge, (int(val_x2), int(val_y2)), 3, (255, 0, 255), -1)
cv2.circle(edge, (int(mid_contour[0]), int(
mid_contour[1])), 3, (255, 0, 255), -1)
# Uncomment to see final image/edges/grasping points!
cv2.imshow("canny with points", edge)
cv2.imshow("points", original)
cv2.waitKey(0)
return val_x1, val_y1, val_x2, val_y2, min_distance
raw_img = image
width, height = width_box, height_box
cropped_image = raw_img[y1:y1+height_box, x1:x1+width_box]
ceRet = canny_edge(cropped_image, width, height)
edge_image = ceRet[0]
shortest_x1, shortest_y1, shortest_x2, shortest_y2, shortest_dist = shortest_path(
raw_img, edge_image, ceRet[1], width, height)
return shortest_x1 + x1, shortest_y1 + y1, shortest_x2 + x1, shortest_y2 + y1, shortest_dist