Ejemplo n.º 1
0
 def _final_frame(self,
                  im,
                  fill,
                  lcurv,
                  rcurv,
                  offset,
                  font=cv.FONT_HERSHEY_DUPLEX,
                  scale_font=1,
                  color_font=(255, 0, 0),
                  show=False):
     fill = prsp.warp(fill, inverse=True)
     out = im.copy()
     out = cv.addWeighted(out, 0.7, fill, 0.5, 0)
     xtxt = 50
     lcurv_text = 'Left curvature={0:.01f}m'.format(lcurv)
     rcurv_text = 'Right curvature={0:.01f}m'.format(rcurv)
     offset_text = 'Offset={0:.02f}m'.format(offset)
     out = cv.putText(out, lcurv_text, (xtxt, 30), font, scale_font,
                      color_font)
     out = cv.putText(out, rcurv_text, (xtxt, 60), font, scale_font,
                      color_font)
     out = cv.putText(out, offset_text, (xtxt, 90), font, scale_font,
                      color_font)
     if show == True:
         show_images(im, out, 'origin', 'lanes', 'Lanes detected')
     return out
Ejemplo n.º 2
0
def test(filename, n=0, show=False):
    import importlib
    importlib.reload(mask)
    print(persp._perspective)
    im_ = plt.imread(filename)
    im = clb.undistort(im_)
    if n == -1:
        return persp.warp(im, show=show)
    elif n == 0:
        im2 = persp.warp(im, show=show)
        color_mask.hls_channel(im2, channel='h', thresh=(100, 255), show=show)
        color_mask.hls_channel(im2, channel='l', thresh=(200, 255), show=show)
        color_mask.hls_channel(im2, channel='s', thresh=(100, 255), show=show)
    elif n == 1:
        im_eq = equalize_hist(im, show=show)
        im2 = persp.warp(im_eq, show=show)
        color_mask.hls_channel(im2, channel='h', thresh=(0, 100), show=show)
        color_mask.hls_channel(im2, channel='l', thresh=(200, 255), show=show)
        color_mask.hls_channel(im2, channel='s', thresh=(100, 255), show=show)
    elif n == 2:
        im2 = persp.warp(im, show=show)
        color_mask.rgb_channel(im2, channel='r', thresh=(220, 255), show=show)
        color_mask.rgb_channel(im2, channel='g', thresh=(210, 255), show=show)
        color_mask.rgb_channel(im2, channel='b', thresh=(0, 100), show=show)
    elif n == 3:
        im2 = persp.warp(im, show=show)
        color_mask.hls_channel(im2, channel='h', thresh=(0, 90), show=show)
        color_mask.hls_channel(im2, channel='l', thresh=(200, 255), show=show)
        color_mask.hls_channel(im2, channel='s', thresh=(110, 255), show=show)
    elif n == 4:
        im2 = persp.warp(im, show=show)
        return custom_mask.special_mask(im2, show=show)
