def __generate_diagonallines(self, image_array): # #You were here # # width = image_array.shape[1] height = image_array.shape[0] all_points = [] pointA: sg.Point = sg.Point(0, np.random.rand() * height * 1 / 2) pointB: sg.Point = sg.Point(width, height * 1 / 2 * (1 + np.random.rand())) points_AB = self.__generate_points_along_p1p2( pointA, pointB, self._max_distance_consecutive_points) all_points.extend(points_AB) pointC: sg.Point = sg.Point(0, height * 1 / 2 * (1 + np.random.rand())) pointD: sg.Point = sg.Point(width, height * 1 / 2 * np.random.rand()) points_CD = self.__generate_points_along_p1p2( pointC, pointD, self._max_distance_consecutive_points) all_points.extend(points_CD) image_result = sg.Util.superimpose_points_on_image( image_array, all_points, 0, 0, 0) return image_result
def create_linemodel_from_scikit_model(self,scikitmodel)->sg.LineModel: origin=sg.Point(scikitmodel.params[0][0],scikitmodel.params[0][1]) unitvector=sg.Point(scikitmodel.params[1][0],scikitmodel.params[1][1]) first_point=origin second_point=sg.Point(first_point.X + unitvector.X*10, first_point.Y+unitvector.Y*10) lineequation=sg.LineModel.create_line_from_2points(first_point.X,first_point.Y, second_point.X, second_point.Y) return lineequation
def find_inliers_from_all_points(self, circle_equation: sg.CircleModel, threshold: float): resulting_inlier_tuples = [] center = sg.Point(circle_equation.X, circle_equation.Y) for black_pixel in self.__all_black_points: black_point = sg.Point(black_pixel[0], black_pixel[1]) radial_distance = sg.Point.euclidean_distance(point1=black_point, point2=center) if (abs(radial_distance - circle_equation.R) > threshold): continue resulting_inlier_tuples.append((black_point.X, black_point.Y)) arr = np.array(resulting_inlier_tuples) return arr
def __checkforinitialization(self): if (self.__model == None): raise Exception( "The class has not been initialized with a CircleModel") if (self.__center == None): self.__center = sg.Point(self.model.params[0], self.model.params[1])
def __generate_xy_from_custom_function(self, image_array): max_distance = self._max_distance_consecutive_points x_start = 0 width = image_array.shape[1] height = image_array.shape[0] x_end = width y_origin = height / 2 delta_x = width * 0.25 #an approx gap to being with x_last = x_start y_last = self.__InvokeAnyFunction( x_last, width=width, height=height ) + y_origin #add a new private functoin and property to decide which type of curve pts_new = list() while (x_last < x_end): gap = delta_x while (True): x_new = x_last + gap y_new = self.__InvokeAnyFunction( x_new, width=width, height=height) + y_origin dsquare = (x_new - x_last)**2 + (y_new - y_last)**2 d = dsquare**0.5 if (d <= max_distance): pt_new = sg.Point(x_new, y_new) pts_new.append(pt_new) x_last = x_new y_last = y_new break else: gap = gap * 0.5 #reduce the gap and try again continue image_result = sg.Util.superimpose_points_on_image( image_array, pts_new, 0, 0, 0) return image_result pass
def __generate_points_along_p1p2(self, pointA: sg.Point, pointB: sg.Point, gap: float): magnitude = math.sqrt((pointA.X - pointB.X)**2 + (pointA.Y - pointB.Y)**2) unit_vector = sg.Point((pointB.X - pointA.X) / magnitude, (pointB.Y - pointA.Y) / magnitude) t = 0 results = [] mean_gap = self.max_consecutive_distance std_gap = mean_gap / 5 while (t < magnitude): dynamic_gap = np.random.normal(mean_gap, std_gap) new_point = sg.Point(pointA.X + t * unit_vector.X, pointA.Y + t * unit_vector.Y) results.append(new_point) t += dynamic_gap #print("dynamic gap=%f" % (dynamic_gap)) return results
def find_common_inliers(self,line1:RansacLineInfo,line2:RansacLineInfo): line1_inliers = line1.inliers line2_inliers = line2.inliers results=[] for line1_inlier in line1_inliers: for line2_inlier in line2_inliers: if ((line1_inlier.X == line2_inlier.X) and (line1_inlier.Y == line2_inlier.Y)): common_point=sg.Point(line1_inlier.X,line1_inlier.Y) results.append(common_point) return results
def test_with_2_simple_circles_inliers_mustbe_shared_and_ransacthresholdspike_stopping_criteria( self): all_black_points, width, height = self.read_test_image( filenameonly="two-simple-circles.png") finder = RansacCircleFinder(pixels=all_black_points, width=width, height=height, nnd_threshold_factor=1, max_ransac_trials=200) finder.stopping_criteria = StoppingCriteria.RANSAC_THRESHOLD_SPIKE finder.ransac_threshold_spike_factor = 2 ransac_circles = finder.find() first_circle = ransac_circles[0] second_circle = ransac_circles[1] for circle_result in range(0, len(ransac_circles)): self.superimpose_resulting_circle( imagefilename="two-simple-circles.png", resultfilename= f"two-simple-circles.{circle_result}.superimposed.png", circle=ransac_circles[circle_result]) first_circle_inliers = list( map(lambda x: sg.Point(x[0], x[1]), first_circle.inlier_points)) second_circle_inliers = list( map(lambda x: sg.Point(x[0], x[1]), second_circle.inlier_points)) count_of_overlaps = 0 for first_circle_inlier in first_circle_inliers: for second_circle_inlier in second_circle_inliers: if ((first_circle_inlier.X == second_circle_inlier.X) and (first_circle_inlier.Y == second_circle_inlier.Y)): count_of_overlaps = count_of_overlaps + 1 self.assertGreater( count_of_overlaps, 1, "There must be 1 or more common inliers between the 2 ransac circles" )
def __generate_circle(self, image_array): max_distance = self._max_distance_consecutive_points min_distance = max_distance / 2 width = image_array.shape[1] height = image_array.shape[0] theta = 0 delta_theta = 0.1 origin_x = width / 2 origin_y = height / 2 radius = width / 10 pts_new = list() x_last = origin_x y_last = origin_y while (True): x = radius * math.cos(theta) y = radius * math.sin(theta) x_new = x + origin_x y_new = y + origin_y if (x_new > width): break if (y_new > height): break if (theta > 2 * math.pi): break distance_from_lastpoint = ((x_new - x_last)**2 + (y_new - y_last)**2)**0.5 if (len(pts_new) == 0) or ((distance_from_lastpoint < max_distance) and (distance_from_lastpoint >= min_distance)): pt_new = sg.Point(x_new, y_new) pts_new.append(pt_new) x_last = x_new y_last = y_new theta = theta + delta_theta elif (distance_from_lastpoint < min_distance): delta_theta = delta_theta * 1.1 theta = theta + delta_theta else: delta_theta = delta_theta * 0.9 theta = theta - delta_theta image_result = sg.Util.superimpose_points_on_image( image_array, pts_new, 0, 0, 0) return image_result
def __generate_spiral(self, image_array): max_distance = self._max_distance_consecutive_points min_distance = max_distance / 2 width = image_array.shape[1] height = image_array.shape[0] theta = 0 delta_theta = 0.1 origin_x = width / 2 origin_y = height / 2 distance_x_at_2pie = width / 10 #Where does the spiral intersect the X axis at 2pie radians const_a = (distance_x_at_2pie / (2 * math.pi)) pts_new = list() x_last = origin_x y_last = origin_y while (True): r = const_a * theta x = r * math.cos(theta) y = r * math.sin(theta) x_new = x + origin_x y_new = y + origin_y if (x_new > width): break if (y_new > height): break distance_from_lastpoint = ((x_new - x_last)**2 + (y_new - y_last)**2)**0.5 if (distance_from_lastpoint < max_distance) and ( distance_from_lastpoint >= min_distance): pt_new = sg.Point(x_new, y_new) pts_new.append(pt_new) x_last = x_new y_last = y_new theta = theta + delta_theta elif (distance_from_lastpoint < min_distance): delta_theta = delta_theta * 1.1 theta = theta + delta_theta else: delta_theta = delta_theta * 0.9 theta = theta - delta_theta image_result = sg.Util.superimpose_points_on_image( image_array, pts_new, 0, 0, 0) return image_result
def superimpose_resulting_circle(self, imagefilename: str, resultfilename: str, circle: RansacCircleInfo): folder_script = os.path.dirname(__file__) original_imagefilename = os.path.join(folder_script, "test", imagefilename) result_imagefilename = os.path.join(folder_script, "out", resultfilename) np_original_image = skimage.io.imread(original_imagefilename, as_gray=True) points_list = list( map(lambda x: sg.Point(x[0], x[1]), circle.inlier_points)) np_newimage = sg.Util.superimpose_points_on_image( np_original_image, points_list, 255, 255, 0) skimage.io.imsave(result_imagefilename, np_newimage) pass
def plot_ransac_circles_with_projections(cls, model: RootModel): inputfilepath: str = model.filename circles = model.ransac_circles print(f"Superimposing circles on base image: {inputfilepath}") for result_index in range(0, len(circles)): circle = circles[result_index] np_blank_image = skimage.io.imread(inputfilepath, as_gray=True) np_blank_image.fill(1) new_filename = f"circle-result-{result_index}-inlier-{len(circle.inlier_points)}-threshold-{round(circle.ransac_threshold,2)}-nnd-{round(circle.mean_nnd,2)}.png" absolute_path = os.path.join(model.output_folder, new_filename) print(f"Got a circle {circle}, saving to file {absolute_path}") points_list = list( map(lambda x: sg.Point(x[0], x[1]), circle.projected_inliers)) np_newimage = sg.Util.superimpose_points_on_image( np_blank_image, points_list, 255, 0, 0) skimage.io.imsave(absolute_path, np_newimage) pass