从图像红色轮廓提取的无序点中查找合理路径的方案及库问询
解决方法
一、直接调用现有库(推荐,效率最高)
OpenCV的cv2.findContours()函数就是专门解决这类有序轮廓提取问题的,不需要自行处理点排序逻辑,适配带回折的非凸轮廓场景,步骤如下:
- 先根据你筛选红色像素的规则生成二值掩码,红色像素位置设为255,其余设为0
- 调用
findContours直接输出按轮廓走向顺序排列的坐标点
代码示例:
import cv2 import numpy as np # 你的阈值参数 r_thres = 0.39 g_lim = 0.25 b_lim = 0.25 # 生成二值掩码 mask = np.zeros(cine_image.shape[:2], dtype=np.uint8) mask[(cine_image[:,:,0] >= r_thres) & (cine_image[:,:,1] <= g_lim) & (cine_image[:,:,2] <= b_lim)] = 255 # 提取有序轮廓,RETR_EXTERNAL只取最外层轮廓,CHAIN_APPROX_NONE保留所有轮廓点不压缩 contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # 取出第一个轮廓的坐标(如果只有一个红色轮廓的话),格式为(N, 2)的数组,每个元素是(x,y)坐标,已经按轮廓走向排好序 sorted_contour = contours[0].reshape(-1, 2)
小提示:如果筛选出的红色像素有孤立噪点,可以先对mask做
cv2.morphologyEx(mask, cv2.MORPH_OPEN, np.ones((3,3), np.uint8))做一次滤波,再提取轮廓效果更好。
二、手动实现算法(如果不想依赖OpenCV)
可以用邻域追踪算法实现,逻辑简单易调试:
- 步骤1:把所有红色像素坐标转成集合方便快速查找,同时准备一个已访问集合记录已经加入路径的点
- 步骤2:任选一个未访问的红色像素作为起点,加入当前路径,标记为已访问
- 步骤3:以当前路径最后一个点为基准,查找8邻域内未访问的红色像素,如果找到就加入路径、标记已访问,重复这个步骤
- 步骤4:如果当前点邻域内没有未访问的点,说明当前轮廓已经遍历完成;如果还有未访问的红色像素,说明存在多个独立轮廓,回到步骤2重新起新路径
代码示例:
# 把坐标转成元组存入集合 pixel_set = set(tuple(coord) for coord in red_pixels_coords) visited = set() all_contours = [] # 8邻域偏移量 offsets = [(-1,-1), (-1,0), (-1,1), (0,-1), (0,1), (1,-1), (1,0), (1,1)] while pixel_set - visited: # 取第一个未访问的点作为起点 start = next(iter(pixel_set - visited)) current_path = [start] visited.add(start) current = start while True: found = False for dx, dy in offsets: neighbor = (current[0] + dx, current[1] + dy) if neighbor in pixel_set and neighbor not in visited: current_path.append(neighbor) visited.add(neighbor) current = neighbor found = True break if not found: break all_contours.append(current_path)
得到的all_contours里每个元素就是一个按顺序排列的独立轮廓坐标列表。
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

