当前位置:网站首页>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
边栏推荐
- Lightweight dynamic monitorable thread pool based on configuration center - dynamictp
- poj 3237 Tree(樹鏈拆分)
- 854. String BFS with similarity K
- Regular expressions and re Libraries
- Poj3414 extensive search
- Storage optimization of performance tuning methodology
- Advantages and disadvantages of the "Chris Richardson microservice series" microservice architecture
- Multiplexing of Oracle control files
- Business learning of mall commodity module
- EBS Oracle 11g 克隆步骤(单节点)
猜你喜欢

Win11缺少dll文件怎么办?Win11系统找不到dll文件修复方法

Official clarification statement of Jihu company

The American Championship is about to start. Are you ready?

Database recovery strategy

元宇宙中的三大“派系”

Lightweight dynamic monitorable thread pool based on configuration center - dynamictp

An exception occurred in Huawei game multimedia calling the room switching method internal system error Reason:90000017

Concurrency control of performance tuning methodology

Granularity of blocking of concurrency control

AD637使用筆記
随机推荐
CRM creates its own custom report based on fetch
EBS Oracle 11g 克隆步骤(单节点)
Robot framework setting variables
Codeforces 12D ball tree array simulation 3 sorting elements
The American Championship is about to start. Are you ready?
Poj3414 extensive search
PyGame practical project: write Snake games with 300 lines of code
让开发效率提升的跨端方案
Blocking protocol for concurrency control
PIP install beatifulsoup4 installation failed
poj 3237 Tree(樹鏈拆分)
Cross end solutions to improve development efficiency
从零开始实现lmax-Disruptor队列(四)多线程生产者MultiProducerSequencer原理解析
[Yugong series] go teaching course in July 2022 004 go code Notes
ICMP 介绍
How to add new fields to mongodb with code (all)
Image editor for their AutoLayout environment
Sentinel production environment practice (I)
Kingbasees v8r3 cluster maintenance case -- online addition of standby database management node
An exception occurred in Huawei game multimedia calling the room switching method internal system error Reason:90000017