当前位置:网站首页>boundary IoU 的计算方式
boundary IoU 的计算方式
2022-07-05 22:03:00 【氵文大师】
Boundary IoU 说白了就是计算 预测图片的边界 和 GT图片的边界 的 IoU

就是酱紫的两个边界计算 IoU 就好
问题是怎么计算上图这样的边界呢? ,用Canny边缘检测之类的? 算个梯度? 可是要边界啊,在分割的区域内部也有可能有边缘啊,这个不是边界吧
我们可以采用Boundary IoU原文的计算方式
这是原图:
我们可以让原图缩小一圈,就像这样
然后原图减去缩小版的图,就得到了边界
那怎么才能得到缩小版的原图呢? 这就请出了主角:腐蚀
可以参考这里:
OpenCV 图像处理之膨胀与腐蚀
腐蚀操作和膨胀操作相反,也就是将毛刺消除,判断方法为:在卷积核大小中对图片进行卷积。
取图像中(3 * 3)区域内的最小值。由于我们是二值图像,也就是取0(黑色)。 总结: 只要原图片3 * 3范围内有黑的,该像素点就是黑的。
接下来直接看看代码吧,代码见 Reference:
# GitHub repo: https://github.com/bowenc0221/boundary-iou-api
# Reference: https://gist.github.com/bowenc0221/71f7a02afee92646ca05efeeb14d687d
import cv2
import numpy as np
import matplotlib.pyplot as plt
# General util function to get the boundary of a binary mask.
# 该函数用于获取二进制 mask 的边界
def mask_to_boundary(mask, dilation_ratio=0.02):
""" Convert binary mask to boundary mask. :param mask (numpy array, uint8): binary mask :param dilation_ratio (float): ratio to calculate dilation = dilation_ratio * image_diagonal :return: boundary mask (numpy array) """
h, w = mask.shape
img_diag = np.sqrt(h ** 2 + w ** 2) # 计算图像对角线长度
dilation = int(round(dilation_ratio * img_diag))
if dilation < 1:
dilation = 1
# Pad image so mask truncated by the image border is also considered as boundary.
new_mask = cv2.copyMakeBorder(mask, 1, 1, 1, 1, cv2.BORDER_CONSTANT, value=0)
kernel = np.ones((3, 3), dtype=np.uint8)
new_mask_erode = cv2.erode(new_mask, kernel, iterations=dilation)
# 因为之前向四周填充了0, 故而这里不再需要四周
mask_erode = new_mask_erode[1 : h + 1, 1 : w + 1]
# G_d intersects G in the paper.
return mask - mask_erode
def boundary_iou(gt, dt, dilation_ratio=0.02):
""" Compute boundary iou between two binary masks. :param gt (numpy array, uint8): binary mask :param dt (numpy array, uint8): binary mask :param dilation_ratio (float): ratio to calculate dilation = dilation_ratio * image_diagonal :return: boundary iou (float) """
gt_boundary = mask_to_boundary(gt, dilation_ratio)
dt_boundary = mask_to_boundary(dt, dilation_ratio)
intersection = ((gt_boundary * dt_boundary) > 0).sum()
union = ((gt_boundary + dt_boundary) > 0).sum()
boundary_iou = intersection / union
return boundary_iou
mask_to_boundary 函数用于计算边界的 mask,而 boundary_iou 用于计算 boundary_iou ,boundary_iou 中会调用 mask_to_boundary .
这一行用于给原图的四周添加0, 这样连边界区域的目标像素也会被腐蚀掉
# Pad image so mask truncated by the image border is also considered as boundary.
new_mask = cv2.copyMakeBorder(mask, 1, 1, 1, 1, cv2.BORDER_CONSTANT, value=0)
以下是 cv2.copyMakeBorder 操作的示意图,其实直接叫 Padding 就好了
这两行用于给图像做腐蚀操作,kernel size 是(3, 3)
kernel = np.ones((3, 3), dtype=np.uint8)
new_mask_erode = cv2.erode(new_mask, kernel, iterations=dilation) # iterations 指的是腐蚀的次数
再来看下 dilation 的计算:
h, w = mask.shape
img_diag = np.sqrt(h ** 2 + w ** 2) # 计算图像对角线长度
dilation = int(round(dilation_ratio * img_diag))
if dilation < 1:
dilation = 1
腐蚀的次数与对角线的长度成正比,如果小于1则直接给1,dilation_ratio 是函数的参数
再看最后一步:
# 因为之前向四周填充了0, 故而这里不再需要四周
mask_erode = new_mask_erode[1 : h + 1, 1 : w + 1]
将周边的padding像素去掉,之后再将二者减掉就可:
return mask - mask_erode
最后就得到这个图:
boundary_iou 的计算方式和一般的 IoU 计算方式一样,有个问题就是,如果交集onion==0时,可能存在除0错误的问题,他这个代码里没有
所以应该改为:
def boundary_iou(gt, dt, dilation_ratio=0.02):
""" Compute boundary iou between two binary masks. :param gt (numpy array, uint8): binary mask :param dt (numpy array, uint8): binary mask :param dilation_ratio (float): ratio to calculate dilation = dilation_ratio * image_diagonal :return: boundary iou (float) """
gt_boundary = mask_to_boundary(gt, dilation_ratio)
dt_boundary = mask_to_boundary(dt, dilation_ratio)
intersection = ((gt_boundary * dt_boundary) > 0).sum()
union = ((gt_boundary + dt_boundary) > 0).sum()
if union < 1:
return 0
boundary_iou = intersection / union
return boundary_iou
边栏推荐
- A long's perception
- Meituan dynamic thread pool practice ideas, open source
- Sentinel production environment practice (I)
- MySQL disconnection reports an error MySQL ldb_ exceptions. OperationalError 4031, The client was disconnected by the server
- Microservice link risk analysis
- oracle 控制文件的多路复用
- Kingbasees v8r3 cluster maintenance case -- online addition of standby database management node
- Common interview questions of JVM manufacturers
- The solution to the problem that Oracle hugepages are not used, causing the server to be too laggy
- 华为云ModelArts文本分类–外卖评论
猜你喜欢

华为云ModelArts文本分类–外卖评论

Overview of database recovery

database mirroring

The Blue Bridge Cup web application development simulation competition is open for the first time! Contestants fast forward!

U盘的文件无法删除文件怎么办?Win11无法删除U盘文件解决教程

Livelocks and deadlocks of concurrency control

微服务入门(RestTemplate、Eureka、Nacos、Feign、Gateway)

Summary of concurrency control

Shell script, awk condition judgment and logic comparison &||

Pl/sql basic syntax
随机推荐
Dbeaver executes multiple insert into error processing at the same time
Scenario interview: ten questions and ten answers about distributed locks
Official clarification statement of Jihu company
大约SQL现场“这包括”与“包括在”字符串的写法
HDU 4391 paint the wall segment tree (water
Lightweight dynamic monitorable thread pool based on configuration center - dynamictp
poj 3237 Tree(樹鏈拆分)
Oracle HugePages没有被使用导致服务器很卡的解决方法
C language knowledge points link
Hysbz 2243 staining (tree chain splitting)
Index optimization of performance tuning methodology
Form artifact
DataGrid directly edits and saves "design defects"
Pointer parameter passing vs reference parameter passing vs value parameter passing
AD637使用筆記
EBS Oracle 11g 克隆步骤(单节点)
An exception occurred in Huawei game multimedia calling the room switching method internal system error Reason:90000017
Ad637 notes d'utilisation
每日刷题记录 (十四)
Interview questions for basic software testing