Paint python - polygon and calculating iou

Draw two polygons and calculates their ratio and cross iou 

import numpy as np
import shapely
from shapely.geometry import Polygon, MultiPoint  # 多边形
from PIL import Image, ImageDraw, ImageFont
import math
from graham_scan import graham_scan


def calulate_iou(line1, line2):
    # 代码来源:https://blog.csdn.net/u012433049/article/details/82909484
    # 只能计算凸边形的iou
    a = np.array(line1).reshape(len(line1)//2, 2)  # 四边形二维坐标表示
    poly1 = Polygon(a).convex_hull  # python四边形对象,会自动计算四个点,最后四个点顺序为:左上 左下  右下 右上 左上
    print(Polygon(a).convex_hull)  # 可以打印看看是不是这样子

    b = np.array(line2).reshape(len(line2)//2, 2)
    poly2 = Polygon(b).convex_hull
    print(Polygon(b).convex_hull)

    union_poly = np.concatenate((a, b))  # 合并两个box坐标,变为8*2
    # print(union_poly)
    # print(MultiPoint(union_poly).convex_hull)  # 包含两四边形最小的多边形点
    if not poly1.intersects(poly2):  # 如果两四边形不相交
        iou = 0
    else:
        try:
            inter_area = poly1.intersection(poly2).area  # 相交面积
            print("inter_area:", inter_area)

            # union_area = MultiPoint(union_poly).convex_hull.area  # 包含两个四边形最小多边形的面积,第一种算法
            union_area = poly1.area + poly2.area - inter_area  # 两四边形并集,第二种常见算法

            print("union_area:", union_area)
            if union_area == 0:
                iou = 0
            iou = float(inter_area) / union_area
            """
            源码中给出了两种IOU计算方式:
            第一种:交集部分/包含两个四边形最小多边形的面积
            第二种:交集 / 并集(常见矩形框IOU计算方式)
            """
        except shapely.geos.TopologicalError:
            print('shapely.geos.TopologicalError occured, iou set to 0')
            iou = 0
    # print(a)
    print("iou:", iou)
    return [iou, inter_area, union_area]


def draw_iou_in_image(figure1, figure2, iou, image_path):
    # 来源:https://blog.csdn.net/pursuit_zhangyu/article/details/80410939?utm_source=distribute.pc_relevant.none-task

    image = Image.open(image_path)
    # 创建一个可以在给定图像上绘图的对象
    draw = ImageDraw.Draw(image)

    figure1 = graham_scan(figure1)
    figure2 = graham_scan(figure2)
    draw.polygon([i for i in figure1], outline=(255, 0, 0))
    draw.polygon([i for i in figure2], outline=(0, 255, 255))

    # 添加文字参考:https://blog.csdn.net/jacke121/article/details/88060686
    font = ImageFont.truetype(font="consola.ttf", size=15, encoding="unic")  # 设置字体,设置大小
    draw.text((image.size[0]*0.7, image.size[0] * 0.05), u"iou={:.4f}".format(iou[0]), (255, 0, 0), font)
    draw.text((image.size[0] * 0.7 - 20, image.size[0] * 0.05+20), u"inter_area={:.1f}".format(iou[1]), (255, 255, 0), font)
    draw.text((image.size[0] * 0.7 - 20, image.size[0] * 0.05+40), u"union_area={:.1f}".format(iou[2]), (0, 255, 0), font)
    # ImageDraw.Draw.text参数:第一个元组(x,y)是标注位置,第二个是内容,第三个是字体颜色,第四个是字体。image.size[0]图片宽,[1]为高,

    image.show()
    image.save("./man_detected.png")  # 很奇怪,不能保存为jpg


image_path = 'man.jpg'
# figure1 = [180, 190, 306, 196, 304, 284, 190, 275]  # 四边形四个点坐标的一维数组表示,[x1,y1,x2,y2....]
# figure2 = [142, 100, 331, 117, 332, 295, 126, 312]
figure1 = np.random.randint(100, 400, size=16, dtype=np.int)
figure2 = np.random.randint(100, 400, size=16, dtype=np.int)
iou = calulate_iou(figure1, figure2)
draw_iou_in_image(figure1, figure2, iou, image_path)


"""
author:UryWu
time  :2020年2月18日12点29分
bug1:
ink = self.draw.draw_ink(ink, self.mode)
    TypeError: function takes exactly 1 argument (3 given)
solution:我的pillow为6.2.1版,降为6.1后正常。pip install pillow==6.1
bug2:
    raise IOError("cannot write mode %s as JPEG" % im.mode)
OSError: cannot write mode RGBA as JPEG
solution:不能保存为jpg,只好改为png.
"""

 

Published 67 original articles · won praise 8 · views 9946

Guess you like

Origin blog.csdn.net/qq_25799253/article/details/104380483