Beispiel #1
0
 def test_distance_of_0_0_from_flat_line_yintercept_is_zero(self):
     x = LineModel(0, 1, -3)
     test_point = Point(0, 0)
     distance_actual = x.compute_distance(test_point)
     distance_expected = 3
     self.assertEqual(distance_actual, distance_expected)
     pass
Beispiel #2
0
 def test_distance_of_origin_from_slope_45degrees_yintercept_is_zero(self):
     x = LineModel(-1, 1, 0)
     test_origin = Point(0, 0)
     distance_actual = x.compute_distance(test_origin)
     distance_expected = 0
     self.assertEqual(distance_actual, distance_expected)
     pass
Beispiel #3
0
 def test_distance_of_1_0_from_slope_45degrees_yintercept_is_zero(self):
     x = LineModel(-1, 1, 0)
     test_point = Point(1, 0)
     distance_actual = x.compute_distance(test_point)
     distance_expected = 1 / math.sqrt(2)
     self.assertEqual(distance_actual, distance_expected)
     pass
Beispiel #4
0
    def test_x_y_intercept_45_degrees_1_0(self):
        line = LineModel(-1, 1, 1)
        xintercept_actual = line.xintercept()
        xintercept_expected = 1
        yintercept_actual = line.yintercept()
        yintercept_expected = -1

        self.assertEqual(xintercept_actual, xintercept_expected)
        self.assertEqual(yintercept_actual, yintercept_expected)
Beispiel #5
0
    def test_x_y_intercept_90_degrees_5_inf(self):
        line = LineModel(1, 0, -5)
        xintercept_actual = line.xintercept()
        xintercept_expected = 5
        yintercept_actual = line.yintercept()
        yintercept_expected = math.inf

        self.assertEqual(xintercept_actual, xintercept_expected)
        self.assertEqual(yintercept_actual, yintercept_expected)
Beispiel #6
0
    def test_x_y_intercept_0_degrees_inf_5(self):
        line = LineModel(0, 1, -5)
        xintercept_actual = line.xintercept()
        xintercept_expected = math.inf
        yintercept_actual = line.yintercept()
        yintercept_expected = 5

        self.assertEqual(xintercept_actual, xintercept_expected)
        self.assertEqual(yintercept_actual, yintercept_expected)
Beispiel #7
0
 def test_generate_points_from_line_90_degrees_passing_through_5_0(self):
     line = LineModel(1, 0, -5)
     x1 = 20
     x2 = 40
     y1 = 10
     y2 = 30
     new_points = LineModel.generate_points_from_line(line, x1, y1, x2, y2)
     for p in new_points:
         print("Testing point=%s" % (p))
         self.assertTrue(p.Y >= y1)
         self.assertTrue(p.Y <= y2)
Beispiel #8
0
 def test_generate_points_from_line_45_degrees_passing_through_0_0(self):
     line = LineModel(-1, 1, 0)
     x1 = 20
     x2 = 40
     y1 = 10
     y2 = 30
     new_points = LineModel.generate_points_from_line(line, x1, y1, x2, y2)
     for p in new_points:
         print("Testing point=%s" % (p))
         self.assertTrue(p.X >= x1)
         self.assertTrue(p.X <= x2)
Beispiel #9
0
 def compute_average_distance(self, model: LineModel,
                              points: list) -> float:
     lst_distances = list()
     for p in points:
         distance = model.compute_distance(p)
         lst_distances.append(distance)
     mean = statistics.mean(lst_distances)
     return mean
Beispiel #10
0
    def create_model(self, points: list) -> LineModel:

        mean_x = 0
        mean_y = 0
        for p in points:
            mean_x += p.X
            mean_y += p.Y
        mean_x = mean_x / len(points)
        mean_y = mean_y / len(points)

        slope_numerator = 0
        slope_denominator = 0
        slope = 0
        #use the formula for least squares
        for p in points:
            slope_numerator += (p.X - mean_x) * (p.Y - mean_y)
            slope_denominator += (p.X - mean_x) * (p.X - mean_x)

        if (math.fabs(slope_denominator) < 0.001):
            #perpendicular line
            x_intercept = mean_x
            #equation   (1)x + (0)y + (-xintercept) + 1
            vertical_line_a = 1
            vertical_line_b = 0
            vertical_line_c = -x_intercept
            model = LineModel(vertical_line_a, vertical_line_b,
                              vertical_line_c)
            return model

        slope = slope_numerator / slope_denominator
        y_intercept = mean_y - (slope * mean_x)

        line_a = slope
        line_b = -1
        line_c = y_intercept
        #  standard form of line equation
        #  ------------------------------
        #   y=mx+c
        #   mx  -   y   +   c=0
        #   ax  +   by  +   c=0
        #   slope= -a/b
        #   yint= -c/b
        #
        model = LineModel(line_a, line_b, line_c)
        return model
