1. 读取图像并进行预处理:将图像转换为灰度图,并应用高斯模糊来减少噪声。
  2. 应用Canny边缘检测:使用Canny算法检测图像中的边缘。
  3. 查找轮廓:使用findContours函数来检测图像中的轮廓。
  4. 计算每个轮廓的连通区域:使用connectedComponentsWithStats函数找到图像中的连通区域。
  5. 找到最大的连通区域:对每个连通区域,找到其最右边的点。
  6. 展示图像:使用imshow函数展示图像,并标注这些点。

以下是实现上述步骤的代码:

import cv2
import numpy as np
import matplotlib.pyplot as plt
def find_and_show_rightmost_points(image_path, num_regions=5):
    # 读取图像
    img = cv2.imread(image_path)
    if img is None:
        raise ValueError("无法读取图像,请检查图像路径。")

    # 转换为灰度图像
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # 应用高斯模糊
    blurred = cv2.GaussianBlur(gray, (5, 5), 0)

    # 应用Canny边缘检测
    edges = cv2.Canny(blurred, 50, 150)

    # 找到连通区域
    num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(edges, connectivity=8)

    # 排除背景,按面积排序,选出前num_regions个最大连通区域
    largest_regions = np.argsort(stats[1:, cv2.CC_STAT_AREA])[::-1][:num_regions] + 1

    rightmost_points = []

    # 计算每个连通区域的最右边点
    for region in largest_regions:
        mask = (labels == region).astype(np.uint8)
        contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        if contours:
            rightmost_point = max(contours[0], key=lambda point: point[0][0])
            rightmost_points.append(tuple(rightmost_point[0]))

    # 打印并标注最右边点
    x_lis = []
    for i, point in enumerate(rightmost_points):
        print(f"连通区域 {i+1} 的最右边点坐标: {point}")
        # 在图像上标注最右边点
        cv2.circle(img, point, 5, (0, 255, 0), -1)
        cv2.putText(img, f"{point}", (point[0] + 10, point[1]), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
        x_lis.append(point[0])

    # 展示图像
    # plt.figure(figsize=(10, 10))
    # plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    # plt.title("Rightmost Points")
    # plt.show()
    save_path = image_path.replace('.png', '_marked.png')
    cv2.imwrite(save_path, img)
    print(f"标记后的图像已保存到 {save_path}")

    print(x_lis)
    return x_lis, save_path

# 示例调用
image_path = '/Users/yangyongsheng/nas/download/23.png'
find_and_show_rightmost_points(image_path, num_regions=5)

在这个代码中:

  1. 应用Canny边缘检测:使用Canny算法检测图像中的边缘。
  2. 查找连通区域:使用connectedComponentsWithStats函数找到图像中的连通区域。
  3. 按面积排序:排除背景后,按面积排序,选出前num_regions个最大连通区域。
  4. 计算最右边点:对每个连通区域,找到其最右边的点。
  5. 标注并展示图像:打印这些点的坐标,并在图像上标注。
  6. x_lis: 返回所有x坐标

这段代码将找到最大的几个连通区域,并在图像上标注它们的最右边点。

 

如下图,得到几个点,准确度待提升(比如下面大象),滑到头截图识别连通区域,然后往回滑