labelme共边算法
效果图:可以看到 线与线之间重合
如果需要想自己写算法,可以参考shapely中文文档
这里附上我自己写的算法
from shapely.geometry import Polygon, mapping
from qtpy import QtCore
import copy
import cv2
import numpy as np
def rec_to_polygon(shape) :
"""
矩形转shapely多边形对象
"""
points = [[i.x(), i.y()] for i in shape.points]
_x1 = points[0][0]
_y1 = points[0][1]
_x2 = points[1][0]
_y2 = points[1][1]
x1 = min(_x1, _x2)
x2 = max(_x1, _x2)
y1 = min(_y1, _y2)
y2 = max(_y1, _y2)
print([[x1, y1], [x2, y1], [x2, y2], [x1, y2], [x1, y1]])
_p = Polygon([[x1, y1], [x2, y1], [x2, y2], [x1, y2], [x1, y1]])
return _p
def merge_border(target_shape, shapes) :
"""
共边
target_shape shape对象 需要共边的shape
shapes 本张图片所有标注信息
:return:
"""
try :
new_shapes = [] # 一个多边形共边时 会产生多个多边形,只保存面积最大的两个
target = Polygon([[i.x(), i.y()] for i in target_shape.points]) # 只共边出一个多边形时 修改target 否则返回new_shapes
inters = []
for shape in shapes : # shapes 包含本张图片的所有标注信息
if shape.shape_type in ["polygon", "rectangle"] and shape != target_shape : # 过滤掉非矩形 非多边形
if shape.shape_type == "rectangle" : # 如果是矩形 需要转成多边形处理
_p = rec_to_polygon(shape)
if _p.intersects(target) or target.within(_p) :
inters.append(_p)
continue
points = [[i.x(), i.y()] for i in shape.points]
if len(points) <= 2 :
continue
_p = Polygon([[i.x(), i.y()] for i in shape.points])
if _p.intersects(target) or target.within(_p) :
inters.append(_p)
for _inter in inters :
if _inter.is_valid :
target = target - _inter # 核心部分 共边算法
print(mapping(target))
if target.type == "GeometryCollection" : # 有线条 有多边形
geometries = mapping(target).get('geometries')
# 找到第一个多出来的多边形 坐标赋值给target_shape
_add_polygons = []
for index, geometry in enumerate(geometries) :
if geometry["type"] == "Polygon" :
_p = Polygon(geometry["coordinates"][0])
if _p.area > 10 and len(
geometry["coordinates"][0][:-1]) >= 3 : # 共边结果新增的多边形需要过滤掉小于3的面积 这里只是随便设
test_p = Polygon([[x, y] for x, y in geometry["coordinates"][0][:-1]])
if not test_p.is_valid :
continue
_add_polygons.append(test_p)
_add_polygons.sort(key=lambda x : x.area, reverse=True)
if _add_polygons :
coordinates = mapping(_add_polygons[0]).get('coordinates')
if coordinates and len(coordinates[0][:-1]) >= 3 :
target_shape.points = []
new_points = []
for x, y in coordinates[0][:-1] :
if [x, y] in new_points :
continue
else :
new_points.append([x, y])
for x, y in new_points :
target_shape.addPoint(QtCore.QPointF(x, y))
elif target.type == "Polygon" :
coordinates = mapping(target).get('coordinates')
if coordinates :
if len(coordinates[0][:-1]) >= 3 :
target_shape.points = [] # 重置
new_points = []
for x, y in coordinates[0][:-1] :
if [x, y] in new_points :
continue
else :
new_points.append([x, y])
for x, y in new_points :
target_shape.addPoint(QtCore.QPointF(x, y))
elif target.type == "MultiPolygon" :
MultiPolygons = mapping(target)['coordinates']
MultiPolygons.sort(key=lambda p : Polygon(p[0]).area, reverse=True)
polygon_coordinates = MultiPolygons[0][0]
polygon_coordinates1 = MultiPolygons[1][0]
print(polygon_coordinates)
target_shape.points = []
new_points = []
for x, y in polygon_coordinates :
if [x, y] in new_points :
continue
else :
new_points.append([x, y])
for x, y in new_points :
target_shape.addPoint(QtCore.QPointF(x, y))
target_shape1 = copy.deepcopy(target_shape)
target_shape1.points = []
new_points = []
for x, y in polygon_coordinates1 :
if [x, y] in new_points :
continue
else :
new_points.append([x, y])
for x, y in new_points :
target_shape1.addPoint(QtCore.QPointF(x, y))
new_shapes.append(target_shape1)
return new_shapes
except Exception as e :
print(str(e))
return None
若有不对的地方,请大佬指点