Beispiel #11
0
 def test_add_points_to_line(self):
     model = LineModel.create_line_from_2points(0, 0, 100, 100)
     test_point1 = Point(1, 0)
     test_point2 = Point(2, 0)
     model.points.append(test_point1)
     model.points.append(test_point2)
     self.assertTrue(test_point1 in model.points)
     self.assertTrue(test_point2 in model.points)
     self.assertTrue(len(model.points) == 2)
Beispiel #12
0
    def test_projection_of_points_on_line_with_slope_45degrees_through_origin(
            self):
        line = LineModel(-1, 1, 0)
        test_point1 = Point(4, 0)
        expected_projected1 = Point(2, 2)

        test_point2 = Point(0, 4)
        expected_projected2 = Point(2, 2)

        lst_inputs = [test_point1, test_point2]
        lst_expected = [expected_projected1, expected_projected2]

        lst_actual = LineModel.compute_projection_of_points(line, lst_inputs)

        for index in range(0, len(lst_inputs)):
            actual = lst_actual[index]
            expected = lst_expected[index]
            self.assertAlmostEqual(actual.X, expected.X, 0.1)
            self.assertAlmostEqual(actual.Y, expected.Y, 0.1)
Beispiel #13
0
 def compute_mean_squared_distance(self, model: LineModel,
                                   points: list) -> float:
     lst_distances = list()
     for p in points:
         distance = model.compute_distance(p)
         lst_distances.append(distance**2)
     sum_of_squared_distances = sum(lst_distances)
     sqroot = sum_of_squared_distances**0.5
     mean = sqroot / len(lst_distances)
     return mean
Beispiel #14
0
 def test_create_line_from_start_and_end_vertical_line(self):
     start_x = 1
     start_y = 5
     end_x = 1
     end_y = 25
     model = LineModel.create_line_from_2points(start_x, start_y, end_x,
                                                end_y)
     expected_B = 0
     expected_x_intercept = start_x
     self.assertAlmostEqual(model.B, 0)
     self.assertAlmostEqual(model.C / model.A, -expected_x_intercept)
Beispiel #15
0
 def get_inliers_from_model(self, model: LineModel,
                            points_old_inliers: list) -> list:
     lst_inliers = list()
     for p in self.points:
         if ((p in points_old_inliers) == True):
             continue
         distance_from_model: float = model.compute_distance(p)
         if (distance_from_model > self.threshold_error):
             continue
         lst_inliers.append(p)
     return lst_inliers
Beispiel #16
0
 def test_generate_points_at_regular_intervals_stline(self):
     start_x = 0
     start_y = 1
     end_x = 10
     end_y = 11
     model = LineModel.create_line_from_2points(start_x, start_y, end_x,
                                                end_y)
     slope = -model.A / model.B
     yintercept = -model.C / model.B
     gap = 5
     new_points = LineModel.generate_points_at_regular_intervals_stline(
         start_x, start_y, end_x, end_y, gap)
     count_of_new_points = len(new_points)
     self.assertTrue(count_of_new_points > 0)
     self.assertTrue(count_of_new_points < 4)
     for new_point in new_points:
         new_x = new_point.X
         new_y = new_point.Y
         expected_y = slope * new_x + yintercept
         self.assertAlmostEqual(new_y, expected_y)
Beispiel #17
0
 def test_create_line_from_start_and_end_horizontal_line(self):
     start_x = 0
     start_y = 1
     end_x = 1
     end_y = 2
     model = LineModel.create_line_from_2points(start_x, start_y, end_x,
                                                end_y)
     #equation ax+by+c=0
     #slope=-a/b
     #yinter=-c/b
     expected_slope = 1
     expected_y_intercept = 1
     self.assertAlmostEqual(model.A / model.B, -expected_slope)
     self.assertAlmostEqual(model.C / model.B, -expected_y_intercept)
