2012-08-09 16 views
6

Ich versuche ein vorzeichenbehaftetes Entfernungsfeld von schwarzen und weißen Pixelbildern zu berechnen, aber ich denke, ich habe es irgendwo geschafft, meinen Code falsch zu bekommen. Da dies meine Ein- und Ausgang:Berechnen eines zweidimensionalen signierten Distanzfeldes

Eingang

Input

Ausgabe

Output

Das Problem das ich habe die schwarze Linie in der Mitte des S, meine Verständnis lässt mich glauben, dass es komplett hellgrau sein sollte?

Dies ist der Code ich benutze:

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)); 
     } 
    } 

Antwort

3

Ihre Schuld daran ist diese Bedingung Aussage:

// If not equal a 
if (a != p) 
{ 

Dies bedeutet, dass Sie auf dem kürzesten Abstand von einem schwarzen Pixel nur daran interessiert sind, ein weißes Pixel, oder wenn 'a' weiß ist, dann suchen Sie nach dem nächsten schwarzen Pixel.

Wenn Sie diesen Test zu ändern, um zu sehen gerade:

if (p == white) 
{ 

Dann werden Sie wahrscheinlich bekommen, was Sie erwarten.

(Ich habe das nicht getestet, also hoffentlich ist es richtig).

(Auch, wenn es nicht richtig ist, wäre es schön, Ihre Math.Clamp Methode zu schreiben, da es nicht ein in der Bibliothek Methode in der Klasse Math gebaut ist.)

Ein letzte Sache, nicht Sicher, wenn der Algorithmus möchte, dass Sie ein Pixel mit sich selbst vergleichen oder nicht, so müssen Sie dies möglicherweise in Ihren verschachtelten for-Schleifen berücksichtigen.

(was würde man eigentlich erwarten, dass die Ausgabe eines völlig schwarzen Bildes mit einem weißen Pixel in der Mitte aussehen sollte? Sollte der Ausgang des mittleren Pixels schwarz sein, da es keine nahen weißen Pixel gibt, oder sollte es sein weiß.)

Verwandte Themen