基于Canny边缘检测的导线像素定位及颜色识别技术问询
导线颜色识别解决方案
问题说明
需要遍历导线垂直中心位置的水平像素行,边缘图中导线首尾为白色,首尾间像素均属导线区域。目标是通过编程实现导线颜色识别,步骤为先使用Canny边缘检测,但目前在获取导线垂直边界的x位置时遇到困难,后续需得到从左到右的颜色列表(如[Violet,Blue,Brown,...])。尝试用np.nonzero(edges)获取列像素,但输出的分散索引无法满足需求。
原代码存在基础错误:调用cv2.imshow("Image", original_image)时,original_image未定义,应改为image;且未针对导线中心行和边界做针对性处理。
解决步骤
- 修正代码基础错误:修复变量名问题,确保图像显示正常。
- 确定导线垂直中心行:从二值化后的图像中,提取所有属于导线区域的行索引,取中间值作为中心行。
- 获取导线左右边界:在中心行上,找到第一个和最后一个白色像素的x坐标,确定导线的水平范围。
- 提取颜色并映射名称:在中心行的导线范围内,逐个提取像素的BGR值,转换为RGB后匹配对应的颜色名称。
修改后的完整代码
import cv2 import numpy as np # 颜色映射:RGB值到颜色名称的对应(可根据实际导线颜色扩展) COLOR_MAP = { (128, 0, 128): "Violet", (0, 0, 255): "Blue", (165, 42, 42): "Brown", (255, 0, 0): "Red", (255, 255, 0): "Yellow", (0, 255, 0): "Green" } def get_color_name(rgb): # 通过计算欧氏距离匹配最接近的预设颜色 min_dist = float('inf') color_name = "Unknown" for color_rgb, name in COLOR_MAP.items(): dist = np.linalg.norm(np.array(rgb) - np.array(color_rgb)) if dist < min_dist: min_dist = dist color_name = name return color_name # 读取图像 image = cv2.imread('Template.jpg') gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) gray = cv2.GaussianBlur(gray, (5,5), 0) # 二值化与形态学操作 _, bin_img = cv2.threshold(gray, 120, 255, cv2.THRESH_BINARY_INV) # 反转阈值适配亮物体暗背景 bin_img = cv2.dilate(bin_img, None, iterations=2) bin_img = cv2.erode(bin_img, None, iterations=2) # Canny边缘检测 edges = cv2.Canny(gray, 50, 200) # 确定导线的垂直中心行 wire_rows = np.where(bin_img == 255)[0] if len(wire_rows) == 0: print("未检测到导线") cv2.destroyAllWindows() exit() center_row = wire_rows[len(wire_rows) // 2] # 获取中心行上导线的左右边界 center_row_pixels = bin_img[center_row, :] left_bound = np.argmax(center_row_pixels == 255) right_bound = len(center_row_pixels) - np.argmax(np.flip(center_row_pixels) == 255) - 1 # 提取中心行导线范围内的颜色列表 color_list = [] for x in range(left_bound, right_bound + 1): # OpenCV为BGR格式,转换为标准RGB b, g, r = image[center_row, x] rgb = (r, g, b) color_name = get_color_name(rgb) color_list.append(color_name) print("从左到右的导线颜色列表:", color_list) # 显示图像 cv2.imshow("Original Image", image) cv2.imshow("Grayscale", gray) cv2.imshow("Binary", bin_img) cv2.imshow("Edges", edges) cv2.waitKey(0) cv2.destroyAllWindows()
代码说明
- 颜色匹配逻辑:通过计算目标RGB与预设颜色的欧氏距离,匹配最接近的颜色名称,可根据实际导线颜色扩展
COLOR_MAP。 - 中心行定位:从二值图中提取所有导线区域的行索引,取中间行作为垂直中心,确保遍历的是导线的核心位置。
- 边界获取:利用
np.argmax快速定位中心行上导线的左右边界,避免了np.nonzero返回分散索引的问题。
内容的提问来源于stack exchange,提问作者yessi
相关产品推荐
相关产品推荐

