I created this "simulation" to run my code from RPI on a laptop. I used randint for the sensor values and also took a few shots from the robot's camera to get everything right. This code running on a Windows laptop does not cause any problems, even though the MotionController() function is identical. On the RPI it freezes after about the third time the code is run.
Code:
import cv2import numpy as npimport tkinter as tkimport mathfrom enum import Enumimport randomimport timecapture = cv2.VideoCapture('source_3.avi')class TunningGUI: def __init__(self, root): self.root = root self.root.title("Image Processing Settings") self.sigma_color = tk.DoubleVar(value=10) self.sigma_space = tk.DoubleVar(value=25) self.kernel_size = tk.IntVar(value=50) self.canny_threshold1 = tk.IntVar(value=35) self.canny_threshold2 = tk.IntVar(value=150) self.dilate_kernel_size = tk.IntVar(value=10) self.create_gui() def create_gui(self): color_label = tk.Label(self.root, text="Sigma Color:") color_label.grid(row=0, column=0, padx=10, pady=5, sticky=tk.W) color_slider = tk.Scale(self.root, from_=1, to=50, orient=tk.HORIZONTAL, variable=self.sigma_color) color_slider.grid(row=0, column=1, padx=10, pady=5) space_label = tk.Label(self.root, text="Sigma Space:") space_label.grid(row=1, column=0, padx=10, pady=5, sticky=tk.W) space_slider = tk.Scale(self.root, from_=1, to=50, orient=tk.HORIZONTAL, variable=self.sigma_space) space_slider.grid(row=1, column=1, padx=10, pady=5) kernel_label = tk.Label(self.root, text="Kernel Size:") kernel_label.grid(row=2, column=0, padx=10, pady=5, sticky=tk.W) kernel_slider = tk.Scale(self.root, from_=1, to=50, orient=tk.HORIZONTAL, variable=self.kernel_size) kernel_slider.grid(row=2, column=1, padx=10, pady=5) canny_threshold1_label = tk.Label(self.root, text="Canny Threshold 1:") canny_threshold1_label.grid(row=3, column=0, padx=10, pady=5, sticky=tk.W) canny_threshold1_slider = tk.Scale(self.root, from_=1, to=255, orient=tk.HORIZONTAL, variable=self.canny_threshold1) canny_threshold1_slider.grid(row=3, column=1, padx=10, pady=5) canny_threshold2_label = tk.Label(self.root, text="Canny Threshold 2:") canny_threshold2_label.grid(row=4, column=0, padx=10, pady=5, sticky=tk.W) canny_threshold2_slider = tk.Scale(self.root, from_=1, to=255, orient=tk.HORIZONTAL, variable=self.canny_threshold2) canny_threshold2_slider.grid(row=4, column=1, padx=10, pady=5) dilate_kernel_size_label = tk.Label(self.root, text="Dilate Kernel Size:") dilate_kernel_size_label.grid(row=5, column=0, padx=10, pady=5, sticky=tk.W) dilate_kernel_size_slider = tk.Scale(self.root, from_=1, to=20, orient=tk.HORIZONTAL, variable=self.dilate_kernel_size) dilate_kernel_size_slider.grid(row=5, column=1, padx=10, pady=5) def update_filter(self): try: sigma_color = int(self.sigma_color.get()) sigma_space = int(self.sigma_space.get()) kernel_size = int(self.kernel_size.get()) canny_threshold1 = int(self.canny_threshold1.get()) canny_threshold2 = int(self.canny_threshold2.get()) dilate_kernel_size = int(self.dilate_kernel_size.get()) return sigma_color, sigma_space, kernel_size, canny_threshold1, canny_threshold2, dilate_kernel_size except ValueError: print("Error") return Nonetunning_gui = TunningGUI(tk.Tk())def simulate_edge_array(): global image_height, image_width sigma_color, sigma_space, kernel_size, canny_threshold1, canny_threshold2, dilate_kernel_size = tunning_gui.update_filter() step_size = 6 edge_array = [] _, img = capture.read() if img is None or img.size == 0: capture.set(cv2.CAP_PROP_POS_FRAMES, 0) _, img = capture.read() img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) img_gray = cv2.bilateralFilter(img_gray, sigma_color, sigma_space, kernel_size) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (dilate_kernel_size,dilate_kernel_size)) dilate = cv2.morphologyEx(img_gray, cv2.MORPH_DILATE, kernel) img_edge = cv2.Canny(dilate, canny_threshold1, canny_threshold2) image_width = img_edge.shape[1] - 1 image_height = img_edge.shape[0] - 1 edge_array = [] cv2.imshow("bilatereal", img_gray) cv2.imshow("final", img_edge) for j in range(0, image_width, step_size): for i in range(image_height-5, 0, -1): if img_edge.item(i, j) == 255: edge_array.append((j, i)) break else: edge_array.append((j, 0)) edge_array.insert(0, (0, image_height)) edge_array.append((image_width, image_height)) return edge_arraydef view(): global image_height, image_width edge_array = simulate_edge_array() if edge_array is None: return [] fov_width = 173 top_left = (0, 0) bottom_left = (0, image_height) top_right = (image_width, 0) bottom_right = (image_width, image_height) pts1 = np.float32([top_left, bottom_left, top_right, bottom_right]) pts2 = np.float32([[fov_width, 0], [0, image_height], [(image_width - fov_width), 0], [image_width, image_height]]) transform_matrix = cv2.getPerspectiveTransform(pts1, pts2) transformed_edge_array = [] for point in edge_array: x, y = point original_coordinates = np.array([x, y, 1]) transformed_coordinates = np.dot(transform_matrix, original_coordinates) transformed_x = int(transformed_coordinates[0] / transformed_coordinates[2]) transformed_y = int(transformed_coordinates[1] / transformed_coordinates[2]) transformed_edge_array.append((transformed_x, transformed_y)) visualization_matrix = np.zeros((image_height, image_width), dtype=np.uint8) for i in range(len(transformed_edge_array)-1): cv2.line(visualization_matrix, tuple(transformed_edge_array[i]), tuple(transformed_edge_array[i+1]), 255, 2) cv2.imshow("visualization_matrix", visualization_matrix) cv2.waitKey(1) return transformed_edge_arraycommands = ["STOP", "FRWD", "BKWD", "LEFT", "RIHT"]class Commands(Enum): STOP = 0 FRWD = 1 BKWD = 2 LEFT = 3 RIHT = 4class MotionController: def __init__(self): self.width, self.height = 1000, 1000 self.angle_line_startx = self.width / 2 self.angle_line_starty = self.height / 2 self.angle = 0 self.mileage = 0 self.line_length = 20 self.size_factor = 0.2 self.x_factor = self.width / 2 self.y_factor = self.height / 2 self.x_transform_offset = 0 self.y_transform_offset = 0 self.x_rot_offset = 0 self.y_rot_offset = 0 self.turn = False self.cmd_pick = 0 self.polygon_points = [] self.root = tk.Tk() self.root.title("Map") self.canvas = tk.Canvas(self.root, width=self.width, height=self.height, bg="black") self.canvas.pack() def arr_pos(self, x, y): start_time = time.time() image_width = 640 * self.size_factor image_height = 480 * self.size_factor self.x_rot_offset = self.x_factor - image_width / 2 self.y_rot_offset = self.y_factor - image_height / 2 angle_in_rad_rot = (self.angle + 90) * math.pi / 180 cos_theta = math.cos(angle_in_rad_rot) sin_theta = math.sin(angle_in_rad_rot) x_rot = self.size_factor * (x - self.x_factor) * cos_theta - self.size_factor * (y - self.y_factor) * sin_theta + self.x_rot_offset y_rot = self.size_factor * (x - self.x_factor) * sin_theta + self.size_factor * (y - self.y_factor) * cos_theta + self.y_rot_offset angle_in_rad_transform = self.angle * math.pi / 180 cos_fi = math.cos(angle_in_rad_transform) sin_fi = math.sin(angle_in_rad_transform) self.x_transform_offset = self.mileage * self.size_factor * cos_fi self.y_transform_offset = self.mileage * self.size_factor * sin_fi x_transformed = x_rot + self.x_transform_offset y_transformed = y_rot + self.y_transform_offset return x_transformed, y_transformed def gen_map(self, surrounding, distance, angle, mileage): self.mileage = mileage angle_in_rad = self.angle * math.pi / 180 cos_theta = math.cos(angle_in_rad) sin_theta = math.sin(angle_in_rad) connection_points = [(0, 0),(0, 0)] angle_line_endx = self.angle_line_startx + self.line_length * cos_theta angle_line_endy = self.angle_line_starty + self.line_length * sin_theta self.canvas.delete("angle_line") self.canvas.create_line(self.angle_line_startx, self.angle_line_starty, angle_line_endx, angle_line_endy, fill="red", tags="angle_line") if mileage % 200 == 0: self.angle += 45 self.turn = True if self.turn == True: x_start_rot, y_start_rot = self.arr_pos(surrounding[0][0], surrounding[0][1]) x_end_rot, y_end_rot = self.arr_pos(surrounding[len(surrounding)-2][0], surrounding[len(surrounding)-2][1]) #print(f"x start: {x_start_rot}") #print(f"y start: {y_start_rot}") #print(f"x end: {x_end_rot}") #print(f"y end: {y_end_rot}") self.x_factor = (x_start_rot + x_end_rot) / 2 self.y_factor = (y_start_rot + y_end_rot) / 2 self.turn = False self.polygon_points = [self.arr_pos(x, y) for x, y in surrounding] self.canvas.create_polygon(self.polygon_points, outline="white", fill="white", tags="map_polygon") if distance < 30: self.cmd_pick = Commands.STOP.value else: self.cmd_pick = Commands.FRWD.value direction = commands[self.cmd_pick] self.root.update() return direction def main(): motion_controller = MotionController() mileage = 0 while True: surrounding = view() distance = random.randint(20, 60) angle = random.randint(20, 50) mileage = mileage + 10 motion_controller.gen_map(surrounding, distance, angle, mileage) time.sleep(0.1)main()
Statistics: Posted by mart1nek — Mon Feb 05, 2024 7:46 am