如何使用OpenCV提取曲线的起点、终点与中心点?
问题:提取曲线的起点、终点与中心点
我需要获取曲线的起点、终点与中心点。目前已通过convexity defects(凸包)获取了多个点,但不知道如何筛选出目标点。
相关图像说明
- 原始图像:包含目标曲线的原图
- 当前输出图像:现有代码运行后标记凸包缺陷点的图
- 期望输出示例图像:标记出起点、终点、中心点的目标效果图
现有代码
import cv2 import numpy as np from math import sqrt image = cv2.imread("2022-09-27 10:01:57image.png") gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) _, thresh = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY) contours,hie= cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) selected_contour = max(contours, key=lambda x: cv2.contourArea(x)) convexHull = cv2.convexHull(selected_contour,returnPoints=False) convexHull[::-1].sort(axis=0) convexityDefects = cv2.convexityDefects(selected_contour, convexHull) for i in range(convexityDefects.shape[0]): s, e, f, d = convexityDefects[i, 0] cv2.circle(image, start, 2, (255, 0, 0), 3) cv2.line(image,start,end , (0, 255, 0), 3) cv2.imshow('frame', image) cv2.waitKey(0)
解决方案
现有代码存在start变量未定义的问题,且未针对目标点做筛选。可通过以下步骤实现需求:
- 修正凸包缺陷点的坐标获取逻辑
- 基于凸包缺陷深度筛选中心点
- 通过轮廓极值点确定起点和终点
修改后的完整代码
import cv2 import numpy as np image = cv2.imread("2022-09-27 10:01:57image.png") gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) _, thresh = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY) contours, hie = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) selected_contour = max(contours, key=lambda x: cv2.contourArea(x)) # 获取凸包及凸包缺陷 convexHull = cv2.convexHull(selected_contour, returnPoints=False) convexityDefects = cv2.convexityDefects(selected_contour, convexHull) # 筛选中心点:取深度最大的凸包缺陷最远点 max_depth = -1 center_point = None for i in range(convexityDefects.shape[0]): s, e, f, d = convexityDefects[i, 0] far_point = tuple(selected_contour[f][0]) if d > max_depth: max_depth = d center_point = far_point # 筛选起点(x坐标最小)和终点(x坐标最大) contour_points = selected_contour.reshape(-1, 2) min_x_idx = np.argmin(contour_points[:, 0]) max_x_idx = np.argmax(contour_points[:, 0]) start_point = tuple(contour_points[min_x_idx]) end_point = tuple(contour_points[max_x_idx]) # 绘制标记 cv2.circle(image, start_point, 5, (0, 0, 255), -1) # 起点红色 cv2.circle(image, end_point, 5, (0, 255, 0), -1) # 终点绿色 cv2.circle(image, center_point, 5, (255, 0, 0), -1) # 中心点蓝色 cv2.imshow('frame', image) cv2.waitKey(0) cv2.destroyAllWindows()
代码说明
- 凸包缺陷的深度
d代表凹陷点到凸包的垂直距离,最大深度点对应曲线的中心点 - 利用轮廓点的x坐标极值筛选起点和终点,适配当前图像中曲线左右延伸的形态
- 用不同颜色标记三个目标点,便于直观区分
内容的提问来源于stack exchange,提问作者arjun
相关产品推荐
相关产品推荐

