Python实现4x4网格图像转坐标及迷宫交点矩阵生成技术问询
Hey Luis, let's break down how to solve your problem step by step—turning that 4x4 grid image into a coordinate matrix, and identifying those red/blue points for your robot. Since you already have the filtered contours, we can build on that with OpenCV and Python:
A 4x4 grid of cells has a 5x5 matrix of intersections (since each row/column of cells adds one extra line at the edges). Here's how to convert your contour image into structured coordinates:
Step 1: Detect Horizontal/Vertical Grid Lines
Use Hough Line Transform to pull out the main grid lines from your filtered contour image:
import cv2 import numpy as np # Load your filtered contour image (binary, white lines on black background) img = cv2.imread('filtered_grid.png', 0) # Ensure it's inverted if lines are black img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV)[1] # Detect lines with HoughLinesP (adjust params for your image) lines = cv2.HoughLinesP( img, rho=1, theta=np.pi/180, threshold=50, minLineLength=img.shape[0] * 0.8, # Only keep long lines (grid edges) maxLineGap=10 ) # Separate horizontal and vertical lines horizontal_lines = [] vertical_lines = [] for line in lines: x1, y1, x2, y2 = line[0] # Horizontal lines have minimal y-change if abs(y2 - y1) < 10: horizontal_lines.append((y1, x1, x2)) # Vertical lines have minimal x-change elif abs(x2 - x1) < 10: vertical_lines.append((x1, y1, y2)) # Sort lines to get ordered rows/columns horizontal_lines.sort(key=lambda x: x[0]) # Sort by y-coordinate vertical_lines.sort(key=lambda x: x[0]) # Sort by x-coordinate
Step 2: Calculate Intersection Points
Each horizontal line intersects every vertical line—we'll turn these into a 5x5 coordinate matrix:
# Compute all intersections intersection_matrix = [] for h_line in horizontal_lines: y_h, _, _ = h_line row_coords = [] for v_line in vertical_lines: x_v, _, _ = v_line # Horizontal line is y=y_h, vertical is x=x_v → intersection at (x_v, y_h) row_coords.append((x_v, y_h)) intersection_matrix.append(row_coords) # Now you have a 5x5 matrix of (x,y) coordinates for grid intersections print("Grid Intersection Matrix:") for row in intersection_matrix: print(row)
Next, we'll detect the colored points and map them to their corresponding grid intersection indices:
Step 1: Isolate Colors with HSV Thresholding
Load the original color image and use HSV to filter red/blue regions:
# Load original drone image color_img = cv2.imread('drone_grid.png') hsv_img = cv2.cvtColor(color_img, cv2.COLOR_BGR2HSV) # Define HSV ranges for red (two ranges since red wraps HSV 0°) lower_red1 = np.array([0, 120, 70]) upper_red1 = np.array([10, 255, 255]) lower_red2 = np.array([170, 120, 70]) upper_red2 = np.array([180, 255, 255]) red_mask = cv2.inRange(hsv_img, lower_red1, upper_red1) | cv2.inRange(hsv_img, lower_red2, upper_red2) # Define HSV range for blue lower_blue = np.array([90, 120, 70]) upper_blue = np.array([130, 255, 255]) blue_mask = cv2.inRange(hsv_img, lower_blue, upper_blue)
Step 2: Find Point Centers & Map to Grid
Calculate the center of each colored blob, then find the closest grid intersection:
# Helper function to find closest grid intersection index def get_grid_index(point, intersection_matrix): min_dist = float('inf') best_index = (0, 0) for row_idx, row in enumerate(intersection_matrix): for col_idx, (x, y) in enumerate(row): dist = np.sqrt((point[0] - x)**2 + (point[1] - y)**2) if dist < min_dist: min_dist = dist best_index = (row_idx, col_idx) return best_index # Process red points red_contours, _ = cv2.findContours(red_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) red_grid_positions = [] for cnt in red_contours: if cv2.contourArea(cnt) > 10: # Filter out small noise blobs M = cv2.moments(cnt) cx = int(M['m10'] / M['m00']) cy = int(M['m01'] / M['m00']) red_grid_positions.append(get_grid_index((cx, cy), intersection_matrix)) # Process blue points blue_contours, _ = cv2.findContours(blue_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) blue_grid_positions = [] for cnt in blue_contours: if cv2.contourArea(cnt) > 10: M = cv2.moments(cnt) cx = int(M['m10'] / M['m00']) cy = int(M['m01'] / M['m00']) blue_grid_positions.append(get_grid_index((cx, cy), intersection_matrix)) print("\nRed Point Grid Positions (row, column):", red_grid_positions) print("Blue Point Grid Positions (row, column):", blue_grid_positions)
- Line Detection Params: Tweak
threshold,minLineLength, andmaxLineGapinHoughLinesPif you're getting extra noise lines or missing grid edges. - Color Thresholds: Use an HSV color picker tool to adjust the
lower_*/upper_*values—lighting and camera settings can change these drastically. - Perspective Correction: If your drone image has perspective distortion, first use
cv2.getPerspectiveTransformto warp the grid into a perfect rectangle. Pick four corner intersections as source points, map them to a target rectangle, then run the above steps on the corrected image.
内容的提问来源于stack exchange,提问作者Luis Cazares

