thr*_*thr 11 .net c# math 2d distance
我正在尝试计算黑白图像像素的带符号距离场,但我想我已经设法在某处弄错了代码.因为这是我的输入和输出:
输入

产量

我遇到的问题是S中间的黑线,我的理解让我相信它应该是完全浅灰色的吗?
这是我正在使用的代码:
for (int x = 0; x < source.width; ++x)
{
for(int y = 0; y < source.height; ++y)
{
// Get pixel
float a = source.GetPixel(x, y).r;
// Distance to closest pixel which is the inverse of a
// start on float.MaxValue so we can be sure we found something
float distance = float.MaxValue;
// Search coordinates, x min/max and y min/max
int fxMin = Math.Max(x - searchDistance, 0);
int fxMax = Math.Min(x + searchDistance, source.width);
int fyMin = Math.Max(y - searchDistance, 0);
int fyMax = Math.Min(y + searchDistance, source.height);
for (int fx = fxMin; fx < fxMax; ++fx)
{
for (int fy = fyMin; fy < fyMax; ++fy)
{
// Get pixel to compare to
float p = source.GetPixel(fx, fy).r;
// If not equal a
if (a != p)
{
// Calculate distance
float xd = x - fx;
float yd = y - fy;
float d = Math.Sqrt((xd * xd) + (yd * yd));
// Compare absolute distance values, and if smaller replace distnace with the new oe
if (Math.Abs(d) < Math.Abs(distance))
{
distance = d;
}
}
}
}
// If we found a new distance, otherwise we'll just use A
if (distance != float.MaxValue)
{
// Clamp distance to -/+
distance = Math.Clamp(distance, -searchDistance, +searchDistance);
// Convert from -search,+search to 0,+search*2 and then convert to 0.0, 1.0 and invert
a = 1f - Math.Clamp((distance + searchDistance) / (searchDistance + searchDistance), 0, 1);
}
// Write pixel out
target.SetPixel(x, y, new Color(a, a, a, 1));
}
}
Run Code Online (Sandbox Code Playgroud)
你的罪魁祸首是这个条件声明:
// If not equal a
if (a != p)
{
Run Code Online (Sandbox Code Playgroud)
这意味着您只对从黑色像素到白色像素的最短距离感兴趣,或者如果“a”是白色,那么您正在寻找最近的黑色像素。
如果您将该测试更改为仅查看:
if ( p == white )
{
Run Code Online (Sandbox Code Playgroud)
然后你可能会得到你所期望的。
(我没有对此进行测试,所以希望它是正确的)。
(另外,如果不正确,最好发布您的 Math.Clamp 方法,因为它不是 Math 类中的内置库方法。)
最后一件事,不确定算法是否希望您将像素与其自身进行比较,因此您可能需要在嵌套 for 循环中考虑这一点。
(基本上,您期望输出应该是什么样子,中间有一个白色像素的全黑图像?中间像素的输出应该是黑色,因为附近没有白色像素,还是应该是白色。)