Beispiel #18
0
 def test_run_with_very_simple_image(self):
     #
     #get a list of points
     #
     folder_script=os.path.dirname(__file__)
     filename_input="Line_50x30.png"
     file_noisy_line=os.path.join(folder_script,"./data/",filename_input)
     np_image=skimage.io.imread(file_noisy_line,as_gray=True)
     lst_points=Util.create_points_from_numpyimage(np_image)
     #
     #initialize RansalHelper
     #
     helper1=RansacLineHelper()
     helper1.add_points(lst_points)
     helper1.max_iterations=1000
     #10000 did not work
     helper1.min_points_for_model=2
     helper1.threshold_error=3 #10
     helper1.threshold_inlier_count=3
     result_model=helper1.run()
     print("RANSAC-complete")    
     print("Found model %s , polar=%s" % (result_model,result_model.display_polar()))
     #
     #Superimpose the new line over the image
     #
     folder_results=os.path.join(folder_script,"../out/")
     count_of_files=len(os.listdir(folder_results))
     filename_results=("Line_50x30.%d.png" % (count_of_files) )
     file_result=os.path.join(folder_results,filename_results)
     x_lower=0
     x_upper=np_image.shape[1]-1
     y_lower=0
     y_upper=np_image.shape[0]-1
     new_points=LineModel.generate_points_from_line(result_model,x_lower,y_lower,x_upper,y_upper)
     np_superimposed=Util.superimpose_points_on_image(np_image,new_points,100,255,100)
     skimage.io.imsave(file_result,np_superimposed)
     #
     #Asserts!
     #
     x_intercept=result_model.xintercept()
     y_intercept=result_model.yintercept()
     self.assertTrue ( x_intercept > 30,"X intercept below threshold")
     self.assertTrue ( x_intercept < 50,"X intercept above threshold")
     self.assertTrue ( y_intercept > 30,"Y intercept above threshold")
     self.assertTrue ( y_intercept < 45,"Y intercept below threshold")
     self.assertTrue(len(result_model.points),5)
     for pt in result_model.points:
         distance_from_line=result_model.compute_distance(pt)
         self.assertTrue(distance_from_line <= helper1.threshold_error)
Beispiel #19
0
def run_ransac(filename):
    folder_script = os.path.dirname(__file__)

    #Images which did not generate good results:
    #   NoisyImage_3.png
    #   NoisyLine-Gaussian-sp-0.80.111.png
    file_noisy_line = os.path.join(folder_script, "./input/", filename)
    np_image = skimage.io.imread(file_noisy_line, as_gray=True)
    #
    #Iterate over all cells of the NUMPY array and convert to array of Point classes
    #
    lst_all_points = Util.create_points_from_numpyimage(np_image)

    #
    #begin RANSAC
    #
    ransac_maxiterations = 12000
    #12000
    #6000
    #12000 worked well
    ransac_minpoints = 5
    #5 worked well
    #2 gave very bad results
    #20 worked well
    ransac_threshold = 5
    #25 worked well for 'NoisyLine-Gaussian-sp-0.80.104.png' 15 and 5 did not
    #Nothing worked well for 'NoisyLine-Gaussian-sp-0.80.111.png" , tried increasing to 35
    #3 for first set when points were much closer
    #5 produced too much deviation

    ransac_mininliers = 10

    helper = RansacLineHelper()
    helper.max_iterations = ransac_maxiterations
    helper.min_points_for_model = ransac_minpoints
    helper.threshold_error = ransac_threshold
    helper.threshold_inlier_count = ransac_mininliers
    helper.add_points(lst_all_points)
    model = helper.run()

    #Display the model , you could render over the original picture
    print("-------------------------------------")
    print("RANSAC-complete")
    print("Found model %s , polar=%s" % (model, model.display_polar()))
    #
    #Generate an output image with the model line
    #
    filename_noextension = no_extension = os.path.splitext(filename)[0]
    now = datetime.datetime.now()
    filename_result = ("%s-%s.result.png") % (
        filename_noextension, now.strftime("%Y-%m-%d-%H-%M-%S"))
    file_result = os.path.join(folder_script, "./out/", filename_result)
    #Load input image into array
    np_image_result = skimage.io.imread(file_noisy_line, as_gray=True)
    new_points = LineModel.generate_points_from_line(
        model, 0, 0, np_image_result.shape[1] - 1,
        np_image_result.shape[0] - 1)
    np_superimposed = Util.superimpose_points_on_image(np_image_result,
                                                       new_points, 100, 255,
                                                       100)
    #Save new image
    skimage.io.imsave(file_result, np_superimposed)
Beispiel #20
0
 def test_display_polar(self):
     line = LineModel(-1, 1, 1)
     s = line.display_polar()
     print(s)
Beispiel #21
0
 def test_construction(self):
     x = LineModel(100, 200, 300)
     self.assertEqual(x.A, 100)
     self.assertEqual(x.B, 200)
     self.assertEqual(x.C, 300)
     pass