Monday, 15 February 2021

Which loss function calculates the distance between two contours

In my contour generation network i am using the nn.L1Loss() to caculate how many pixels are wrong. This works for training, but the 2D-Distance between the real contour and the fake would be way better. My aim is to measure the lenght of generated contours afterwards. This code example of two binary images shows where the nn.L1Loss() fails.

import cv2
import torch
from torch import nn

p1 = [(15, 15),(45,45)]
p2 = [(16, 15),(46,45)]

real = cv2.rectangle(np.ones((60,60)), p1[0], p1[1], color=0, thickness=1)
fake = cv2.rectangle(np.ones((60,60)), p2[0], p2[1], color=0, thickness=1)

cv2.imshow('image',np.hstack((real,fake)))
cv2.waitKey(0)

real = torch.tensor(real)
fake = torch.tensor(fake)

losss = [nn.L1Loss(), nn.MSELoss(), nn.BCELoss(), nn.HingeEmbeddingLoss(), nn.SmoothL1Loss()]
print(my_loss(real, fake))

for k, loss in enumerate(losss):
    err = loss(real, fake)
    print(err*60)

If i move the rectangle 1 pixel to the right:

-> L1 loss is 0.0333 * 60 = 2

If i move the rectangle 1 pixel to the right and 1 to the left:

-> L1 loss is 0.0656 * 60 = 3.933

If i move the rectangle 10 pixel to the right and 10 to the left:

-> L1 loss is 0.0656 * 60 = 3.933
still the same! Which is no suprise, the amount of wrong pixels is the same. But the distance to them changed by 10 * 2**1/2.

I also thought about the distance between both centers with this:

    M = cv2.moments(c)
    cX = int(M['m10'] /M['m00'])
    cY = int(M['m01'] /M['m00'])
    centers.append([cX,cY])

The problem here is that the generated contours are not identical to the real and thus have diffrent centers.

This answer is close to what i am looking for, but is computional very expensive?!

https://stackoverflow.com/a/36505073/12337147

Is there a custom loss functions to determine the distance like i discribed?



from Which loss function calculates the distance between two contours

No comments:

Post a Comment