Reputation: 1
I'm trying to find the road in a certain image using canny algorithm but for some reason it keeps finding pixels that are not the road. This is the picture I came up with trying to find the road:
The map:
This is the code I'm trying to find the road with:
import cv2
import numpy as np
from matplotlib import pyplot as plt
def remove_red(image_path, save_path):
"""
Removes red pixels from the image and saves the result as a PNG image with transparency.
:param image_path: Path to the input image.
:param save_path: Path to save the output image.
"""
# Load the image with the possibility of having an alpha channel (transparency)
image = cv2.imread(image_path, cv2.IMREAD_UNCHANGED)
# Convert to BGRA (if not already) to support transparency
if image.shape[-1] != 4:
image = cv2.cvtColor(image, cv2.COLOR_BGR2BGRA)
# Create a mask for red pixels (Red channel > 100 and greater than Green & Blue)
red_mask = (image[:, :, 2] > 100) & (image[:, :, 2] > image[:, :, 1]) & (image[:, :, 2] > image[:, :, 0])
# Set red pixels to transparent (alpha = 0)
image[red_mask] = [0, 0, 0, 0] # Transparent
# Save the processed image
cv2.imwrite(save_path, image)
# Convert to RGB for correct display in Matplotlib (OpenCV uses BGRA)
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGRA2RGBA)
# Display the result using Matplotlib
plt.figure(figsize=(10, 6))
plt.imshow(image_rgb)
plt.title("Image Without Red")
plt.axis("off")
plt.show()
def detect_color_of_road(path, path_to_save):
# Read the images
image = cv2.imread(path)
# Resizing the image
# Convert Image to Image HSV
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
# Defining lower and upper bound HSV values
lower = np.array([100, 50, 50])
upper = np.array([120, 255, 255])
# Defining mask for detecting color
mask = cv2.inRange(hsv, lower, upper)
# Display Image and Mask
cv2.imshow("Mask", mask)
# Make python sleep for unlimited time
cv2.waitKey(0)
cv2.imwrite(path_to_save, mask)
def bresenham_line(x1, y1, x2, y2):
"""
Bresenham's Line Algorithm to get all pixel coordinates between two points.
:return: List of (x, y) pixel coordinates as plain Python integers
"""
points = []
dx = abs(x2 - x1)
dy = abs(y2 - y1)
sx = 1 if x1 < x2 else -1
sy = 1 if y1 < y2 else -1
err = dx - dy
while True:
points.append((int(x1), int(y1))) # Ensure output is a tuple of plain integers
if x1 == x2 and y1 == y2:
break
e2 = err * 2
if e2 > -dy:
err -= dy
x1 += sx
if e2 < dx:
err += dx
y1 += sy
return points
def detect_and_show_road(image_path):
"""
Detects road lines in the image, draws them in red, and displays the result.
:param image_path: Path to the input image
:return: List of (x, y) pixel coordinates as plain Python integers
"""
# Load the image
image = cv2.imread(image_path)
# Convert to grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Apply Gaussian Blur to reduce noise
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
# Detect edges using Canny Edge Detection
edges = cv2.Canny(blurred, 50, 150)
# Use Hough Line Transform to detect straight lines
lines = cv2.HoughLinesP(edges, 1, np.pi / 180, threshold=100, minLineLength=50, maxLineGap=10)
# Store pixel coordinates of detected lines
line_pixels = []
if lines is not None:
for line in lines:
x1, y1, x2, y2 = map(int, line[0]) # Convert to plain Python int
# Use Bresenham's algorithm to get all pixels along the line
points = bresenham_line(x1, y1, x2, y2)
line_pixels.extend(points)
# Draw the line on the image in RED
cv2.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2)
# Show the image with detected road lines
cv2.imshow("Detected Roads", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
return line_pixels
# Path to the image
image_path = r"C:\python_projects\macro\photos\map\above.png"
save_path = r"C:\python_projects\macro\photos\map\without_red.png"
# Remove red pixels and save the result
remove_red(image_path, save_path)
detect_color_of_road(image_path, save_path)
# Detect and show roads from the processed image
road_pixels = detect_and_show_road(save_path)
# Print first few pixel coordinates (for verification)
print(road_pixels)
This is the result:
I tried to erase all the red from the image to make it easier for the canny algorithm to find the road but it didn't work. My end goal was to find the road and return an array of pixels along the edges of the road.
Upvotes: 0
Views: 48