
import cv2
import numpy as np
import cv2
colors_32 = [
(0, 0, 0), # Black
(255, 255, 255), # White
(255, 0, 0), # Red
(0, 255, 0), # Lime
(0, 0, 255), # Blue
(255, 255, 0), # Yellow
(0, 255, 255), # Cyan
(255, 0, 255), # Magenta
(192, 192, 192), # Silver
(128, 128, 128), # Gray
(128, 0, 0), # Maroon
(128, 128, 0), # Olive
(0, 128, 0), # Green
(128, 0, 128), # Purple
(0, 128, 128), # Teal
(0, 0, 128), # Navy
(255, 165, 0), # Orange
(255, 192, 203), # Pink
(165, 42, 42), # Brown
(255, 215, 0), # Gold
(245, 245, 220), # Beige
(230, 230, 250), # Lavender
(255, 255, 240), # Ivory
(64, 224, 208), # Turquoise
(75, 0, 130), # Indigo
(238, 130, 238), # Violet
(240, 230, 140), # Khaki
(250, 128, 114), # Salmon
(255, 127, 80), # Coral
(220, 20, 60), # Crimson
(0, 255, 255), # Aqua
(255, 0, 255) # Fuchsia
]
# 读取图像并转灰度、二值化
img = cv2.imread(r"B:\360MoveData\Users\Administrator\Documents\WeChat Files\libanggeng\FileStorage\File\2025-05\test\test\daojian_4_mask.jpg")
import cv2
import numpy as np
from sklearn.cluster import DBSCAN
import matplotlib.pyplot as plt
# 读取图像并转灰度、二值化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# 查找轮廓
contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cnt = contours[0]
# 计算切线方向(使用导数近似)
tangent_features = []
points = []
for i in range(len(cnt)):
p_prev = cnt[(i - 1) % len(cnt)][0]
p_next = cnt[(i + 1) % len(cnt)][0]
p_curr = cnt[i][0]
dx = p_next[0] - p_prev[0]
dy = p_next[1] - p_prev[1]
norm = np.hypot(dx, dy)
if norm == 0:
continue
dx /= norm
dy /= norm
# 使用单位方向向量作为特征
tangent_features.append([dx, dy])
points.append(p_curr)
tangent_features = np.array(tangent_features)
points = np.array(points)
# DBSCAN 聚类(在方向空间上)
db = DBSCAN(eps=0.3, min_samples=5).fit(tangent_features)
labels = db.labels_
# 可视化聚类结果
n_clusters = len(set(labels)) - (1 if -1 in labels else 0)
# 创建可视化图像
output = img.copy()
for point, label in zip(points, labels):
color = (0, 0, 0) if label == -1 else colors_32[label]
cv2.circle(output, tuple(point), 2, color, -1)
# 显示结果
cv2.imshow("DBSCAN on Tangent Directions", output)
cv2.waitKey(0)
cv2.destroyAllWindows()