• 如何顺时针或者逆时针记录多边形的每个点


    问题定义:

    按照顺时针或者逆时针提取多边形的各个顶点

    问题解决:

    针对一个凸多边形,假设多边形的中心为C,多边形的任意一个顶点为A

    做一个辅助点,假设有一条水平线通过中心点C,并在c点右边设一个B点

    这样,可以通过\overrightarrow{CA} 与\overrightarrow{CB} 的夹角确定A点的角度,这样根据不同位置的顶点就能得到其夹角。

    具体python实现:

    1. # -*- coding: utf-8 -*-
    2. import numpy as np
    3. import cv2
    4. import cv2 as cv
    5. from sklearn.cluster import DBSCAN
    6. import copy
    7. def obtain_corners(mask):
    8. dst = cv.cornerHarris(mask,5,5,0.04)
    9. # 设置阈值,将角点绘制出来,阈值根据图像进行选择
    10. pos = np.where(dst>0.001*dst.max())
    11. x = pos[1]
    12. y = pos[0]
    13. epsilon = 2
    14. min_samples=1
    15. ou = np.concatenate((x.reshape(-1,1),y.reshape(-1,1)), axis=1)
    16. db = DBSCAN(eps=epsilon, min_samples=min_samples).fit(ou)
    17. _labels = db.labels_
    18. points_poly = np.zeros([0,2], dtype=np.float32)
    19. for i in range(_labels.max()+1):
    20. vv = np.mean(ou[np.where(_labels == i)[0], :], 0)
    21. points_poly = np.concatenate((points_poly, vv.reshape(1,2)), axis=0)
    22. return points_poly
    23. def dot_product_angle(v1, v2):
    24. if np.linalg.norm(v1) == 0 or np.linalg.norm(v2) == 0:
    25. print("Zero magnitude vector!")
    26. else:
    27. vector_dot_product = np.dot(v1, v2)
    28. arccos = np.arccos(vector_dot_product / (np.linalg.norm(v1) * np.linalg.norm(v2)))
    29. angle = np.degrees(arccos)
    30. return angle
    31. return 0
    32. def obtain_vector(a, b, center):
    33. aa = copy.deepcopy(a)
    34. bb = copy.deepcopy(b)
    35. aa[0] = center[0] - aa[0]
    36. aa[1] = center[1] - aa[1]
    37. bb[0] = center[0] - bb[0]
    38. bb[1] = center[1] - bb[1]
    39. return aa, bb
    40. # load image
    41. large = cv2.imread('ss_big.png', 0)
    42. # obtain corners
    43. points_poly = obtain_corners(large)
    44. _, temp_bin = cv2.threshold(large, 126, 255, cv2.THRESH_BINARY)
    45. num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(temp_bin, connectivity=8)
    46. # obtain the center
    47. center = centroids[1, :]
    48. # save angle
    49. angle = []
    50. b = np.array([center[0] + 10, center[1]], dtype=np.float32)
    51. for i in range(points_poly.shape[0]):
    52. aa, bb = obtain_vector(points_poly[i,:], b, center)
    53. angle_ = dot_product_angle(aa, bb)
    54. #print(points_poly[i,:])
    55. if points_poly[i,1] > center[1]:
    56. angle_ += 180
    57. angle.append(angle_)
    58. index_ = np.argsort(np.array(angle, dtype=np.float32))
    59. # sorted by angle
    60. pos_poly = points_poly[index_,:]
    61. print(pos_poly)

     结果:

    [[1761.5         651.125     ]
     [1562.43636364  592.49090909]
     [1489.41666667  514.9375    ]
     [1527.11111111  310.44444444]
     [1499.36363636  272.04545455]
     [1261.42857143  219.03571429]
     [1224.15        234.15      ]
     [1180.          416.66666667]
     [ 890.18181818  395.42424242]
     [1638.48484848 1105.84848485]
     [1432.53061224 1043.44897959]
     [1360.25       1078.85      ]
     [1303.54166667 1246.16666667]
     [1240.48       1267.46      ]
     [ 965.09090909 1175.6969697 ]
     [1015.73076923 1001.42307692]
     [ 978.5         904.55555556]
     [ 793.65714286  833.8       ]]

  • 相关阅读:
    NCCL后端
    RunwayGen2上线全新控制功能「运动笔刷」
    Google桌面与BBdoc文件管理助手对比分析
    互联网摸鱼日报(2023-09-20)
    【golang】建议收藏的golang瑞士军刀-9个工具方法
    创建Vue项目的常用npm插件总结
    redis主从扩容
    【其他】sd卡的照片在相机上能看到在电脑上却看不到
    ESP8266-Arduino编程实例-磁簧开关传感器驱动
    基于JAVA中华二十四节气文化传承宣展平台计算机毕业设计源码+系统+数据库+lw文档+部署
  • 原文地址:https://blog.csdn.net/yeyang911/article/details/127108198