Skip to content

Commit

Permalink
Updated vision
Browse files Browse the repository at this point in the history
  • Loading branch information
FadlHassan committed Apr 1, 2021
1 parent e03d4ea commit e50db5d
Show file tree
Hide file tree
Showing 112 changed files with 157 additions and 37 deletions.
Binary file modified .DS_Store
Binary file not shown.
Binary file added robopump/.DS_Store
Binary file not shown.
Binary file added robopump/controllers/.DS_Store
Binary file not shown.
Binary file modified robopump/controllers/joint_rotator_test/.DS_Store
Binary file not shown.
Binary file removed robopump/controllers/joint_rotator_test/image3.png
Binary file not shown.
Binary file added vision/fuel_hatch_detection_model/.DS_Store
Binary file not shown.
108 changes: 108 additions & 0 deletions vision/fuel_hatch_detection_model/Eclipse_detection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# USAGE
# python Eclipse_detection.py --image image.png
# About the output:
# slant: the angle that the cap rotated that we see an eclipse instead of a circle
# Centroid: the center coordinate of the cap
# phi: the angle that the eclipse rotate without change of orientation



import matplotlib.pyplot as plt
import cv2
from skimage import color, img_as_ubyte
from skimage.feature import canny
from skimage.transform import hough_ellipse
from skimage.draw import ellipse_perimeter
import numpy as np
import argparse


# For calculate the diameter of the circle form the eclipse
def find_phi(xs,ys,cx,cy):
max = 0
max_X = 0
max_Y = 0

for i in range(len(xs)):
distance = np.power(xs[i]-cx,2)+np.power(ys[i]-cy,2)
if distance>max:
max = distance
max_X = xs[i]
max_Y = ys[i]
# print("inner_find_phi, the radian is: ", np.sqrt(np.power(max_X-cx,2)+np.power(max_Y-cy,2)))
# print("max_Y,max_X=",max_Y,max_X)

slant = np.arctanh((max_Y-cy)/(max_X-cx))
return slant



def get_cap_info(image_rgb):
# convert to grayscale and detect edges
gray = cv2.cvtColor(image_rgb, cv2.COLOR_BGR2GRAY)
thresh_for_bar = cv2.threshold(gray, 30, 255, cv2.THRESH_BINARY)[1]
edges = canny(thresh_for_bar, sigma=2.0,
low_threshold=0.55, high_threshold=0.8)

# cv2.imshow('tianbu',gray)
# cv2.waitKey(0)

# Perform a Hough Transform
# The accuracy corresponds to the bin size of a major axis.
# The value is chosen in order to get a single high accumulator.
# The threshold eliminates low accumulators
result = hough_ellipse(edges, accuracy=21, threshold=1,
min_size=1, max_size=None)
# print('sorting start')
result.sort(order='accumulator')
# print('sorting finished')
# Estimated parameters for the ellipse
best = list(result[-1])
yc, xc, a, b = [int(round(x)) for x in best[1:5]]
orientation = best[5]

slant = np.arccos(min(a,b)/max(a,b))
print("slant = ",slant)

print("Centroid = ","[",xc,",",yc,"]")
# print("longest_radius=",a," shortest_radius=",b)


cy, cx = ellipse_perimeter(yc, xc, a, b, orientation)

# phi value of a rotated eclipse
if np.abs(a-b)>2:
phi = find_phi(cx,cy,xc,yc)
print("phi = ",phi)
else:
print("phi = 0")
######
# Draw the ellipse on the original image
#image_rgb[cy, cx] = (0, 0, 255)
# # Draw the edge (white) and the resulting ellipse (red)
edges = color.gray2rgb(img_as_ubyte(edges))
edges[cy, cx] = (250, 0, 0)

fig2, (ax1, ax2) = plt.subplots(ncols=2, nrows=1, figsize=(8, 4),
sharex=True, sharey=True)
ax1.set_title('Original picture')
ax1.imshow(image_rgb)
ax2.set_title('Edge (white) and result (red)')
ax2.imshow(edges)
plt.show()


return slant, phi, [xc,yc]
######

# construct the argument parse and parse the arguments
# ap = argparse.ArgumentParser()
# ap.add_argument("-i", "--image", required=True,
# help="path to the input image")
# args = vars(ap.parse_args())

# # load the image and resize it to a smaller factor so that
# # the shapes can be approximated better
# image = cv2.imread(args["image"])

# get_cap_info(image)
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ def visualize_boxes_and_labels_on_image_array(
for i in range(boxes.shape[0]):
if max_boxes_to_draw == len(box_to_color_map):
break
if scores is None or scores[i] == max:
if scores is None or (scores[i] == max and scores[i]>min_score_thresh):
box = tuple(boxes[i].tolist())
if instance_masks is not None:
box_to_instance_masks_map[box] = instance_masks[i]
Expand Down Expand Up @@ -426,7 +426,7 @@ def return_coordinates(
for i in range(boxes.shape[0]):
if max_boxes_to_draw == len(box_to_color_map):
break
if scores is None or scores[i] == max:
if scores is None or (scores[i] == max and scores[i]>min_score_thresh):
box = tuple(boxes[i].tolist())
if instance_masks is not None:
box_to_instance_masks_map[box] = instance_masks[i]
Expand Down Expand Up @@ -504,7 +504,7 @@ def run(image_path):
category_index,
use_normalized_coordinates=True,
line_thickness=8,
min_score_thresh=0.50)
min_score_thresh=0.75)

