如何从多边形中带有空白掩码或多边形的多边形生成掩码?
How to generate mask from polygons with blank mask or polygon inside polygon?
我以这种方式从遮罩生成多边形(json):
def mask_to_json(mask, file_name, labelname = 'cranes'):
annotation = {
"lineColor": [0,255,0,128],
"shapes": [],
"imagePath": file_name,
"imageData": None,
"fillColor": [255,0,0,128]
}
contours = measure.find_contours(mask, 0.5)
contours = sorted(contours, key=len, reverse=True) #[:1]
shape_dict = {"points":[], "line_color": None, "fill_color": None, "label": labelname}
for n, contour in enumerate(contours):
coords = measure.approximate_polygon(contour, tolerance=3)[:-1]
segmentation = np.flip(coords, axis=1).tolist()
cur_shape = copy.deepcopy(shape_dict)
cur_shape["points"] = segmentation
annotation["shapes"].append(cur_shape)
file = file_name.replace(".jpg", ".json")
#return annotation
with open(file, 'w') as outfile:
json.dump(annotation, outfile, indent=2)
它工作得很好,但就我而言,我在多边形内部得到了多边形,我不知道如何获得正确的可视化效果:
我有这样的代码可以去除这样的多边形:
从 PIL 导入图像,ImageDraw
def polygons_to_mask_array_labelme(polygons, width : int = 300, height : int = 300) -> np.ndarray:
'''
This function takes a list of lists that contains polygon masks for each building. Example;
[[x11,y11,x12,y12,...],...,[xn1,yn1,xn2,yn2,...]]
The return of this function is an array of size width x height which contains a binary mask
as defined by the list of polygons
Example usage:
import json
with open(json_names[0], encoding = 'utf-8') as f:
data = json.load(f)
plt.imshow(polygons_to_mask_array(data['shapes'], 898, 559))
'''
img = Image.new('L', (width, height), 0)
for polygon in polygons:
nested_lst_of_tuples = [tuple(l) for l in polygon['points']]
try:
ImageDraw.Draw(img).polygon(nested_lst_of_tuples, outline=1, fill=1)
except:
print(nested_lst_of_tuples)
mask = np.array(img)
return mask
如何从这些多边形中正确恢复遮罩?
更新:
如果我将调用其他多边形内的每个多边形此函数 ImageDraw
不填充区域,我可以将其设为空白:
ImageDraw.Draw(img).polygon(nested_lst_of_tuples, outline=0, fill=0)
所以没有问题如何找到其他多边形内部的多边形
这样解决了。我只是检查是否有任何多边形包含其他多边形:
from shapely.geometry.polygon import Polygon
def polygons_to_mask_array(polygons, width : int = 300, height : int = 300) -> np.ndarray:
img = Image.new('L', (width, height), 0)
for polygon in polygons:
nested_lst_of_tuples = [tuple(l) for l in polygon['points']]
if len(nested_lst_of_tuples)<=2: continue
ImageDraw.Draw(img).polygon(nested_lst_of_tuples, outline=1, fill=1)
for polygon in polygons:
nested_lst_of_tuples = [tuple(l) for l in polygon['points']]
if len(nested_lst_of_tuples)<=2: continue
if is_polygons_contains_polygon(polygons, nested_lst_of_tuples):
ImageDraw.Draw(img).polygon(nested_lst_of_tuples, outline=0, fill=0)
mask = np.array(img)
return mask
def is_polygons_contains_polygon(all_polygons, polygon):
for possible_bigger_polyg in all_polygons:
possible_bigger_polyg = [tuple(l) for l in possible_bigger_polyg['points']]
if len(possible_bigger_polyg)<=2: continue
if possible_bigger_polyg != polygon and Polygon(possible_bigger_polyg).contains(Polygon(polygon)):
return True
return False
我以这种方式从遮罩生成多边形(json):
def mask_to_json(mask, file_name, labelname = 'cranes'):
annotation = {
"lineColor": [0,255,0,128],
"shapes": [],
"imagePath": file_name,
"imageData": None,
"fillColor": [255,0,0,128]
}
contours = measure.find_contours(mask, 0.5)
contours = sorted(contours, key=len, reverse=True) #[:1]
shape_dict = {"points":[], "line_color": None, "fill_color": None, "label": labelname}
for n, contour in enumerate(contours):
coords = measure.approximate_polygon(contour, tolerance=3)[:-1]
segmentation = np.flip(coords, axis=1).tolist()
cur_shape = copy.deepcopy(shape_dict)
cur_shape["points"] = segmentation
annotation["shapes"].append(cur_shape)
file = file_name.replace(".jpg", ".json")
#return annotation
with open(file, 'w') as outfile:
json.dump(annotation, outfile, indent=2)
它工作得很好,但就我而言,我在多边形内部得到了多边形,我不知道如何获得正确的可视化效果:
我有这样的代码可以去除这样的多边形: 从 PIL 导入图像,ImageDraw
def polygons_to_mask_array_labelme(polygons, width : int = 300, height : int = 300) -> np.ndarray:
'''
This function takes a list of lists that contains polygon masks for each building. Example;
[[x11,y11,x12,y12,...],...,[xn1,yn1,xn2,yn2,...]]
The return of this function is an array of size width x height which contains a binary mask
as defined by the list of polygons
Example usage:
import json
with open(json_names[0], encoding = 'utf-8') as f:
data = json.load(f)
plt.imshow(polygons_to_mask_array(data['shapes'], 898, 559))
'''
img = Image.new('L', (width, height), 0)
for polygon in polygons:
nested_lst_of_tuples = [tuple(l) for l in polygon['points']]
try:
ImageDraw.Draw(img).polygon(nested_lst_of_tuples, outline=1, fill=1)
except:
print(nested_lst_of_tuples)
mask = np.array(img)
return mask
如何从这些多边形中正确恢复遮罩?
更新:
如果我将调用其他多边形内的每个多边形此函数 ImageDraw
不填充区域,我可以将其设为空白:
ImageDraw.Draw(img).polygon(nested_lst_of_tuples, outline=0, fill=0)
所以没有问题如何找到其他多边形内部的多边形
这样解决了。我只是检查是否有任何多边形包含其他多边形:
from shapely.geometry.polygon import Polygon
def polygons_to_mask_array(polygons, width : int = 300, height : int = 300) -> np.ndarray:
img = Image.new('L', (width, height), 0)
for polygon in polygons:
nested_lst_of_tuples = [tuple(l) for l in polygon['points']]
if len(nested_lst_of_tuples)<=2: continue
ImageDraw.Draw(img).polygon(nested_lst_of_tuples, outline=1, fill=1)
for polygon in polygons:
nested_lst_of_tuples = [tuple(l) for l in polygon['points']]
if len(nested_lst_of_tuples)<=2: continue
if is_polygons_contains_polygon(polygons, nested_lst_of_tuples):
ImageDraw.Draw(img).polygon(nested_lst_of_tuples, outline=0, fill=0)
mask = np.array(img)
return mask
def is_polygons_contains_polygon(all_polygons, polygon):
for possible_bigger_polyg in all_polygons:
possible_bigger_polyg = [tuple(l) for l in possible_bigger_polyg['points']]
if len(possible_bigger_polyg)<=2: continue
if possible_bigger_polyg != polygon and Polygon(possible_bigger_polyg).contains(Polygon(polygon)):
return True
return False