当前位置: 首页 > article >正文

一笔画-获取图像轮廓坐标点

文章目录

  • 构图
  • K邻近算法
  • 代码
  • 一笔画轮廓
  • 坐标点


构图

首先是制作合适的图像,尽量是黑色背景,白色的图像。
SL3.jpg
在这里插入图片描述

K邻近算法

使用 python

from sklearn.neighbors import NearestNeighbors

代码

在这里插入图片描述
完整代码

import cv2
import numpy as np
from sklearn.neighbors import NearestNeighbors
import matplotlib.pyplot as plt
# 获取图片一笔画的轮廓点
def sort_contour_points(points):
    """按照最近邻算法排序轮廓点"""
    if len(points) == 0:
        return points  # 如果点集为空,直接返回


    ordered_points = []
    current_point = points[0]
    ordered_points.append(current_point)
    remaining_points = np.delete(points, 0, axis=0)  # 移除当前点

    while len(remaining_points) > 0:
        nbrs = NearestNeighbors(n_neighbors=1, algorithm='auto').fit(remaining_points)
        _, indices = nbrs.kneighbors([current_point])
        next_point_idx = indices[0][0]

        # 检查索引是否超出范围
        if next_point_idx >= len(remaining_points):
            break  # 如果超出范围,退出循环

        current_point = remaining_points[next_point_idx]
        ordered_points.append(current_point)
        remaining_points = np.delete(remaining_points, next_point_idx, axis=0)

    return np.array(ordered_points)

def sample_points(points, num_samples):
    """对轮廓点进行采样"""
    if len(points) == 0:
        return points  # 如果点集为空,直接返回

    indices = np.linspace(0, len(points) - 1, num_samples).astype(int)
    return points[indices]

def get_contour_points(image_path, num_samples=1000):
    """从图像中提取轮廓并采样到指定数量的点"""
    # 读取图像
    image = cv2.imread(image_path)
    if image is None:
        raise ValueError("图像路径错误或图像无法读取")

    # 灰度化
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # 二值化
    _, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)

    # 轮廓检测
    contours, _ = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

    # 合并所有轮廓点
    contour_points = np.vstack(contours).squeeze()

    # 按照一笔画方式排序轮廓点
    sorted_points = sort_contour_points(contour_points)

    # 采样到指定数量的点
    sampled_points = sample_points(sorted_points, num_samples)

    return sampled_points

def plot_contour_points(points):
    """可视化轮廓点"""
    if len(points) == 0:
        print("没有可用的轮廓点")
        return

    plt.plot(points[:, 0], points[:, 1], '-o', markersize=2)
    plt.gca().invert_yaxis()  # 反转Y轴以匹配图像坐标系
    plt.title("Sampled Contour Points")
    plt.xlabel("X")
    plt.ylabel("Y")
    plt.show()

# 示例使用
if __name__ == "__main__":
    # 图像路径
    image_path = "SL3.jpg"  # 替换为你的图像路径

    # 获取自定义数量个轮廓点, num_samples 自定义数量
    sampled_points = get_contour_points(image_path, num_samples=100)

    # 输出结果
    print("Sampled Points Shape:", sampled_points.shape)
    # sum_array = sampled_points.sum(axis=1)[:, np.newaxis]
    first = sampled_points[:, 0]
    second = sampled_points[:, 1]
    print("first min max:", np.min(first), np.max(first))   # 找到0维最大最小的元素
    print("second min max:", np.min(second), np.max(second)) # 找到1维最大最小的元素
    print("First 10 Points:\n", sampled_points[:10])

    with open('output.txt', 'w') as file:
        # 将列表转换为用逗号分隔的字符串,并写入文件
        # 默认的坐标轴0点是图像的左下角, 通过0/1维最大最小的元素 求平均平移,使坐标原点在图像中间,方便个性化使用
        file.write(','.join(map(str, (sampled_points-np.array([(57+525)/2, (18+508)/2])).tolist())))
    # 可视化
    plot_contour_points(sampled_points)

一笔画轮廓

可视化采集到的坐标集合
在这里插入图片描述

坐标点

得到的坐标点结果如下,坐标是按照一笔画方式排序的。
在这里插入图片描述


—————— 但行好事莫问前程,你若盛开蝴蝶自来


http://www.kler.cn/a/551467.html

相关文章:

  • JavaScript设计模式 -- 迭代器模式
  • vmware下ubuntu无法上网,电脑通过wifi连网
  • 罗德与施瓦茨ZNB4,4.5GHz网络分析仪的佼佼者
  • openGauss 3.0 数据库在线实训课程18:学习视图管理
  • 基于Qlearning强化学习的1DoF机械臂运动控制系统matlab仿真
  • 【GPIO详解及实践示例】
  • Leetcode 3459. Length of Longest V-Shaped Diagonal Segment
  • 大数据学习(48) - Flink状态种类
  • 李代数和李群的转化方法
  • Openssl交叉编译
  • 项目流程图
  • BSD协议栈:UDP发送
  • Python中通过Pymysql连接MySQL
  • SoftwareCluster中如何配置VendorSignature
  • 机器学习_14 随机森林知识点总结
  • flink反压详解
  • Android 10.0 移除wifi功能及相关菜单
  • Android中kotlin的Map简单使用方法
  • 【现代深度学习技术】深度学习计算 | GPU
  • STM32 ADC介绍(硬件原理篇)