coordinates = return_coordinates(
image_np,
Expand All @@ -514,27 +514,37 @@ def run(image_path):
category_index,
use_normalized_coordinates=True,
line_thickness=8,
min_score_thresh=0.50)
min_score_thresh=0.75)
#Need to edit path to output coordinates directory
img_coords = []
if(len(coordinates)!=0):
try:
with open("output/output_coordinates.txt","w") as file:
for item in coordinates[0]:
img_coords.append(item)
file.write("%s\n" % item)
#Need to edit path to output images directory
# img_coords[0] = img_coords[0]-40
# img_coords[1] = img_coords[1]-40
# img_coords[2] = img_coords[2]+40
# img_coords[3] = img_coords[3]+40

im= Image.fromarray(image_np)
new_im = im.resize((1000, 1000))
new_im.save("output/output_image.png")
return image,image_np,img_coords
except IndexError:
return None
#Need to edit path to output images directory
# plt.figure(figsize=IMAGE_SIZE)
# plt.xticks([])
# plt.yticks([])
# plt.imshow(image_np) # matplotlib is configured for command line only so we save the outputs instead
# plt.savefig("output/output_image.png") # create an outputs folder for the images to be saved


im= Image.fromarray(image_np)
new_im = im.resize((1000, 1000))
new_im.save("output/output_image.png")
# im= Image.fromarray(image_np)
# new_im = im.resize((1000, 1000))
# new_im.save("output/output_image.png")

return image_np,img_coords



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ def find_shape(img):
# if slant_angle == 0:
# left_high = True
# if Xmin_y-Ymin < Xmax_y- Ymin
actualContour = [[[Xmin,Xmin_y]],[[Ymin_x,Ymin]],[[Xmax,Xmax_y]],[[Ymax_x,Ymax]]]
# actualContour = [[[Xmin,Xmin_y]],[[Ymin_x,Ymin]],[[Xmax,Xmax_y]],[[Ymax_x,Ymax]]]
actualContour = [[Xmin,Xmin_y],[Ymin_x,Ymin],[Xmax,Xmax_y],[Ymax_x,Ymax]]
print("Vertice (pixel):",actualContour)
print("Centroid (pixel):(",cX,",",cY,")")
angle = np.arctan((Xmin_y-Ymin)/(Xmax-Ymax_x))
Expand All @@ -148,10 +149,10 @@ def find_shape(img):
c = c.astype("float")
c *= rat
c = c.astype("int")
cv2.drawContours(img, [c], -1, (0, 255, 0), 2)
cv2.drawContours(img, [c], -1, (0, 255, ), 2)

cv2.putText(img, shape, (cX, cY), cv2.FONT_HERSHEY_SIMPLEX,
0.5, (255, 255, 255), 2)
cv2.putText(img, shape, (cX, cY), cv2.FONT_HERSHEY_SIMPLEX,
2, (255, 255, 255), 2)

# show the output image
cv2.imwrite("output/fuel_cap.jpg", img)
Expand All @@ -160,6 +161,14 @@ def find_shape(img):
detect_circle = 1
print("Found the cap!")
return actualContour, (cX,cY), width, angle


# try:
# if shape != "circle":
# raise CapNotFoundError
# break
# except CapNotFoundError:
# print("This value is too small, try again!")

# # construct the argument parse and parse the arguments
# ap = argparse.ArgumentParser()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,49 +9,42 @@

def detect_fuel_cap(image_path):

try:
image_np, img_coords = cm.run(image_path)
img = Image.fromarray(image_np)
crop_img = np.array(img.crop((img_coords[1], img_coords[0], img_coords[3], img_coords[2])))
try:
image, image_np, img_coords = cm.run(image_path)
#img = Image.fromarray(image_np)
crop_img = np.array(image.crop((img_coords[1], img_coords[0], img_coords[3], img_coords[2])))
#crop_img = image_np[img_coords[0]:img_coords[2], img_coords[1]:img_coords[3]]
cv2.imwrite("output/cropped.png", crop_img)
except:
print('Hatch has not been found')
return

try:
pass
#vertices, centroid, width, rotate_angle = ds.find_shape(crop_img)
except Exception as e:
print(e)
return
# try:
# vertices, centroid, width, rotate_angle = ds.find_shape(crop_img)
# except Exception as e:
# print("Okay")
# return


try:
pass
#slant, phi = ed.get_cap_info(crop_img)
slant, phi,centroid = ed.get_cap_info(crop_img)
except:
print('Slant and Phi can not be calculated')
return
print('Slant and Phi can not be calculated')
return

print('Fuel cap found')
print('Fuel cap found')
file = open("fuel_cap_coordinates.txt", "w")
'''
file.write("%s\n" % slant)
file.write("%s\n" % phi)
file.write("%s\n" % vertices)
file.write("{} {}\n".format(centroid[0],centroid[1]))
file.write("%s\n" % width)
file.write("%s\n" % rotate_angle)
'''
# file.write("%s\n" % vertices)
# file.write("%s\n" % width)
# file.write("%s\n" % rotate_angle)

return img_coords

'''
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,
help="path to the input image")
args = vars(ap.parse_args())

detect_fuel_cap(args["image"])
'''

0 comments on commit e50db5d

Please sign in to comment.