When running this code the desired outcome is for the line drawn to be red but it is drawing a black line. I am confused since I wrote the BGR code for white but it seems that is it is just working in greyscale. Here is the complete code(The specific line where the line is drawn is in line 73 if you want to jump to it):
import cv2 as cv
import numpy as np
from skimage.measure import LineModelND, ransac
min_samples = 10 # This is the minimum amount of points/pixels that can form a line
class RansacLineInfo(object):
"""Helper class to manage the information about the RANSAC line."""
def __init__(self, inlier_points: np.ndarray, model: LineModelND):
self.inliers = inlier_points # the inliers that were detected by RANSAC algo
self.model = model # The LinearModelND that was a result of RANSAC algo
@property
def unitvector(self):
"""The unitvector of the model. This is an array of 2 elements (x,y)"""
return self.model.params[1]
# This function gets all of the white pixels in the image and stores the coordinates
def get_white_pixels(image_as_array):
threshold = 40
indices = np.where(image_as_array >= threshold)
width = image_as_array.shape[1]
height = image_as_array.shape[0]
np_data_points = np.column_stack((indices[0], indices[1]))
return np_data_points, width, height
# This function is in charge of separating which pixels form the first RANSAC line identifiable
def extract_first_ransac_line(data_points: [], max_distance: int):
model_robust, inliers = ransac(data_points, LineModelND, min_samples=min_samples,
residual_threshold=max_distance, max_trials=1000)
results_inliers = []
results_inliers_removed = []
for i in range(len(data_points)):
if not inliers[i]:
results_inliers_removed.append(data_points[i])
continue
x = data_points[i][0]
y = data_points[i][1]
results_inliers.append((x, y))
return np.array(results_inliers), np.array(results_inliers_removed), model_robust
# This function obtains the points necessary to plot the RANSAC fitted lines
def generate_plottable_points_along_line(model: LineModelND, xmin: int, xmax: int, ymin: int, ymax: int):
unit_vector = model.params[1]
slope = abs(unit_vector[1] / unit_vector[0])
x_values = None
y_values = None
if slope > 1:
y_values = np.arange(ymin, ymax, 1)
x_values = model.predict_x(y_values)
else:
x_values = np.arange(xmin, xmax, 1)
y_values = model.predict_y(x_values)
np_data_points = np.column_stack((x_values, y_values))
return np_data_points
def superimpose_all_inliers(image, ransac_lines, width: float, height: float):
new_image = image.copy()
for line_index in range(len(ransac_lines)):
color = (0, 0, 255) # Red color in BGR format
ransac_lineinfo: RansacLineInfo = ransac_lines[line_index]
inliers = ransac_lineinfo.inliers
y_min = inliers[:, 1].min()
y_max = inliers[:, 1].max()
x_min = inliers[:, 0].min()
x_max = inliers[:, 0].max()
plottable_points = generate_plottable_points_along_line(ransac_lineinfo.model, xmin=x_min, xmax=x_max, ymin=y_min, ymax=y_max)
if len(plottable_points) > 1:
pt1 = (int(round(plottable_points[0][1])), int(round(plottable_points[0][0])))
pt2 = (int(round(plottable_points[-1][1])), int(round(plottable_points[-1][0])))
cv.line(new_image, pt1, pt2, color, 2)
return new_image
def extract_multiple_lines_and_save(inputfilename: str, iterations: int, max_distance: int, min_inliers_allowed: int):
results = []
all_black_points, width, height = get_white_pixels(inputfilename)
starting_points = all_black_points
for index in range(iterations):
if len(starting_points) <= min_samples:
print("No more points available. Terminating search for RANSAC")
break
inlier_points, inliers_removed_from_starting, model = extract_first_ransac_line(starting_points, max_distance=max_distance)
if len(inlier_points) < min_inliers_allowed:
print("Not sufficient inliers found %d, threshold=%d, therefore halting" % (len(inlier_points), min_inliers_allowed))
break
starting_points = inliers_removed_from_starting
results.append(RansacLineInfo(inlier_points, model))
print("Found %d RANSAC lines" % len(results))
superimposed_image = superimpose_all_inliers(inputfilename, results, width, height)
# Save the results
cv.imwrite("Resultado RANSAC3.jpg", superimposed_image)
print("Results saved to file")
image = cv.imread("framenumber0.jpg", cv.IMREAD_GRAYSCALE)
extract_multiple_lines_and_save(image, iterations=20, max_distance=10, min_inliers_allowed=50)
Here is the outcome, it is hard to tell but it drawing a line, but it is black and I want it to be red.
I tried googling to see if there was an interference with one of the libraries I was using but could not find any.
4