python 两直线的夹角


class Point(object):
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y



class Line(object):  # 直线由两个点组成
    def __init__(self, p1=Point(0, 0), p2=Point(2, 2)):
        self.p1 = p1
        self.p2 = p2

    def distance_point_to_line(self, current_line, mainline):
        angle = self.get_cross_angle(current_line, mainline)
        sin_value = np.sin(angle * np.pi / 180)  # 其中current_line视为斜边
        long_edge = math.sqrt(  # 获取斜边长度
            math.pow(current_line.p2.x - current_line.p1.x, 2) + math.pow(current_line.p2.y - current_line.p1.y,
                                                                          2))  # 斜边长度
        distance = long_edge * sin_value
        return distance

    def get_cross_angle(self, l1, l2):
        arr_a = np.array([(l1.p2.x - l1.p1.x), (l1.p2.y - l1.p1.y)])  # 向量a
        arr_b = np.array([(l2.p2.x - l2.p1.x), (l2.p2.y - l2.p1.y)])  # 向量b
        cos_value = (float(arr_a.dot(arr_b)) / (np.sqrt(arr_a.dot(arr_a)) * np.sqrt(arr_b.dot(arr_b))))  # 注意转成浮点数运算
        return np.arccos(cos_value) * (180 / np.pi)  # 两个向量的夹角的角度, 余弦值:cos_value, np.cos(para), 其中para是弧度,不是角度

    def get_main_line(self, mask):
        # 获取最上面和最下面的contour的质心
        contour_list = get_contours(mask)
        c7_x, c7_y = get_centroid(contour_list[7])  # 最上面
        c0_x, c0_y = get_centroid(contour_list[0])  # 最下面

        # 获取串联两个质心,得到主线
        point1 = Point(c7_x, c7_y)
        point2 = Point(c0_x, c0_y)
        mainline = Line(point1, point2)
        return mainline

    #  求seg_img图中的直线与垂直方向的夹角
    def mainline_inclination_angle(self, seg_img):
        # 获取串联两个质心,得到主线
        mainline = self.get_main_line(seg_img)
        # 测试该函数,三角形边长:3,4,5
        mainline.p1.x = 0  # 列
        mainline.p1.y = 0
        mainline.p2.x = 3
        mainline.p2.y = 4
        # 获取参考线,这里用的是垂直方向的直线
        # base_line = Line.get_main_line(normal_mask)
        base_line = Line(Point(mainline.p1.x, mainline.p1.y),
                         Point(mainline.p1.x, mainline.p2.y))  # 同一列mainline.p1.x,行数随便
        # 获取两条线的夹角
        angle = mainline.get_cross_angle(mainline, base_line)
        return angle


# 求最大连通域的中心点坐标
def get_centroid(contour):
    moment = cv2.moments(contour)
    if moment['m00'] != 0:
        cx = int(moment['m10'] / moment['m00'])
        cy = int(moment['m01'] / moment['m00'])
        return cx, cy  # col, row
    else:
        return None


# 过滤面积较小的contour, 不同于后面的get_cnts(),
def get_contours(seg_img, area_thresh=0):
    if len(seg_img.shape) == 3:
        image_gray = cv2.cvtColor(seg_img, cv2.COLOR_RGB2GRAY)
    else:
        image_gray = seg_img.copy()

    # 1, 二值化原图的灰度图,然后求解轮廓contours
    _, mask_contour = cv2.threshold(image_gray.copy(), 0.1, 255, cv2.THRESH_BINARY)
    # 2, 找二值化后图像mask中的contour
    contours, hierarchy = cv2.findContours(image=mask_contour.copy(), mode=cv2.RETR_EXTERNAL,
                                           method=cv2.CHAIN_APPROX_SIMPLE)
    # 3, 遍历轮廓,将轮廓面积大于阈值的保存到contour_list中
    contour_list = []
    if len(contours) == 0:
        return contour_list
    for c_num in range(len(contours)):
        area = cv2.contourArea(contours[c_num])
        if area > area_thresh:
            contour_list.append(contours[c_num])
        else:
            continue
    return contour_list



def get_bbox_num(seg_img, area_thresh=0):
    image = seg_img.copy()
    contour_list = get_contours(image, area_thresh)  # contours排序是从上到下
    return len(contour_list)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.Q

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值