python shapely.geometry.polygon任意两个四边形的IOU计算实例


Posted in Python onApril 12, 2020

在目标检测中一个很重要的问题就是NMS及IOU计算,而一般所说的目标检测检测的box是规则矩形框,计算IOU也非常简单,有两种方法:

1. 两个矩形的宽之和减去组合后的矩形的宽就是重叠矩形的宽,同比重叠矩形的高

2. 右下角的minx减去左上角的maxx就是重叠矩形的宽,同比高

然后 IOU = 重叠面积 / (两矩形面积和—重叠面积)

然,不规则四边形就不能通过这种方式来计算,找了好久数学资料,还是没找到答案(鄙人数学渣渣),最后看了白翔老师的textBoxes++论文源码后,知道python的shapely包可以直接做到,下面给出的代码和注释:

import numpy as np 
import shapely
from shapely.geometry import Polygon,MultiPoint #多边形
 
line1=[2,0,2,2,0,0,0,2]  #四边形四个点坐标的一维数组表示,[x,y,x,y....]
a=np.array(line1).reshape(4, 2)  #四边形二维坐标表示
poly1 = Polygon(a).convex_hull #python四边形对象,会自动计算四个点,最后四个点顺序为:左上 左下 右下 右上 左上
print(Polygon(a).convex_hull) #可以打印看看是不是这样子
 
line2=[1,1,4,1,4,4,1,4]
b=np.array(line2).reshape(4, 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)
    #union_area = poly1.area + poly2.area - inter_area
    union_area = MultiPoint(union_poly).convex_hull.area
    print(union_area)
    if union_area == 0:
      iou= 0
    #iou = float(inter_area) / (union_area-inter_area) #错了
    iou=float(inter_area) / union_area
    # iou=float(inter_area) /(poly1.area+poly2.area-inter_area)
    # 源码中给出了两种IOU计算方式,第一种计算的是: 交集部分/包含两个四边形最小多边形的面积 
    # 第二种: 交集 / 并集(常见矩形框IOU计算方式) 
  except shapely.geos.TopologicalError:
    print('shapely.geos.TopologicalError occured, iou set to 0')
    iou = 0
 
print(a)
 
print(iou)

具体原理还没弄明白,还在研究中,研究完再给出来(当然数学渣渣能不能研究出来有待商榷*—*)

补充知识:python 二维坐标多边形 计算多边形中心点,以及距该中心点最远的距离

我就废话不多说了,还是直接看代码吧!

def center_geolocation(geolocations):
	'''
	输入多个经纬度坐标(格式:[[lon1, lat1],[lon2, lat2],....[lonn, latn]]),找出中心点
	:param geolocations:
	:return:中心点坐标 [lon,lat]
	'''
	#求平均数 同时角度弧度转化 得到中心点
	x = 0	# lon
	y = 0	# lat
	z = 0
	lenth = len(geolocations)
	for lon, lat in geolocations:
		lon = radians(float(lon))
		# radians(float(lon))  Convert angle x from degrees to radians
		# 	          把角度 x 从度数转化为 弧度
		lat = radians(float(lat))
		x += cos(lat) * cos(lon)
		y += cos(lat) * sin(lon)
		z += sin(lat)
		x = float(x / lenth)
		y = float(y / lenth)
		z = float(z / lenth)
	return (degrees(atan2(y, x)), degrees(atan2(z, sqrt(x * x + y * y))))
 
#得到离中心点里程最近的里程
 
def geodistance(lon1,lat1,lon2,lat2):
	'''
	得到两个经纬度坐标距离 单位为千米 (计算不分前后顺序)
	:param lon1: 第一个坐标 维度
	:param lat1: 第一个坐标 经度
	:param lon2: 第二个坐标 维度
	:param lat2: 第二个坐标 经度
	:return: distance 单位千米
	'''
	# lon1,lat1,lon2,lat2 = (120.12802999999997,30.28708,115.86572000000001,28.7427)
	lon1, lat1, lon2, lat2 = map(radians, [float(lon1), float(lat1), float(lon2), float(lat2)]) #经纬度转换成弧度
	dlon=lon2-lon1
	dlat=lat2-lat1
	a=sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
	distance=2*asin(sqrt(a))*6371*1000 #地球平均半径,6371km
	distance=round(distance/1000,3)
	print(distance)
	return distance
 
def getMaxestDistance(geolocations,centre):
	'''
	中心点 距离 多个经纬度左边 最远的距离
	:param geolocations: 多个经纬度坐标(格式:[[lon1, lat1],[lon2, lat2],....[lonn, latn]])
	:param centre: 中心点  centre [lon,lat]
	:return: 最远距离 千米
	'''
	distantces=[]
	for lon, lat in geolocations:
		d=geodistance(lat,lon,centre[1],centre[0])
		distantces.append(d)
	# print(distantces)
	return max(distantces)
 
