计算两个旋转矩形的交集——Python

转自:https://blog.csdn.net/sda42342342423/article/details/79746736

知识准备
cv2.rotatedRectangleIntersection(rect1, rect2)

计算两个旋转矩形的交集,返回值 0,1,2分别表示没有,有,包含;以及交点的坐标的一个array。很遗憾的是这个坐标是不是逆时针也不是顺时针。而cv2.contourArea()需要点是顺时针或者逆时针。
例子程序
# 中心点 矩形的w h, 旋转的theta(角度,不是弧度)
rect1 = ((0,0),(1,1),45)
rect2 = ((1.5,0),(4,3),0)
r1 = cv2.rotatedRectangleIntersection(rect1, rect2)
print r1
1
2
3
4
5
多边形的点逆时针排序 
Python 的自定义的排序程序只能返回0,1,-1。没有true,false。所以没return a > b种写法
主要是根据所求出的重心,按照向量的叉积,然后排序
排序函数如下:
def cmp(a, b):
    if a.x >= 0 and b.x < 0:
        return -1
    if a.x == 0 and b.x == 0:
        # return a.y > b.y
        if a.y > b.y:
            return -1
        elif a.y < b.y:
            return 1
        return 0
    det = (a.x - c.x) * (b.y - c.y) - (b.x - c.x) * (a.y - c.y)
    if det < 0:
        return 1
    if det > 0:
        return -1
    d1 = (a.x - c.x) * (a.x - c.x) + (a.y - c.y) * (a.y - c.y)
    d2 = (b.x - c.x) * (b.x - c.x) + (b.y - c.y) * (b.y - c.y)
    # return d1 > d2
    if d1 > d2:
        return -1
    elif d1 < d2:
        return 1
    return 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
cv2.contourArea() 
计算点所包围的面积
坑点 dtype=’float32’
# 可行
r = ((2,-2),(-2,-2),(-2,2),(2,2))
r2 = cv2.contourArea(np.array(r))
# 可行
r = [[1,-1],[-1,-1],[-1,1],[1,1]]
r2 = cv2.contourArea(np.array(r))
# 不可行
r = np.full((len_p, 2), 0.0)
for i in range(len(pp)):
    print pp[i].x, pp[i].y
    r[i][0] = pp[i].x
    r[i][1] = pp[i].y
r2 = cv2.contourArea(r)
# 可行
r = np.full((len_p, 2), 0.0, dtype='float32')
for i in range(len(pp)):
    print pp[i].x, pp[i].y
    r[i][0] = pp[i].x
    r[i][1] = pp[i].y
r2 = cv2.contourArea(r)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
代码
import cv2
import  numpy as np


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

def cmp(a, b, c):
    if a.x >= 0 and b.x < 0:
        return -1
    if a.x == 0 and b.x == 0:
        # return a.y > b.y
        if a.y > b.y:
            return -1
        elif a.y < b.y:
            return 1
        return 0
    det = (a.x - c.x) * (b.y - c.y) - (b.x - c.x) * (a.y - c.y)
    if det < 0:
        return 1
    if det > 0:
        return -1
    d1 = (a.x - c.x) * (a.x - c.x) + (a.y - c.y) * (a.y - c.y)
    d2 = (b.x - c.x) * (b.x - c.x) + (b.y - c.y) * (b.y - c.y)
    # return d1 > d2
    if d1 > d2:
        return -1
    elif d1 < d2:
        return 1
    return 0
## centerx, centery w, h, thetta
rect1 = ((0,0),(1,1),45)
rect2 = ((1.5,0),(4,3),0)

r1 = cv2.rotatedRectangleIntersection(rect1, rect2)

x = 0
y = 0
p = []
len_p = r1[1].shape[0]
for i in range(len_p):
    p.append(Point(r1[1][i][0][0], r1[1][i][0][1]))
    x += r1[1][i][0][0]
    y += r1[1][i][0][1]

c = Point(x / len_p, y/len_p)

pp = sorted(p, lambda x,y: cmp(x, y, c))
r = np.full((len_p, 2), 0.0, dtype='float32')
for i in range(len(pp)):
    print pp[i].x, pp[i].y
    r[i][0] = pp[i].x
    r[i][1] = pp[i].y
r2 = cv2.contourArea(r)
print r2
--------------------- 
作者:sda42342342423 
来源:CSDN 
原文:https://blog.csdn.net/sda42342342423/article/details/79746736 
版权声明:本文为博主原创文章,转载请附上博文链接!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值