如何对OpenCV connectedComponentsWithStats()输出按X轴排序以遍历?
按X轴位置排序connectedComponentsWithStats的组件
要解决按cv.CC_STAT_LEFT(X轴左侧位置)排序条码组件的问题,核心是对组件的索引按照对应位置值排序,而非直接对函数返回的元组操作。以下是具体实现方案:
解决方案1:Python列表排序(直观易懂)
先筛选出符合面积条件的组件,再按左侧位置值排序:
analysis = cv.connectedComponentsWithStats(roi_image_copy,4, cv.CV_32S) (totalLabels, label_ids, values, centroid) = analysis output = np.zeros(roi_image_copy.shape, dtype="uint8") # 收集符合面积要求的组件:存储(左侧位置, 组件索引) valid_components = [] for i in range(1, totalLabels): area = values[i, cv.CC_STAT_AREA] if 1 < area < 400: left_pos = values[i, cv.CC_STAT_LEFT] valid_components.append( (left_pos, i) ) # 按左侧位置升序排序(即从左到右) valid_components.sort(key=lambda item: item[0]) # 遍历排序后的组件 for _, i in valid_components: # 以下是你原有的组件处理代码,无需修改 x1 = values[i, cv.CC_STAT_LEFT] y1 = values[i, cv.CC_STAT_TOP] w = values[i, cv.CC_STAT_WIDTH] h = values[i, cv.CC_STAT_HEIGHT] pt1 = (x1, y1) pt2 = (x1 + w, y1 + h) (X, Y) = centroid[i] new_img = roi_image_copy.copy() new_img = cv.cvtColor(new_img, cv.COLOR_BGR2RGB) cv.rectangle(new_img, pt1, pt2, (255, 255, 0), 3) cv.circle(new_img, (int(X), int(Y)), 4, (0, 255, 255), -1) component = np.zeros(roi_image_copy.shape, dtype="uint8") componentMask = (label_ids == i).astype("uint8") * 255 component = cv.bitwise_or(component, componentMask) output = cv.bitwise_or(output, componentMask) cv.imshow("Image", new_img) cv.imshow("Individual Component", component) cv.imshow("Filtered Components", output) cv.waitKey(0)
解决方案2:Numpy数组排序(高效简洁)
利用Numpy的数组操作直接完成筛选和排序,适合处理大图像:
analysis = cv.connectedComponentsWithStats(roi_image_copy,4, cv.CV_32S) (totalLabels, label_ids, values, centroid) = analysis output = np.zeros(roi_image_copy.shape, dtype="uint8") # 获取所有非背景组件的索引(从1开始) component_indices = np.arange(1, totalLabels) # 筛选符合面积条件的组件索引 area_mask = (values[component_indices, cv.CC_STAT_AREA] > 1) & (values[component_indices, cv.CC_STAT_AREA] < 400) filtered_indices = component_indices[area_mask] # 按左侧位置排序筛选后的索引 sorted_indices = filtered_indices[np.argsort(values[filtered_indices, cv.CC_STAT_LEFT])] # 遍历排序后的组件 for i in sorted_indices: # 原有的组件处理代码保持不变 x1 = values[i, cv.CC_STAT_LEFT] y1 = values[i, cv.CC_STAT_TOP] w = values[i, cv.CC_STAT_WIDTH] h = values[i, cv.CC_STAT_HEIGHT] pt1 = (x1, y1) pt2 = (x1 + w, y1 + h) (X, Y) = centroid[i] new_img = roi_image_copy.copy() new_img = cv.cvtColor(new_img, cv.COLOR_BGR2RGB) cv.rectangle(new_img, pt1, pt2, (255, 255, 0), 3) cv.circle(new_img, (int(X), int(Y)), 4, (0, 255, 255), -1) component = np.zeros(roi_image_copy.shape, dtype="uint8") componentMask = (label_ids == i).astype("uint8") * 255 component = cv.bitwise_or(component, componentMask) output = cv.bitwise_or(output, componentMask) cv.imshow("Image", new_img) cv.imshow("Individual Component", component) cv.imshow("Filtered Components", output) cv.waitKey(0)
为什么你的原有尝试无效?
connectedComponentsWithStats返回的analysis是一个包含4个元素的元组:(总标签数, 标签矩阵, 统计信息数组, 质心数组)。直接对这个元组调用sorted()没有意义,因为你需要排序的是组件的索引,而非元组本身。通过上述方法,我们先获取有效组件的索引,再按对应位置值排序,就能实现从左到右遍历条码条的需求,无需旋转ROI。
内容的提问来源于stack exchange,提问作者CBJFan2009
相关产品推荐
相关产品推荐

