如何提取Numpy数组格式图像中黑色曲线最高点坐标并添加红色标记
实现逻辑
- 图像坐标说明:OpenCV中灰度图的shape为(高度, 宽度),行索引从上到下递增(行号越小位置越靠上),列索引从左到右递增。
- 黑色曲线的灰度值远低于白色背景,先做二值化反转处理,让曲线像素值为255,背景为0,方便检索。
- 逐列遍历图像,每列只取最顶部的曲线像素(即该列第一个值为255的像素,行号最小),避免粗曲线的多个像素干扰。
- 所有列的顶部曲线像素中,行号最小的就是上方曲线的最高点。
完整实现代码
import numpy as np import cv2 as cv2 # 读入灰度图 b = cv2.imread("graph.png", 0) # 二值化反转:曲线变为255,背景变为0,可根据实际图像调整阈值 # 也可使用OTSU自适应阈值:ret, thresh = cv2.threshold(b, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) ret, thresh = cv2.threshold(b, 127, 255, cv2.THRESH_BINARY_INV) # 初始化最高点坐标:初始行号设为图像最大高度(最底部) min_row = b.shape[0] peak_col = 0 # 逐列遍历 for col in range(thresh.shape[1]): # 获取当前列所有曲线像素的行索引 curve_rows = np.where(thresh[:, col] == 255)[0] if len(curve_rows) > 0: # 取该列最靠上的曲线像素行号 col_top_row = curve_rows[0] # 更新全局最高点 if col_top_row < min_row: min_row = col_top_row peak_col = col # 转彩色图像方便画红框 img_color = cv2.cvtColor(b, cv2.COLOR_GRAY2BGR) # 画10x10大小的红框,可自行调整框的大小和厚度 cv2.rectangle(img_color, (peak_col - 5, min_row - 5), (peak_col + 5, min_row + 5), (0, 0, 255), 2) # 显示结果 cv2.imshow("peak_marked", img_color) cv2.waitKey(0) cv2.destroyAllWindows()
可选优化
如果图像存在噪点,可在二值化后添加一行形态学开运算去除噪点:
thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, np.ones((3,3), np.uint8))
内容的提问来源于stack exchange,提问作者purple_coder
相关产品推荐
相关产品推荐

