Browse Source

cleaned up opticalSensor.py

subDesTagesMitExtraKaese 3 years ago
parent
commit
c56c7b9dfe
1 changed files with 30 additions and 13 deletions
  1. 30 13
      raspberry-pi/sensors/opticalSensor.py

+ 30 - 13
raspberry-pi/sensors/opticalSensor.py

@@ -30,13 +30,21 @@ parameters =  aruco.DetectorParameters_create()
 
 
 
 
 def find_marker(image, debug=True):
 def find_marker(image, debug=True):
-    # Our operations on the frame come here
   gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
   gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
   if debug:
   if debug:
     image[:,:,0] = gray
     image[:,:,0] = gray
     image[:,:,1] = gray
     image[:,:,1] = gray
     image[:,:,2] = gray
     image[:,:,2] = gray
   corners, ids, rejectedImgPoints = aruco.detectMarkers(gray, aruco_dict, parameters=parameters)
   corners, ids, rejectedImgPoints = aruco.detectMarkers(gray, aruco_dict, parameters=parameters)
+
+  if debug:
+    for corner in rejectedImgPoints:
+      print(corner)
+      c = corner[0]
+      cv2.line(image, tuple(c[0]), tuple(c[1]), (0, 255, 255), 1)
+      cv2.line(image, tuple(c[1]), tuple(c[2]), (0, 255, 255), 1)
+      cv2.line(image, tuple(c[2]), tuple(c[3]), (0, 255, 255), 1)
+      cv2.line(image, tuple(c[3]), tuple(c[0]), (0, 255, 255), 1)
   
   
   markers = [None] * 4
   markers = [None] * 4
 
 
@@ -44,12 +52,13 @@ def find_marker(image, debug=True):
     return markers
     return markers
 
 
   for corner, id in zip(corners, ids.flatten()):
   for corner, id in zip(corners, ids.flatten()):
-    # draw the bounding box of the ArUCo detection
+    # calculate the average of all 4 corners
     c = corner[0]
     c = corner[0]
     cX = sum(c[:,0]) / 4
     cX = sum(c[:,0]) / 4
     cY = sum(c[:,1]) / 4
     cY = sum(c[:,1]) / 4
 
 
     if debug:
     if debug:
+      # draw the bounding box of the ArUCo detection
       cv2.line(image, tuple(c[0]), tuple(c[1]), (0, 255, 0), 2)
       cv2.line(image, tuple(c[0]), tuple(c[1]), (0, 255, 0), 2)
       cv2.line(image, tuple(c[1]), tuple(c[2]), (0, 255, 0), 2)
       cv2.line(image, tuple(c[1]), tuple(c[2]), (0, 255, 0), 2)
       cv2.line(image, tuple(c[2]), tuple(c[3]), (0, 255, 0), 2)
       cv2.line(image, tuple(c[2]), tuple(c[3]), (0, 255, 0), 2)
@@ -67,8 +76,9 @@ def measureDistances(image, debug=True):
     markers = find_marker(image, debug)
     markers = find_marker(image, debug)
 
 
     if markers[0] and markers[1]:
     if markers[0] and markers[1]:
-      
+      # the distance between marker 0 and marker 1
       distance = np.sqrt((markers[0][0]-markers[1][0])**2 + (markers[0][1]-markers[1][1])**2)
       distance = np.sqrt((markers[0][0]-markers[1][0])**2 + (markers[0][1]-markers[1][1])**2)
+      # the center point between marker 0 and 1
       centerX = (markers[0][0]+markers[1][0])/2
       centerX = (markers[0][0]+markers[1][0])/2
       centerY = (markers[0][1]+markers[1][1])/2
       centerY = (markers[0][1]+markers[1][1])/2
 
 
@@ -80,6 +90,7 @@ def measureDistances(image, debug=True):
         cv2.putText(image, "%.2fpx" % (distance), (int(markers[0][0]), int(markers[0][1]+25)), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 255), 3)
         cv2.putText(image, "%.2fpx" % (distance), (int(markers[0][0]), int(markers[0][1]+25)), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 255), 3)
         cv2.putText(image, "%.2fpx" % (centerX) , (25, 50), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 255), 3)
         cv2.putText(image, "%.2fpx" % (centerX) , (25, 50), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 255), 3)
         
         
+      # normalize pixels to percent of horizontal resolution
       return centerX/image.shape[1], distance/image.shape[1]
       return centerX/image.shape[1], distance/image.shape[1]
 
 
     else:
     else:
@@ -97,16 +108,14 @@ class OpticalSensor():
     self.x_offset               = float(conf["opt_sensor"]["x_offset"])
     self.x_offset               = float(conf["opt_sensor"]["x_offset"])
     self.fov                    = float(conf["opt_sensor"]["fov"])
     self.fov                    = float(conf["opt_sensor"]["fov"])
     self.log_handler            = logHandler.get_log_handler()
     self.log_handler            = logHandler.get_log_handler()
-    self._t  = None
+    self.showImage              = conf["opt_sensor"]["debug_image"] == "yes"
+    self._thread  = threading.Thread(target=self._getFrames, args=())
     self.success = False
     self.success = False
     self.running = True
     self.running = True
-    self.showImage = True
 
 
   def start(self):
   def start(self):
     self.log_handler.log_and_print("start optical sensor")
     self.log_handler.log_and_print("start optical sensor")
-    if not self._t:
-      self._t = threading.Thread(target=self._getFrames, args=())
-      self._t.start()
+    self._thread.start()
 
 
   def _getFrames(self):
   def _getFrames(self):
     try:
     try:
@@ -125,7 +134,7 @@ class OpticalSensor():
           if position != None:
           if position != None:
             self.pass_to_gui(position + values)
             self.pass_to_gui(position + values)
         if self.showImage:
         if self.showImage:
-          cv2.imshow("image", image)
+          cv2.imshow("Camera capture with ARUCO detection", image)
           if cv2.waitKey(1) & 0xFF == ord('q'):
           if cv2.waitKey(1) & 0xFF == ord('q'):
             self.showImage = False
             self.showImage = False
             cv2.destroyAllWindows()
             cv2.destroyAllWindows()
@@ -138,14 +147,22 @@ class OpticalSensor():
 
 
   def stop(self):
   def stop(self):
     self.running = False
     self.running = False
-    if self._t:
-      self._t.join()
-    self.log_handler.log_and_print("stop optical sensor")
+    self._thread.join()
+    self.log_handler.log_and_print("stopped optical sensor")
 
 
   def calculate_position(self, values):
   def calculate_position(self, values):
     centerX_perc, distance_perc = values
     centerX_perc, distance_perc = values
-
+    #       distance (as a percentage of visible_width_at_y)
+    # \    <-------->    /<= beta
+    #   \       |  /   /
+    #     \    y| /  /
+    #       \   |/ /
+    #  x_off  \__/ 
+    #<---------># <= camera with FoV/2 = alpha
+
+    # extrapolate total width from measured fiducial distance
     visible_width_at_y = self.target_distance / distance_perc
     visible_width_at_y = self.target_distance / distance_perc
+    # 50% is is center of camera, so we shift it by x_offset to align with the system
     x = self.x_offset + visible_width_at_y * (centerX_perc-0.5)
     x = self.x_offset + visible_width_at_y * (centerX_perc-0.5)
     alpha = (self.fov/2) / 180 * math.pi
     alpha = (self.fov/2) / 180 * math.pi
     beta = (90 - self.fov/2) / 180 * math.pi
     beta = (90 - self.fov/2) / 180 * math.pi