python——计算两个多边形的IOU

任务描述

计算两个多边形的IOU。可以是不同类的多边形,如一个矩形和一个三角形;也可以是两个同类的多边形。

代码

import cv2
import math
from skimage.draw import polygon
from skimage.feature import peak_local_max
import torch.nn.functional as F
import numpy as np

def polygon_IOU(polygon_1, polygon_2):
    """
    计算两个多边形的IOU
    :param polygon_1: [[row1, col1], [row2, col2], ...]
    :param polygon_2: 同上
    :return:
    """
    rr1, cc1 = polygon(polygon_2[:, 0], polygon_2[:, 1])
    rr2, cc2 = polygon(polygon_1[:, 0], polygon_1[:, 1])

    try:
        r_max = max(rr1.max(), rr2.max()) + 1
        c_max = max(cc1.max(), cc2.max()) + 1
    except:
        return 0

    canvas = np.zeros((r_max, c_max))
    canvas[rr1, cc1] += 1
    canvas[rr2, cc2] += 1
    union = np.sum(canvas > 0)
    if union == 0:
        return 0
    intersection = np.sum(canvas == 2)
    return intersection / union

if __name__ == '__main__':
    dx = 15
    # 三角形输入为三个点坐标
    triangle_1 = np.array([
        [200, 100],
        [180, 180],
        [220, 180]
    ])
    triangle_2 = np.array([
        [200 + dx, 100],
        [180 + dx, 180],
        [220 + dx, 180]
    ])
    # [row, col]
    rect_1 = np.array([
        [100, 100],
        [100, 200],
        [200, 200],
        [200, 100]
    ])
    rect_2 = np.array([
        [100, 150],
        [100, 250],
        [200, 250],
        [200, 150]
    ])
    iou = polygon_IOU(rect_1, rect_2)
    print('IOU={:.5f}'.format(iou))
以下是一个计算两个多边形IOU的C++代码,假设多边形的顶点坐标已知: ```c++ #include <iostream> #include <vector> using namespace std; struct Point { double x, y; }; // 计算多边形面积 double polygonArea(const vector<Point>& polygon) { double area = 0; int n = polygon.size(); for (int i = 0; i < n; i++) { int j = (i + 1) % n; area += polygon[i].x * polygon[j].y - polygon[j].x * polygon[i].y; } return area / 2; } // 计算多边形的交集面积 double polygonIntersectionArea(const vector<Point>& polygon1, const vector<Point>& polygon2) { double area = 0; int n1 = polygon1.size(); int n2 = polygon2.size(); for (int i = 0; i < n1; i++) { int j = (i + 1) % n1; for (int k = 0; k < n2; k++) { int l = (k + 1) % n2; Point p1 = polygon1[i]; Point p2 = polygon1[j]; Point q1 = polygon2[k]; Point q2 = polygon2[l]; double t1 = (q1.x - p1.x) * (p2.y - p1.y) - (p2.x - p1.x) * (q1.y - p1.y); double t2 = (q2.x - p1.x) * (p2.y - p1.y) - (p2.x - p1.x) * (q2.y - p1.y); double t3 = (p1.x - q1.x) * (q2.y - q1.y) - (q2.x - q1.x) * (p1.y - q1.y); double t4 = (p2.x - q1.x) * (q2.y - q1.y) - (q2.x - q1.x) * (p2.y - q1.y); if (t1 * t2 < 0 && t3 * t4 < 0) { Point p = {0, 0}; p.x = (t2 * q1.x - t1 * q2.x) / (t2 - t1); p.y = (t2 * q1.y - t1 * q2.y) / (t2 - t1); area += polygonArea(vector<Point>{p1, p, p2}); } } } return area; } // 计算两个多边形IOU double polygonIOU(const vector<Point>& polygon1, const vector<Point>& polygon2) { double area1 = polygonArea(polygon1); double area2 = polygonArea(polygon2); double intersectionArea = polygonIntersectionArea(polygon1, polygon2); double unionArea = area1 + area2 - intersectionArea; return intersectionArea / unionArea; } int main() { // 示例1:边长为1的正方形和边长为2的正方形,重叠面积为1,总面积为4 vector<Point> polygon1{{0, 0}, {1, 0}, {1, 1}, {0, 1}}; vector<Point> polygon2{{0.5, 0.5}, {2.5, 0.5}, {2.5, 2.5}, {0.5, 2.5}}; double iou = polygonIOU(polygon1, polygon2); cout << "IOU: " << iou << endl; // 示例2:半径为1的圆和半径为2的圆,重叠面积为2.828,总面积为9.424 const double pi = 3.14159265358979323846; vector<Point> circle1; vector<Point> circle2; int n = 100; for (int i = 0; i < n; i++) { double angle = 2 * pi / n * i; Point p1 = {cos(angle), sin(angle)}; Point p2 = {2 * cos(angle), 2 * sin(angle)}; circle1.push_back(p1); circle2.push_back(p2); } iou = polygonIOU(circle1, circle2); cout << "IOU: " << iou << endl; return 0; } ``` 以上代码实现了计算两个多边形IOU的功能,并提供了两个示例。其中,`polygonArea`函数用于计算多边形面积;`polygonIntersectionArea`函数用于计算两个多边形的交集面积;`polygonIOU`函数用于计算两个多边形IOU
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值