Ejemplo n.º 3
0
 def process(self, frame, show=False):
     im = clb.undistort(frame)
     warped = prsp.warp(im)
     masked = custom_mask.apply(warped, show=show)
     lp, rp = self._find_lane_points(masked,
                                     num_strips=10,
                                     radius=70,
                                     show=show)
     height = masked.shape[0]
     width = masked.shape[1]
     llane = Lane(lp, end=height - 1, num=height)
     rlane = Lane(rp, end=height - 1, num=height)
     offset = Lane.offset(llane,
                          rlane,
                          y=masked.shape[0] - 1,
                          frame_width=width)
     lcurv = llane.curvature(height // 2)
     rcurv = rlane.curvature(height // 2)
     fill = Lane.fill_lanes(warped, llane, rlane, show=show)
     return self._final_frame(im, fill, lcurv, rcurv, offset, show=show)
Ejemplo n.º 4
0
class WhiteBoard:
	running = False
	mouseclicked = False
	calibrating = False	
	
	KEEPLIGHTTIME = 3 #will not consider if we lose the light for x frames
	CLICKMAXTIME = 5 #longest that we will consider as a click for touchpad mode
	CLICKMINTIME = 3 # will not move the pointer for the first x frames after click to help a singleclic with shaky hand
	MAXTIMEBETWEENCLICKDRAG = 5 #...
	
	def __init__(self):
		self.mouse = MouseControl()
		self.XRES,self.YRES = self.mouse.get_screen_resolution()
		self.XRES, self.YRES = float(self.XRES), float(self.YRES)
		self.ABCD = [(0,0),(self.XRES-5,0),(0,self.YRES-5),(self.XRES-5,self.YRES-5)]
		self.perspective = Perspective()
		self.perspective.setdst((0.0,0.0),(self.XRES,0.0),(0.0,self.YRES),(self.XRES,self.YRES))
		self.cursor = Cursor(self)
		self.Options = Options()
		
	def printOut(self,strList,newLine = True):
		for all in strList:
			print all,
		#if newLine: print ""
		print ""
	
	def GetBattery(self):
		try:
			bat = self.wiimote.WiimoteState.Battery
		except AttributeError:
			return None
		if bat: return  bat*100/200
		else: return None
		
	def Connect(self):
		self.wiimote = Wiimote()
		self.OnConnecting()
		if sys.platform != 'win32': self.printOut(["Press 1 and 2 on wiimote"])
		#try:
		self.wiimote.Connect()
		#except:
		#	self.OnNoWiimoteFound()
		#	raise SystemExit
		self.OnConnected()
		self.wiimote.SetLEDs(True,False,False,False)
		self.wiimote.SetReportType(self.wiimote.InputReport.IRAccel,True)
	
	def IsConnected(self):
		try:
			cn = self.wiimote.running
		except:
			return False
		return cn
		
		
	def IsRunning(self):
		return self.running
	
	def OnRun(self): #to be overloaded
		pass
		
	def OnConnected(self): #to be overloaded
		self.printOut(["Battery: ", self.GetBattery(), "%"])
	
	def OnConnecting(self): #to be overloaded
		pass
	
	def OnDisconnect(self): #to be overloaded
		pass
	
	def OnStop(self): #to be overloaded
		pass
		
	def OnCalibrated(self): #to be overloaded
		pass
	
	def OnCalibrating(self):
		pass
		
	def OnNoWiimoteFound(self):
		print "No Wiimote or no Bluetooth found..."
		pass
		
	def OnOptionsChanged(self):
		pass
		
	def Run(self):
		
		self.running = True
		
		keep_light = self.KEEPLIGHTTIME
		x,y = (0,0)
		first_x, first_y = (0,0)
		light_state = False
		timer = 0
		
		self.OnRun()
		
		while self.running:
			if self.wiimote.WiimoteState.ButtonState.A:
				self.Stop()
				continue

			time.sleep(0.030)
			
			if self.wiimote.WiimoteState.IRState.Found1: 
				if not light_state: #if the light appears
					light_state = True
					first_x,first_y = map(int,self.perspective.warp(self.wiimote.WiimoteState.IRState.RawX1, self.wiimote.WiimoteState.IRState.RawY1))
					x,y = first_x, first_y
					timer = 0 #reset timer
					self.cursor.update(light_state, True, (first_x,first_y), (x,y), timer)
					
				else: #if the light is still lit
					x,y = map(int,self.perspective.warp(self.wiimote.WiimoteState.IRState.RawX1, self.wiimote.WiimoteState.IRState.RawY1))
					timer += 1
					keep_light = self.KEEPLIGHTTIME #keep it high while light is seen.
					self.cursor.update(light_state, False, (first_x,first_y), (x,y), timer)
			
			else:
				if keep_light and timer > self.KEEPLIGHTTIME: keep_light -= 1 #keep_light will not prevent cut-off if the light goes out quick
				else:
					if light_state:
						light_state = False
						self.cursor.update(light_state, True, (first_x,first_y), (x,y), timer)
						timer = self.KEEPLIGHTTIME - keep_light #this is the true delay since the light has gone off, not 0
					else:
						timer += 1
						self.cursor.update(light_state, False, (first_x,first_y), (x,y), timer)
						
					
			
	
	def Stop(self):
		self.running = False
		self.OnStop()
		
	def Disconnect(self):
		if self.IsRunning: self.Stop()
		self.wiimote.Disconnect()
		self.OnDisconnect()
		if self.calibrating: raise SystemExit
		del self.wiimote
		
	def Calibrate(self):
		self.Stop()
		self.calibrating = True
		self.OnCalibrating()
		self.printOut(["Point to the top left corner of the screen... "],False)
		self.ABCD[0] = self.WaitForLight()
		self.printOut(["OK"])
		
		self.WaitNoLight()
		self.printOut(["Point to the top right corner of the screen... "],False)
		self.ABCD[1] = self.WaitForLight()
		self.printOut([ "OK"])
		
		self.WaitNoLight()
		self.printOut([ "Point to the bottom left corner of the screen... "],False)
		self.ABCD[2] = self.WaitForLight()
		self.printOut([ "OK"])
		
		self.WaitNoLight()
		self.printOut([ "Point to the bottom right corner of the screen... "],False)
		self.ABCD[3] = self.WaitForLight()
		self.printOut([ "OK"])
	
		self.WaitNoLight()
		
		x0,y0 = self.ABCD[0]
		x1,y1 = self.ABCD[1]
		x2,y2 = self.ABCD[2]
		x3,y3 = self.ABCD[3]
		self.perspective.setsrc((x0,y0),(x1,y1),(x2,y2),(x3,y3))
		
		self.calibrating = False
		self.printOut([ "Calibration complete!"])
		self.OnCalibrated()
		
	def WaitForLight(self):
		dot = False
		while not dot:
			checkdot = self.wiimote.WiimoteState.IRState.RawX1, self.wiimote.WiimoteState.IRState.RawY1
			if self.wiimote.WiimoteState.IRState.Found1:
				dot = checkdot
				return dot
			time.sleep(0.030)
			
	def WaitNoLight(self):
		time.sleep(0.5)
		while 1:
			time.sleep(0.030)
			if self.wiimote.WiimoteState.IRState.Found1 == False:
				return
Ejemplo n.º 5
0
class WhiteBoard:
    running = False
    mouseclicked = False
    calibrating = False

    KEEPLIGHTTIME = 3  #will not consider if we lose the light for x frames
    CLICKMAXTIME = 5  #longest that we will consider as a click for touchpad mode
    CLICKMINTIME = 3  # will not move the pointer for the first x frames after click to help a singleclic with shaky hand
    MAXTIMEBETWEENCLICKDRAG = 5  #...

    def __init__(self):
        self.mouse = MouseControl()
        self.XRES, self.YRES = self.mouse.get_screen_resolution()
        self.XRES, self.YRES = float(self.XRES), float(self.YRES)
        self.ABCD = [(0, 0), (self.XRES - 5, 0), (0, self.YRES - 5),
                     (self.XRES - 5, self.YRES - 5)]
        self.perspective = Perspective()
        self.perspective.setdst((0.0, 0.0), (self.XRES, 0.0), (0.0, self.YRES),
                                (self.XRES, self.YRES))
        self.cursor = Cursor(self)
        self.Options = Options()

    def printOut(self, strList, newLine=True):
        for all in strList:
            print all,
        #if newLine: print ""
        print ""

    def GetBattery(self):
        try:
            bat = self.wiimote.WiimoteState.Battery
        except AttributeError:
            return None
        if bat: return bat * 100 / 200
        else: return None

    def Connect(self):
        self.wiimote = Wiimote()
        self.OnConnecting()
        if sys.platform != 'win32': self.printOut(["Press 1 and 2 on wiimote"])
        #try:
        self.wiimote.Connect()
        #except:
        #   self.OnNoWiimoteFound()
        #   raise SystemExit
        self.OnConnected()
        self.wiimote.SetLEDs(True, False, False, False)
        self.wiimote.SetReportType(self.wiimote.InputReport.IRAccel, True)

    def IsConnected(self):
        try:
            cn = self.wiimote.running
        except:
            return False
        return cn

    def IsRunning(self):
        return self.running

    def OnRun(self):  #to be overloaded
        pass

    def OnConnected(self):  #to be overloaded
        self.printOut(["Battery: ", self.GetBattery(), "%"])

    def OnConnecting(self):  #to be overloaded
        pass

    def OnDisconnect(self):  #to be overloaded
        pass

    def OnStop(self):  #to be overloaded
        pass

    def OnCalibrated(self):  #to be overloaded
        pass

    def OnCalibrating(self):
        pass

    def OnNoWiimoteFound(self):
        print "No Wiimote or no Bluetooth found..."
        pass

    def OnOptionsChanged(self):
        pass

    def Run(self):

        self.running = True

        keep_light = self.KEEPLIGHTTIME
        x, y = (0, 0)
        first_x, first_y = (0, 0)
        light_state = False
        timer = 0

        self.OnRun()

        while self.running:
            if self.wiimote.WiimoteState.ButtonState.A:
                self.Stop()
                continue

            time.sleep(0.030)

            if self.wiimote.WiimoteState.IRState.Found1:
                if not light_state:  #if the light appears
                    light_state = True
                    first_x, first_y = map(
                        int,
                        self.perspective.warp(
                            self.wiimote.WiimoteState.IRState.RawX1,
                            self.wiimote.WiimoteState.IRState.RawY1))
                    x, y = first_x, first_y
                    timer = 0  #reset timer
                    self.cursor.update(light_state, True, (first_x, first_y),
                                       (x, y), timer)

                else:  #if the light is still lit
                    x, y = map(
                        int,
                        self.perspective.warp(
                            self.wiimote.WiimoteState.IRState.RawX1,
                            self.wiimote.WiimoteState.IRState.RawY1))
                    timer += 1
                    keep_light = self.KEEPLIGHTTIME  #keep it high while light is seen.
                    self.cursor.update(light_state, False, (first_x, first_y),
                                       (x, y), timer)

            else:
                if keep_light and timer > self.KEEPLIGHTTIME:
                    keep_light -= 1  #keep_light will not prevent cut-off if the light goes out quick
                else:
                    if light_state:
                        light_state = False
                        self.cursor.update(light_state, True,
                                           (first_x, first_y), (x, y), timer)
                        timer = self.KEEPLIGHTTIME - keep_light  #this is the true delay since the light has gone off, not 0
                    else:
                        timer += 1
                        self.cursor.update(light_state, False,
                                           (first_x, first_y), (x, y), timer)

    def Stop(self):
        self.running = False
        self.OnStop()

    def Disconnect(self):
        if self.IsRunning: self.Stop()
        self.wiimote.Disconnect()
        self.OnDisconnect()
        if self.calibrating: raise SystemExit
        del self.wiimote

    def Calibrate(self):
        self.Stop()
        self.calibrating = True
        self.OnCalibrating()
        self.printOut(["Point to the top left corner of the screen... "],
                      False)
        self.ABCD[0] = self.WaitForLight()
        self.printOut(["OK"])

        self.WaitNoLight()
        self.printOut(["Point to the top right corner of the screen... "],
                      False)
        self.ABCD[1] = self.WaitForLight()
        self.printOut(["OK"])

        self.WaitNoLight()
        self.printOut(["Point to the bottom left corner of the screen... "],
                      False)
        self.ABCD[2] = self.WaitForLight()
        self.printOut(["OK"])

        self.WaitNoLight()
        self.printOut(["Point to the bottom right corner of the screen... "],
                      False)
        self.ABCD[3] = self.WaitForLight()
        self.printOut(["OK"])

        self.WaitNoLight()

        x0, y0 = self.ABCD[0]
        x1, y1 = self.ABCD[1]
        x2, y2 = self.ABCD[2]
        x3, y3 = self.ABCD[3]
        self.perspective.setsrc((x0, y0), (x1, y1), (x2, y2), (x3, y3))

        self.calibrating = False
        self.printOut(["Calibration complete!"])
        self.OnCalibrated()

    def WaitForLight(self):
        dot = False
        while not dot:
            checkdot = self.wiimote.WiimoteState.IRState.RawX1, self.wiimote.WiimoteState.IRState.RawY1
            if self.wiimote.WiimoteState.IRState.Found1:
                dot = checkdot
                return dot
            time.sleep(0.030)

    def WaitNoLight(self):
        time.sleep(0.5)
        while 1:
            time.sleep(0.030)
            if self.wiimote.WiimoteState.IRState.Found1 == False:
                return
Ejemplo n.º 6
0
        plt.ylim(720, 0)
        plt.axis("off")
        # Save visualization
        if save_image:
            plt.savefig('./output_images/vis_area.png', bbox_inches='tight')
        plt.show()


if __name__ == '__main__':
    polyfit = Polyfit()
    perspective = Perspective()

    image_file = 'test_images/test2.jpg'
    image = mpimg.imread(image_file)
    undistorted = undistort(image)
    # Create binary outputs
    abs_thresh, mag_thresh, dir_thresh, hls_thresh, hsv_thresh, combined_output = combined_threshold(
        undistorted)
    plt.imshow(combined_output, cmap='gray')
    warped = perspective.warp(combined_output)
    plt.imshow(warped, cmap='gray')
    # Find lanes
    left_fit, right_fit, vars = polyfit.poly_fit_skip(warped)
    left_curve_rad, right_curve_rad = polyfit.curvature()
    position = polyfit.vehicle_position(warped)
    print('curvature: {:.2f}m'.format((left_curve_rad + right_curve_rad) / 2))
    print('vehicle position: {:.2f}m from center'.format(position))
    # Visualize lane finding
    polyfit.visualize_window(warped, vars, save_image=True)
    polyfit.visualize_area(warped, vars, save_image=True)
Ejemplo n.º 7
0
class LaneLines:
    def __init__(self, camera_matrix, distortion_coefficients, buffer_size = 50, img_size = (1280,720)):
        self.camera_matrix = camera_matrix
        self.distortion_coefficients = distortion_coefficients

        src = np.float32(
            [[(img_size[0] / 2) - 75, img_size[1] / 2 + 100],
            [((img_size[0] / 6) - 10), img_size[1]],
            [(img_size[0] * 5 / 6) + 60, img_size[1]],
            [(img_size[0] / 2 + 75), img_size[1] / 2 + 100]])
        dst = np.float32(
            [[(img_size[0] / 4), 0],
            [(img_size[0] / 4), img_size[1]],
            [(img_size[0] * 3 / 4), img_size[1]],
            [(img_size[0] * 3 / 4), 0]])

        self.perspective = Perspective(src,dst)

        self.search_engine = HistogramSearch(
                            window_width = 200,
                            window_height = 80,
                            min_pixels_to_recenter=50,
                            visualisation = None)
        self.left = Lane(buffer_size)
        self.right = Lane(buffer_size)

    def draw(self, img):
        preprocessed_img = self.preprocess(img)
        left, right = self.find_lanes(preprocessed_img)
        result = img
        if left.best_fit is not None and right.best_fit is not None:
            area = self.lane_area(preprocessed_img, left, right)
            area = cv2.warpPerspective(area, self.perspective.matrix, (img.shape[1], img.shape[0]), flags=cv2.WARP_INVERSE_MAP)
            result = cv2.addWeighted(img, 1, area, 0.3, 0)

            ls = LaneStatistics(preprocessed_img, left)
            rs = LaneStatistics(preprocessed_img, right)

            radius = "radius of curvature {0:.0f} m"  \
                .format((ls.radius_of_curvature_in_m + rs.radius_of_curvature_in_m)/2)

            offset = "offset {0:.2f} m" \
                .format(np.abs(ls.distance_to_vehicle_center_in_m - rs.distance_to_vehicle_center_in_m))

            cv2.putText(result, radius, (50, 65), cv2.FONT_HERSHEY_PLAIN, 3,(255,255,255),2);
            cv2.putText(result, offset, (50, 135), cv2.FONT_HERSHEY_PLAIN, 3,(255,255,255),2);

        return result

    def find_lanes(self, preprocessed_img):
        l_detection, r_detection = self.search_engine.find_lane_polynomials(
                    preprocessed_img,
                    self.left.best_fit,
                    self.right.best_fit)

        if l_detection is None or r_detection is None or not l_detection.trustful() or not r_detection.trustful():
            l_detection, r_detection = self.search_engine.find_lane_polynomials(preprocessed_img)

        self.left.update(l_detection)
        self.right.update(r_detection)
        return (self.left, self.right)

    def lane_area(self, warped, left_lane, right_lane):
        warp_zero = np.zeros_like(warped).astype(np.uint8)
        color_warp = np.dstack((warp_zero, warp_zero, warp_zero))

        arguments_y = np.linspace(0, warped.shape[0]-1, warped.shape[0] )
        left_values_x = left_lane.best_fit[0]*arguments_y**2 + left_lane.best_fit[1]*arguments_y + left_lane.best_fit[2]
        right_values_x = right_lane.best_fit[0]*arguments_y**2 + right_lane.best_fit[1]*arguments_y + right_lane.best_fit[2]

        # Recast the x and y points into usable format for cv2.fillPoly()
        pts_left = np.array([np.transpose(np.vstack([left_values_x, arguments_y]))])
        pts_right = np.array([np.flipud(np.transpose(np.vstack([right_values_x, arguments_y])))])
        pts = np.hstack((pts_left, pts_right))

        # Draw the lane onto the warped blank image
        cv2.fillPoly(color_warp, np.int_([pts]), (0,255, 0))

        return color_warp

    def preprocess(self, img):
        img = self.undistort(img)
        img = self.blur(img)
        img = self.threshold(img)
        img = self.warp(img)
        return img

    def warp(self, img):
        return self.perspective.warp(img)

    def blur(self, img,  kernel_size = 5):
        return cv2.GaussianBlur(img, (kernel_size, kernel_size), 0)

    def undistort(self, img):
        return  cv2.undistort(img, self.camera_matrix, self.distortion_coefficients, None, self.camera_matrix)

    def threshold(self, img):
        img_hls = cv2.cvtColor(img, cv2.COLOR_BGR2HLS).astype(np.float)
        img_lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB).astype(np.float)
        img_luv = cv2.cvtColor(img, cv2.COLOR_BGR2LUV).astype(np.float)

        threshold = Threshold()

        w_binary = threshold.white(img_luv, min_max= (180, 255))
        l_x = threshold.gradient_magnitude_x(img_luv[:,:,0], sobel_kernel=5, min_max = (15,255))
        l_d = threshold.gradient_direction_xy(img_luv[:,:,0], sobel_kernel=3, min_max = (0.7, 1.3))
        white = np.zeros_like(w_binary)
        white[(img[:,:,0] >= 200) & (img[:,:,1] >= 200) & (img[:,:,2] >= 200)] = 1
        r_x = threshold.gradient_magnitude_x(white, sobel_kernel=5, min_max = (10,255))
        l_binary = threshold.lightness(img_hls, min_max = (210, 255))
        g_m = threshold.gradient_magnitude_x(l_binary, sobel_kernel=31, min_max = (100, 255))

        white_lane = np.zeros_like(w_binary)
        white_lane [(r_x == 1) | ((l_d == 1) & (l_x == 1) & (w_binary == 1)) | (g_m == 1)] = 1

        y_binary = threshold.blue_yellow(img_lab, min_max= (145, 255))
        y_m = threshold.gradient_magnitude_xy(img_lab[:,:,2], sobel_kernel=3, min_max = (50, 255))
        s_binary = threshold.saturation(img_hls, min_max = (10,255))
        s_x = threshold.gradient_magnitude_x(img_hls[:,:,2], sobel_kernel=31, min_max = (100,255))
        s_d = threshold.gradient_direction_xy(img_hls[:,:,2], sobel_kernel=31, min_max = (0.6, 1.2))

        yellow_line = np.zeros_like(y_binary)
        yellow_line[(y_binary == 1) | (y_m == 1) | ((s_d == 1) & (s_x == 1) & (s_binary == 1))] = 1

        result = np.zeros_like(w_binary)
        result[(yellow_line == 1) | (white_lane == 1)] = 1
        return result