任意四点按顺时针排列

任意四点按起始点从左上角开始,顺时针输出,代码如下:

#coding:utf-8

import cv2
import numpy as np


if __name__=='__main__':
    img = np.zeros((1000, 1000, 3), np.uint8)
    # cnt=np.array([[474,143],[448,135],[369,359],[343,350]])   #倾斜的矩形
    # cnt=np.array([[500,300],[100,100],[500,100],[100,300]])   #水平矩形
    cnt =np.array([[300,304],[187,240],[149,299],[257,362]])    #倾斜矩形
    x, y, w, h = cv2.boundingRect(cnt)
    img = cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 1)
    leftTop=np.array([x,y])
    rect = cv2.minAreaRect(cnt)
    # print(rect)
    box = cv2.boxPoints(rect)
    box = np.int0(box)
    tempList=[]
    for i,item in enumerate(box):
        dif =item - leftTop
        dist = np.sqrt(np.sum(dif * dif))
        item=np.append(item,round(dist,2))
        item=np.append(item,i)
        tempList.append(list(item))
    NewResult = sorted(tempList, key=lambda x: x[2])  # 根据第四项距离值默认从小到大排序
    lt,rt,rb,lb=[],[],[],[]
    print(NewResult[0][3])
    if int(NewResult[0][3])==0:
        lt=[box[0][0],box[0][1]]
        rt=[box[1][0],box[1][1]]
        rb=[box[2][0],box[2][1]]
        lb=[box[3][0],box[3][1]]
    elif int(NewResult[0][3])==1:
        lt = [box[1][0], box[1][1]]
        rt = [box[2][0], box[2][1]]
        rb = [box[3][0], box[3][1]]
        lb = [box[0][0], box[0][1]]
    elif int(NewResult[0][3])==2:
        lt = [box[2][0], box[2][1]]
        rt = [box[3][0], box[3][1]]
        rb = [box[0][0], box[0][1]]
        lb = [box[1][0], box[1][1]]
    else:
        lt = [box[3][0], box[3][1]]
        rt = [box[0][0], box[0][1]]
        rb = [box[1][0], box[1][1]]
        lb = [box[2][0], box[2][1]]
    print(lt,rt,rb,lb)
    cv2.drawContours(img, [box], 0, (0, 0, 255), 1)  # 测试
    cv2.imshow("src",img)
    cv2.waitKey(0)

def sort_points_clockwise(PointList):
    """提供一组凸四边形顶点,按照从左上角顶点开始顺时针方向排序
      :param points: Numpy矩阵,shape为(4, 2),描述一组凸四边形顶点
      :return sorted_points: 经过排序的点
    """
    # 直接分别取四个点坐标中x和y的最小值作为最大外接矩形左上顶点
    points=np.array(PointList)  # 倾斜矩形
    outter_rect_l_t = np.append(np.min(points[::, 0]), np.min(points[::, 1]))
    # 求距离最大外接矩形左上点最近的点,作为给定四边形的左上顶点
    # 这一步应当是np.argmin(np.sqrt(np.sum(np.square(points - (x, y)), axis=1)))
    # 但是开不开算数平方根结果都一样,不是特别有必要,还浪费算力,就省了
    l_t_point_index = np.argmin(
        np.sum(np.square(points - outter_rect_l_t), axis=1))
    # 分别拿出来左上角点和剩余三点
    l_t_point = points[l_t_point_index]
    other_three_points = np.append(points[0:l_t_point_index:],
                                   points[l_t_point_index + 1::],
                                   axis=0)
    # 以x轴(此处以(1, 0)矢量视为x轴)为基准,根据剩余三点与x轴夹角角度排序
    BASE_VECTOR = np.asarray((1, 0))
    BASE_VECTOR_NORM = 1.0  # np.linalg.norm((1, 0))结果为1
    other_three_points = sorted(other_three_points,
                                key=lambda item: np.arccos(
                                    np.dot(BASE_VECTOR, item) /
                                    (BASE_VECTOR_NORM * np.linalg.norm(item))),
                                reverse=False)
    sorted_points = np.append(l_t_point.reshape(-1, 2),
                              np.asarray(other_three_points),
                              axis=0)
   # lt, rt, rb, lb = [sorted_points[0][0],sorted_points[0][1]], [sorted_points[1][0],sorted_points[1][1]],[sorted_points[2][0],sorted_points[2][1]], [sorted_points[3][0],sorted_points[3][1]]
    return sorted_points

更新一下思路,确定左上角的点之后,如果四个点是标准矩形,上述代码可以通用,如果是凸四边形,思路可以稍微调整一下,确认左上角,后续1、根据确认左上角方法,依次确认其他的角,2、其他三个点求跟坐标原点(图像默认左上角为原点),同横方向的夹角,顺时针,角度依次从小大,同理,同纵方向夹角,角度依次从大大小排序,即可得到依左上角为起始点,顺时针旋转。
代码冗余,有好的建议,可以自行修改,留言交流

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值