image = cv2.imread(“0.0/01.pgm”, cv2.COLOR_BGR2GRAY)


def get_coords_by_threshold(image: np.ndarray, threshold: int = 150) -> tuple:
“”“Gets pixel coords with intensity more then ‘theshold’.”“”
coords = np.where(image > threshold)
return coords


def delete_pixels_by_min_threshold(
image: np.ndarray, min_threshold: int = 100
) -> np.ndarray:
“”“Deletes coords from image and returns this image.”“”
anti_coords = np.where(image < min_threshold)
image[anti_coords] = 0
return image


def get_neigh_nums_list(
coords: tuple, kernel_size: int = 3
) -> list:
“”“
Gets list with number of neighborhoods by kernel.
Returns list like [[x1, y1, N1], [x2, y2, N2]],
Where N - neighborhood’s number.
“””
neigh_nums = []
offset = (kernel_size - 1) // 2

for x, y in zip(coords[0], coords[1]):
if x < 0 + offset or x > image.shape[0] - offset:
continue
if y < 0 + offset or y > image.shape[1] - offset:
continue

kernel = image[x-offset:x+offset+1, y-offset:y+offset+1]
step_neigh_num = np.count_nonzero(kernel) - 1
neigh_nums.append([x, y, step_neigh_num])

return neigh_nums


def sort_neight_nums_by_N(neigh_nums: list) -> np.ndarray:
“”“
Sort neigh_nums by N parameter.
Removes N=-1, N=0 and sorts by N desc. 
“””
np_neigh_nums = np.array(neigh_nums)

np_neigh_nums = np_neigh_nums[
(np_neigh_nums[:, 2] != -1) & (np_neigh_nums[:, 2] != 0)]

np_neigh_nums = np_neigh_nums[
np.argsort(-np_neigh_nums[:, 2])]

return np_neigh_nums


def get_potential_points_coords(
sorted_niegh_nums: np.ndarray, potential_points_num: int = 30
) -> np.ndarray:
“”“
Gets best candidates, potential points coords only.
Returns np.ndarray like [[x1, y1], [x2, y2]].
“””
sorted_neigh_nums = np.delete(sorted_niegh_nums, 2, axis=1)
return sorted_neigh_nums[:potential_points_num]


def get_best_lines(potential_points: np.ndarray) -> np.ndarray:
“”“
Gets best combinations of lines by all points.
Line y = kx + b.
Returns np.ndarray like [[k1, b1], [k2, b2]].
“””
pass



# main
coords = get_coords_by_threshold(image)

image = delete_pixels_by_min_threshold(image)

neigh_nums = get_neigh_nums_list(coords)

sorted_neigh_nums = sort_neight_nums_by_N(neigh_nums)

potential_points = get_potential_points_coords(sorted_neigh_nums)

best_lines = get_best_lines(potential_points)
print(best_lines)

# Visualization
plt.imshow(image, cmap=“gray”)
plt.scatter(potential_points[:, 1], potential_points[:, 0], color=“red”, marker=“o”)
plt.show()

# # Plot the lines on the image
# for equation in best_lines:
# k, b = equation
# x = np.arange(0, image.shape[1])
# y = k * x + b
# plt.imshow(image, cmap=“gray”)
# plt.scatter(potential_points[:, 1], potential_points[:, 0], color=“red”, marker=“o”)
# plt.plot(x, y, color=“green”)
# plt.scatter(potential_points[:, 1], potential_points[:, 0], color=“red”, marker=“o”)
# plt.show()

Допиши метод get_best_lines так, чтобы он возвращал три лучших прямых, таких, что максимальное количество potential_points (потенциальных точек) лежат в окрестности 3 пикселя от прямой и k и b этих прямых не слишком похожи (tolerance_k=0.1, tolerance_b=10). То есть нужно вернуть три самых попадающих в точки прямых, но разных (детекция прямых, образующих треугольник). Для выполнения этой задачи можно использовать только numpy. Можно использовать только numpy