def getOnePolyygen(geolocations):
	'''
	输入多个经纬度坐标(格式:[[lon1, lat1],[lon2, lat2],....[lonn, latn]]),找出距该多边形中心点最远的距离
	:param geolocations:多个经纬度坐标(格式:[[lon1, lat1],[lon2, lat2],....[lonn, latn]])
	:return:center,neartDistance 多边形中心点 最远距离
	'''
	center=center_geolocation(geolocations) # 得到中心点
	neartDistance=getMaxestDistance(geolocations,center)
	# print(center,"-----------------",neartDistance)
	return center,neartDistance

以上这篇python shapely.geometry.polygon任意两个四边形的IOU计算实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
用于统计项目中代码总行数的Python脚本分享
Apr 21 Python
简单介绍Python中的struct模块
Apr 28 Python
Python获取运行目录与当前脚本目录的方法
Jun 01 Python
python实现支持目录FTP上传下载文件的方法
Jun 03 Python
浅析Python中的for 循环
Jun 09 Python
安装Python的教程-Windows
Jul 22 Python
python使用插值法画出平滑曲线
Dec 15 Python
Python使用Opencv实现图像特征检测与匹配的方法
Oct 30 Python
如何实现一个python函数装饰器(Decorator)
Oct 12 Python
Python实现随机爬山算法
Jan 29 Python
python 利用panda 实现列联表(交叉表)
Feb 06 Python
Python 使用 Frame tkraise() 方法在 Tkinter 应用程序中的Frame之间切换
Apr 24 Python
Python求凸包及多边形面积教程
Apr 12 #Python
python实现人脸签到系统
Apr 13 #Python
python实现IOU计算案例
Apr 12 #Python
python 已知平行四边形三个点,求第四个点的案例
Apr 12 #Python
python 已知三条边求三角形的角度案例
Apr 12 #Python
python实现输入三角形边长自动作图求面积案例
Apr 12 #Python
Python3如何判断三角形的类型
Apr 12 #Python
You might like
VIM中设置php自动缩进为4个空格的方法详解
2013/06/14 PHP
PHP判断字符串长度的两种方法很实用
2015/09/22 PHP
PHP采用超长(超大)数字运算防止数字以科学计数法显示的方法
2016/04/01 PHP
Thinkphp框架中D方法与M方法的区别
2016/12/23 PHP
php实现获取近几日、月时间示例
2019/07/06 PHP
Swoole源码中如何查询Websocket的连接问题详解
2020/08/30 PHP
符合W3C网页标准的iframe标签的使用方法
2007/07/19 Javascript
jquery星级插件、支持页面中多次使用
2012/03/25 Javascript
JavaScript 用Node.js写Shell脚本[译]
2012/09/20 Javascript
使用jquery.upload.js实现异步上传示例代码
2014/07/29 Javascript
JavaScript实现的经典文件树菜单效果
2015/09/08 Javascript
解析利用javascript如何判断一个数为素数
2016/12/08 Javascript
Easyui Datagrid自定义按钮列(最后面的操作列)
2017/07/13 Javascript
JavaScript截屏功能的实现代码
2017/07/28 Javascript
vue.js,ajax渲染页面的实例
2018/02/11 Javascript
原生JS+HTML5实现跟随鼠标一起流动的粒子动画效果
2018/05/03 Javascript
JS实现电话号码的字母组合算法示例
2019/02/26 Javascript
JS学习笔记之闭包小案例分析
2019/05/29 Javascript
不刷新网页就能链接新的js文件方法总结
2020/03/01 Javascript
[09:13]2014DOTA2国际邀请赛 中国区预选赛coser表演
2014/05/23 DOTA
Python实现简单状态框架的方法
2015/03/19 Python
Windows下将Python文件打包成.EXE可执行文件的方法
2018/08/03 Python
在pandas多重索引multiIndex中选定指定索引的行方法
2018/11/16 Python
Pycharm 字体大小调整设置的方法实现
2019/09/27 Python
python3.8下载及安装步骤详解
2020/01/15 Python
python模拟哔哩哔哩滑块登入验证的实现
2020/04/24 Python
python爬虫爬取图片的简单代码
2021/01/18 Python
优秀的个人求职信范文
2014/05/09 职场文书
合同权益转让协议书模板
2014/11/18 职场文书
应届毕业生自荐信
2015/03/04 职场文书
学校中秋节活动总结
2015/03/23 职场文书
死者家属慰问信
2015/03/24 职场文书
投标售后服务承诺书
2015/04/29 职场文书
世界文化遗产导游词
2019/08/07 职场文书
Pandas数据结构之Series的使用
2022/03/31 Python
vue中使用mockjs配置和使用方式
2022/04/06 Vue.js