def test_visible_sublanes(self): fantasy, ig = Genre.lookup(self._db, classifier.Fantasy) urban_fantasy, ig = Genre.lookup(self._db, classifier.Urban_Fantasy) humorous, ig = Genre.lookup(self._db, classifier.Humorous_Fiction) visible_sublane = Lane(self._db, "Humorous Fiction", genres=humorous) visible_grandchild = Lane(self._db, "Urban Fantasy", genres=urban_fantasy) invisible_sublane = Lane(self._db, "Fantasy", invisible=True, genres=fantasy, sublanes=[visible_grandchild], subgenre_behavior=Lane.IN_SAME_LANE) lane = Lane(self._db, "English", sublanes=[visible_sublane, invisible_sublane], subgenre_behavior=Lane.IN_SAME_LANE) eq_(2, len(lane.visible_sublanes)) assert visible_sublane in lane.visible_sublanes assert visible_grandchild in lane.visible_sublanes
def test_custom_sublanes(self): fantasy, ig = Genre.lookup(self._db, classifier.Fantasy) urban_fantasy, ig = Genre.lookup(self._db, classifier.Urban_Fantasy) urban_fantasy_lane = Lane(self._db, "Urban Fantasy", genres=urban_fantasy) fantasy_lane = Lane(self._db, "Fantasy", fantasy, genres=fantasy, subgenre_behavior=Lane.IN_SAME_LANE, sublanes=[urban_fantasy_lane]) eq_([urban_fantasy_lane], fantasy_lane.sublanes.lanes) # You can just give the name of a genre as a sublane and it # will work. fantasy_lane = Lane(self._db, "Fantasy", fantasy, genres=fantasy, subgenre_behavior=Lane.IN_SAME_LANE, sublanes="Urban Fantasy") eq_([["Urban Fantasy"]], [x.genre_names for x in fantasy_lane.sublanes.lanes])
def init_lanes(self, capacities): """ Initialize lanes for each lane group, different lane groups might share the same lane :param capacities: :return: """ capacities = [int(c) for c in capacities] self.capacity = sum(capacities) if sum(capacities) == 5: # if it's single lane, then all group share the same lane self.single_lane = True lane = Lane(self.link, self, max(capacities)) self.lanes["T"].append(lane) self.lanes["L"].append(lane) self.lanes["R"].append(lane) else: # create left,right lanes left_lane = Lane(self.link, self, capacities[0]) right_lane = Lane(self.link, self, capacities[-1]) self.lanes["L"].append(left_lane) self.lanes["R"].append(right_lane) # create through lanes for cap in capacities[1:-1]: if cap: self.lanes["T"].append(Lane(self.link, self, cap)) # if capacity is 5, then left/right and through group share the same lane if capacities[0] == 5: self.lanes["T"].insert(0, left_lane) if capacities[-1] == 5: self.lanes["T"].append(right_lane)
def process_image(self, image): img_height, img_width, _ = image.shape undistorted_img = self.undistort(image) color_binary, combined_binary = self.thresholded_binary( undistorted_img) bin_image = self.transform_to_top_down(combined_binary) left_fitx, right_fitx, ploty, left_fit, right_fit, leftx, lefty, rightx, righty = self.find_lane_lines( bin_image) left = Lane(leftx, lefty) right = Lane(rightx, righty) lanes = Lanes(left, right) self.lanes_average.update(lanes) if self.last_lanes is None: self.last_lanes = lanes if lanes.lanes_parallel(img_height) and lanes.distance_from_center( (img_width / 2, img_height)) < 4.0: self.last_lanes = lanes self.output = self.draw_overlays( image=image, left_fit=self.lanes_average.lanes.left.pixels.fit, right_fit=self.lanes_average.lanes.right.pixels.fit, leftx=self.lanes_average.left.xs, rightx=self.lanes_average.right.xs, lefty=self.lanes_average.left.ys, righty=self.lanes_average.right.ys) return self.output
def test_can_change_lane_when_alone(self): car1 = Car(20, 0, 0, 10, 0) lane1 = Lane() lane2 = Lane() lane1.add_car(car1) light = TrafficLight(100) self.assertTrue(control.can_change_lane(car1, lane1, lane2, [light]))
def __init__(self, *args, **kwargs): self.south = Lane("south") self.north = Lane("north") self.west = Lane("west") self.east = Lane("east") self.traffic_probability = self.fit_curve(False) self.time = 0
def update_position(self, maze, modifs): """depending on the player answer: gives the conditions to update McGyver's position inside the maze. modifs: given by the player in the move method of class Game return: None if McGyver is out = True and stop reading this method""" if self.is_out: return # initial position = Mcgyver tile in maze # update position inside the maze pos = maze.find_tile(McGyver) lin = pos[0] + modifs[0] lin = min(lin, 14) lin = max(0, lin) col = pos[1] + modifs[1] col = min(col, 14) col = max(0, col) # if the new position (found with get_tile) is an item, # print a lane (with set_tile) tile = maze.get_tile(lin, col) if isinstance(tile, Item): self.inventory.append(tile.name) maze.set_tile(lin, col, Lane()) # if the new position is Guardian -> check victory if isinstance(maze.get_tile(lin, col), Guardian): self.check_victory(maze) # if the new position is a lane: replace by mg, # and print lane instead of old position if isinstance(maze.get_tile(lin, col), Lane): maze.set_tile(pos[0], pos[1], Lane()) maze.set_tile(lin, col, self)
def test_cant_change_lane_when_close_to_traffic_lights(self): car1 = Car(98, 0, 0, 10, 0) lane1 = Lane() lane2 = Lane() lane1.add_car(car1) light = TrafficLight(100) self.assertFalse(control.can_change_lane(car1, lane1, lane2, [light]))
def get_lane_type(self, img, color_img): right_lane = Lane() left_lane = Lane() # Detect color. left_lane.color, right_lane.color = detect_color(color_img) # Detect solid vs dotted and single vs double. left_lane, right_lane, left_centers, right_centers = detect_dotted( img, left_lane, right_lane) # Handle errors. Don't update lane information unless new lane has been seen for 5 frames. if left_lane != self.last_left: if self.new_count_left >= 5 or self.first_frame: self.last_left = left_lane self.new_count_left = 0 else: left_lane = self.last_left self.new_count_left += 1 else: self.new_count_left = 0 if right_lane != self.last_right: if self.new_count_right >= 5 or self.first_frame: self.last_right = right_lane self.new_count_right = 0 self.first_frame = False else: right_lane = self.last_right self.new_count_right += 1 else: self.new_count_right = 0 return left_lane, right_lane, left_centers, right_centers
def quick_detect_lane_lines(image, last_lanes): nonzero = image.nonzero() nonzero_x, nonzero_y = np.array(nonzero[1]), np.array(nonzero[0]) last_left_p = np.poly1d(last_lanes.left.pixels.fit) last_right_p = np.poly1d(last_lanes.right.pixels.fit) margin = 100 left_lane_indices = ((nonzero_x > (last_left_p(nonzero_y) - margin)) & (nonzero_x < (last_left_p(nonzero_y) + margin))) right_lane_indices = ((nonzero_x > (last_right_p(nonzero_y) - margin)) & (nonzero_x < (last_right_p(nonzero_y) + margin))) # Again, extract left and right line pixel positions left_x = nonzero_x[left_lane_indices] left_y = nonzero_y[left_lane_indices] right_x = nonzero_x[right_lane_indices] right_y = nonzero_y[right_lane_indices] left = Lane(left_x, left_y) right = Lane(right_x, right_y) return Lanes(left, right), image
def compute_lane_from_candidates(line_candidates, img_shape): # Compute lines that approximate the position of both road lanes. #:param line_candidates: lines from hough transform # :param img_shape: shape of image to which hough transform was applied # :return: lines that approximate left and right lane position pos_lines = [l for l in line_candidates if l.slope > 0] neg_lines = [l for l in line_candidates if l.slope < 0] # interpolate biases and slopes to compute equation of line that approximates # left lane median is employed to filter outliers neg_bias = np.median([l.bias for l in neg_lines]).astype(int) neg_slope = np.median([l.slope for l in neg_lines]) x1, y1 = 0, neg_bias x2, y2 = -np.int32(np.round(neg_bias / neg_slope)), 0 left_lane = Lane(x1, y1, x2, y2) # interpolate biases and slopes to compute equation of line that approximates # right lane median is employed to filter outliers lane_right_bias = np.median([l.bias for l in pos_lines]).astype(int) lane_right_slope = np.median([l.slope for l in pos_lines]) x1, y1 = 0, lane_right_bias x2, y2 = np.int32( np.round( (img_shape[0] - lane_right_bias) / lane_right_slope)), img_shape[0] right_lane = Lane(x1, y1, x2, y2) return left_lane, right_lane
def __init__(self): self.new_count_left = 0 self.new_count_right = 0 self.last_left = Lane() self.last_right = Lane() self.first_frame = True self.left_fit = None self.right_fit = None
def test_cant_change_lane_when_car_slightly_in_front(self): car1 = Car(20, 0, 0, 10, 0) car2 = Car(25, 0, 0, 10, 0) lane1 = Lane() lane2 = Lane() lane1.add_car(car1) lane2.add_car(car2) light = TrafficLight(100) self.assertFalse(control.can_change_lane(car1, lane1, lane2, [light]))
def test_shouldnt_change_lane_to_go_faster_when_nothing(self): car1 = Car(50, 0, 0, 10, 0) lane0 = Lane() lane1 = Lane() lane2 = Lane() lane1.add_car(car1) light = TrafficLight(100) self.assertFalse( control.should_change_lane_to_move_faster(car1, lane1, [lane0, lane2], [light]))
def test_can_change_lane_when_cars_around_but_far(self): car1 = Car(50, 0, 0, 10, 0) car2 = Car(20, 0, 0, 10, 0) car3 = Car(70, 0, 0, 10, 0) lane1 = Lane() lane2 = Lane() lane1.add_car(car1) lane2.add_car(car2) lane2.add_car(car3) light = TrafficLight(100) self.assertTrue(control.can_change_lane(car1, lane1, lane2, [light]))
def smoothen_over_time(lane_lines): # Smooth the lane line inference over a window of frames and returns the average lines avg_line_lt = np.zeros((len(lane_lines), 4)) avg_line_rt = np.zeros((len(lane_lines), 4)) for t in range(0, len(lane_lines)): avg_line_lt[t] += lane_lines[t][0].get_coordinates() avg_line_rt[t] += lane_lines[t][1].get_coordinates() # axis=0 : rows return Lane(*np.mean(avg_line_lt, axis=0)), Lane( *np.mean(avg_line_rt, axis=0))
def test_includes_language(self): english_lane = Lane(self._db, self._str, languages=['eng']) eq_(True, english_lane.includes_language('eng')) eq_(False, english_lane.includes_language('fre')) no_english_lane = Lane(self._db, self._str, exclude_languages=['eng']) eq_(False, no_english_lane.includes_language('eng')) eq_(True, no_english_lane.includes_language('fre')) all_language_lane = Lane(self._db, self._str) eq_(True, all_language_lane.includes_language('eng')) eq_(True, all_language_lane.includes_language('fre'))
def find_lane(self): img = self.img if self.last_frame and self.last_valid_left_lane_found < 12 and self.last_valid_right_lane_found < 12: nonzero, left_lane_inds, right_lane_inds = self._extrapolate_from_last_frame( ) else: nonzero, left_lane_inds, right_lane_inds = self._sliding_window() nonzerox = np.array(nonzero[1]) nonzeroy = np.array(nonzero[0]) # Extract left and right line pixel positions leftx = nonzerox[left_lane_inds] lefty = nonzeroy[left_lane_inds] rightx = nonzerox[right_lane_inds] righty = nonzeroy[right_lane_inds] if len(leftx) == 0: print('no left lane') if len(rightx) == 0: print('not right lane') # Fit a second order polynomial to each left_fit_polynomial = np.polyfit(lefty, leftx, 2) right_fit_polynomial = np.polyfit(righty, rightx, 2) # Generate x and y values for plotting left_fitx, right_fitx, left_fity, right_fity = self._fit_polynomial_to_lane_data( left_fit_polynomial, right_fit_polynomial) left_lane = Lane(leftx, lefty, left_fit_polynomial, left_fitx, left_fity) right_lane = Lane(rightx, righty, right_fit_polynomial, right_fitx, right_fity) if left_lane.calculate_curvature() < 195: # import ipdb; ipdb.set_trace() left_lane = self.last_frame.left_lane if self.last_frame else None self.last_valid_left_lane_found += 1 else: self.last_valid_left_lane_found = 0 if right_lane.calculate_curvature() < 195: # import ipdb; ipdb.set_trace() right_lane = self.last_frame.right_lane if self.last_frame else None self.last_valid_right_lane_found += 1 else: self.last_valid_right_lane_found = 0 return left_lane, right_lane
def __init__(self): self.ym_per_pix = 30 / 720 # meters per pixel in y dimension self.xm_per_pix = 3.7 / 880 # meters per pixel in x dimension self.src_points = np.float32([[240, 690], [1070, 690], [577, 460], [706, 460]]) self.dst_points = np.float32([[200, 720], [1110, 720], [200, 25], [1110, 25]]) self.saved_camera_calibration_path = './camera_cal/ \ saved_camera_calibration.p' self.camera_calibration = self.__do_camera_calibration() self.line_left = Lane() self.line_right = Lane()
def test_should_change_lane_to_go_to_no_car_lane(self): car1 = Car(20, 0, 0, 10, 0) car2 = Car(30, 0, 0, 10, 0) car3 = Car(60, 0, 0, 10, 0) lane0 = Lane() lane1 = Lane() lane2 = Lane() lane1.add_car(car1) lane1.add_car(car3) lane0.add_car(car2) light = TrafficLight(100) self.assertEquals( control.should_change_lane_to_move_faster(car1, lane1, [lane0, lane2], [light]), lane2)
def process_video_file(file_name, camera): lane_object = Lane(camera.image_shape) src_clip = VideoFileClip(file_name) dst_clip = src_clip.fl_image( lambda frame: process_image(frame, camera, lane_object)) dst_clip.write_videofile(get_out_file_name(file_name), audio=False)
def test_shouldnt_change_lane_when_current_lane_is_fastest(self): car0 = Car(30, 0, 0, 10, 0) car1 = Car(20, 0, 0, 10, 0) car2 = Car(45, 0, 0, 10, 0) car3 = Car(50, 0, 0, 10, 0) lane0 = Lane() lane1 = Lane() lane2 = Lane() lane0.add_car(car0) lane1.add_car(car1) lane1.add_car(car3) lane2.add_car(car2) light = TrafficLight(100) self.assertFalse( control.should_change_lane_to_move_faster(car1, lane1, [lane0, lane2], [light]))
def test_refusal_to_create_expensive_feed(self): facets = Facets.default() pagination = Pagination.default() lane = Lane(self._db, "My Lane", languages=['eng', 'chi']) args = (self._db, lane, CachedFeed.PAGE_TYPE, facets, pagination, None) # If we ask for a group feed that will be cached forever, and it's # not around, we'll get a page feed instead. feed, fresh = CachedFeed.fetch(*args, max_age=Configuration.CACHE_FOREVER) eq_(CachedFeed.PAGE_TYPE, feed.type) # If we ask for the same feed, but we don't say it must be cached # forever, it'll be created. feed, fresh = CachedFeed.fetch(*args, max_age=0) # Or if we explicitly demand that the feed be created, it will # be created. feed, fresh = CachedFeed.fetch(*args, force_refresh=True, max_age=Configuration.CACHE_FOREVER) feed.update("Cache this forever!") # Once the feed has content associated with it, we can ask for # it in cached-forever mode and no longer get the exception. feed, fresh = CachedFeed.fetch(*args, max_age=Configuration.CACHE_FOREVER) eq_("Cache this forever!", feed.content)
def test_lifecycle(self): facets = Facets.default() pagination = Pagination.default() lane = Lane(self._db, "My Lane", languages=['eng', 'chi']) # Fetch a cached feed from the database--it's empty. args = (self._db, lane, CachedFeed.PAGE_TYPE, facets, pagination, None) feed, fresh = CachedFeed.fetch(*args, max_age=0) eq_(False, fresh) eq_(None, feed.content) eq_(pagination.query_string, feed.pagination) eq_(facets.query_string, feed.facets) eq_(lane.name, feed.lane_name) eq_('eng,chi', feed.languages) # Update the content feed.update("The content") self._db.commit() # Fetch it again. feed, fresh = CachedFeed.fetch(*args, max_age=0) # Now it's cached! But not fresh, because max_age is zero eq_("The content", feed.content) eq_(False, fresh) # Lower our standards, and it's fresh! feed, fresh = CachedFeed.fetch(*args, max_age=1000) eq_("The content", feed.content) eq_(True, fresh)
def test_query_works_from_lane_definition_handles_exclude_languages(self): search = DummyExternalSearchIndex() lane = Lane( self._db, self._default_library, "Not english or spanish", exclude_languages=set(['eng', 'spa']), ) filter = search.make_filter( lane.media, lane.languages, lane.exclude_languages, lane.fiction, list(lane.audiences), lane.age_range, lane.genre_ids, ) exclude_languages_filter, medium_filter = filter['and'] expect_exclude_languages = ['eng', 'spa'] assert 'not' in exclude_languages_filter assert 'terms' in exclude_languages_filter['not'] assert 'language' in exclude_languages_filter['not']['terms'] eq_(expect_exclude_languages, sorted(exclude_languages_filter['not']['terms']['language']))
def __init__(self): self.image_shape = [0, 0] self.camera_calibration_path = '../camera_cal/' self.output_images_path = '../output_images/' self.input_video_path = '../input_video/' self.output_video_path = '../output_video/' self.sobel_kernel_size = 7 self.sx_thresh = (60, 255) self.sy_thresh = (60, 150) self.s_thresh = (170, 255) self.mag_thresh = (40, 255) self.dir_thresh = (.65, 1.05) self.wrap_src = np.float32([[595, 450], [686, 450], [1102, 719], [206, 719]]) self.wrap_dst = np.float32([[320, 0], [980, 0], [980, 719], [320, 719]]) self.mask_offset = 30 self.vertices = [np.array([[206-self.mask_offset, 719], [595-self.mask_offset, 460-self.mask_offset], [686+self.mask_offset, 460-self.mask_offset], [1102+self.mask_offset, 719]], dtype=np.int32)] self.mask_offset_inverse = 30 self.vertices_inverse = [np.array([[206+self.mask_offset_inverse, 719], [595+self.mask_offset_inverse, 460-self.mask_offset_inverse], [686-self.mask_offset_inverse, 460-self.mask_offset_inverse], [1102-self.mask_offset_inverse, 719]], dtype=np.int32)] self.thresh = Threshold() self.lane = Lane()
def test_lane_query_with_configured_opds(self): """The appropriate opds entry is deferred during querying. """ original_setting = Configuration.DEFAULT_OPDS_FORMAT lane = Lane(self._db, "Everything") # Verbose config doesn't query simple OPDS entries. Configuration.DEFAULT_OPDS_FORMAT = "verbose_opds_entry" works_query_str = str(lane.works()) mw_query_str = str(lane.materialized_works()) assert "verbose_opds_entry" in works_query_str assert "verbose_opds_entry" in mw_query_str assert "works.simple_opds_entry" not in works_query_str assert "simple_opds_entry" not in mw_query_str # Simple config doesn't query verbose OPDS entries. Configuration.DEFAULT_OPDS_FORMAT = "simple_opds_entry" works_query_str = str(lane.works()) mw_query_str = str(lane.materialized_works()) assert "works.simple_opds_entry" in works_query_str assert "simple_opds_entry" in mw_query_str assert "verbose_opds_entry" not in works_query_str assert "verbose_opds_entry" not in mw_query_str Configuration.DEFAULT_OPDS_FORMAT = original_setting
def test_get_search_target(self): fantasy, ig = Genre.lookup(self._db, classifier.Fantasy) lane = Lane( self._db, "YA Fantasy", genres=fantasy, languages='eng', audiences=Lane.AUDIENCE_YOUNG_ADULT, age_range=[15,16], subgenre_behavior=Lane.IN_SUBLANES ) sublanes = lane.sublanes.lanes names = sorted([x.name for x in sublanes]) eq_(["Epic Fantasy", "Historical Fantasy", "Urban Fantasy"], names) # To start with, none of the lanes are searchable. eq_(None, lane.search_target) eq_(None, sublanes[0].search_target) # If we make a lane searchable, suddenly there's a search target. lane.searchable = True eq_(lane, lane.search_target) # The searchable lane also becomes the search target for its # children. eq_(lane, sublanes[0].search_target)
def test_staff_picks_and_best_sellers_sublane(self): staff_picks, ignore = self._customlist( foreign_identifier=u"Staff Picks", name=u"Staff Picks!", data_source_name=DataSource.LIBRARY_STAFF, num_entries=0) best_sellers, ignore = self._customlist( foreign_identifier=u"NYT Best Sellers", name=u"Best Sellers!", data_source_name=DataSource.NYT, num_entries=0) lane = Lane(self._db, "Everything", include_staff_picks=True, include_best_sellers=True) # A staff picks sublane and a best-sellers sublane have been # created for us. best, picks = lane.sublanes.lanes eq_("Best Sellers", best.display_name) eq_("Everything - Best Sellers", best.name) nyt = DataSource.lookup(self._db, DataSource.NYT) eq_(nyt.id, best.list_data_source_id) eq_("Staff Picks", picks.display_name) eq_("Everything - Staff Picks", picks.name) eq_([staff_picks.id], picks.list_ids)
def process_image(file_name, path, show): """ Loads a given image path, and applies the pipeline to it :param file_name: The name of the file (without extension) :param path: Path to the input (image, video) to process. :param show: Show the outcome :return: None """ # load the image image = cv2.imread(path, cv2.IMREAD_UNCHANGED) height, width = image.shape[:2] # initialize the objects threshold = Threshold() lane = Lane(height=height) camera = Camera(image_size=(width, height)) transform = Transform(width=width, height=height) # process the frame output = pipeline(image, camera, threshold, transform, lane) # save the output cv2.imwrite(f'data/processed/output_images/{file_name}.jpg', output)