AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Abstand (min, max, avg) in Bitmap

Ein Thema von cltom · begonnen am 12. Dez 2011 · letzter Beitrag vom 14. Dez 2011
Antwort Antwort
Furtbichler
(Gast)

n/a Beiträge
 
#1

AW: Abstand (min, max, avg) in Bitmap

  Alt 13. Dez 2011, 06:59
Du musst ja nicht jedesmal, wenn Du einen Punkt analysierst, die ganze Bitmap durchgehen.

1. Ermitteln der Positionen aller Punkte und aufteilen in Schwarz/Weiß.
2. Ermitteln aller Abstände zwischen zwei Punkten (weiss ->schwarz)
3. Ermitteln der Zielwerte Min/Max/Avg für jeden weissen Punkt

Erster Durchlauf: O(h*b). h,b = Dimension des Bitmaps.
Zweiter und dritter Durchlauf: O(n*m). n= Anzahl der gefundenen weissen Punkte, m=schwarze Punkte

Ist n*m überschaubar, gehts eins-fix-drei, Im theoretischen Worstcase jedoch O((h*b)^2). Die Frage lautet jedoch: Was ist der realistische Worstcase?

Selbst bei einigen Tausend Punkten solltest Du in überschaubarer Zeit hinkommen.

Code:
For x := 0 to bitmap.width - 1 do
  For y:= 0 to bitmap.height - 1 do
     case Bitmap.pixel[x,y] of
       White : WhitePoints.Add(x,y):
       Black : BlackPoints.Add(x,y):

Foreach Point W in WhitePoints do begin
  Foreach Point B in BlackPoints do
    W.Distances.Add(Distance(W,B));

  Output ('White Point ', W, 'Min=', W.Distance.Min, 'Max=', W.Distances.Max, 'Avg=',W.Distances.Avg);
end

Geändert von Furtbichler (13. Dez 2011 um 07:02 Uhr)
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.688 Beiträge
 
Delphi 2007 Enterprise
 
#2

AW: Abstand (min, max, avg) in Bitmap

  Alt 13. Dez 2011, 08:41
Sind das nun schwarze Punkte auf weissem Hintergrund, oder schwarze und weisse Punkte mite "Leerraum" dazwischen? Heisst "Punkt" bei dir Pixel, oder sind das eher kleine Pixelgrüppchen? Was ist der minimale und maximale Abstand in deinem Fall? (Verständnis des letzteren hängt von den anderen Fragen ab vermute ich.)

Eine Skizze, oder besser noch ein Realfall als Bild wären hier verdammt hilfreich. Weil so ohne weiteres an Kenntnis über die Struktur, bleibt erstmal wirklich nur alle paarweisen Abstände einzeln durchzukauen. Man kann zwar, wenn es nur um größer/kleiner geht zunächst die Wurzelei einsparen, aber es bleibt dennoch eine Zahlenschlacht
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
cltom

Registriert seit: 22. Sep 2005
230 Beiträge
 
Delphi 12 Athens
 
#3

AW: Abstand (min, max, avg) in Bitmap

  Alt 13. Dez 2011, 15:21
Vielen Dank einmal für die Antworten.

Zu den Fragen:

Die Bitmaps enthalten Kreise und Rechtecke in regelmäßiger Verteilung/Anordnung. Typischerweise 10-40% der Fläche ist schwarz. Im Wesentlichen ein (Loch)Gitter, Beispiel anbei.

Bekannt sind die Koordinaten der Punkte sowie deren Radius. Gesucht ist eben von jedem (weissen) Punkt der kleinstmögliche Weg zum nächsten schwarzen Punkt. Wenn ich also irgendwo auf einem weissen Pixel lande, wie weit ist der Weg maximal, bis ich zum nächsten schwarzen Punkt komme. Und über diesen Weg eine Art Histogramm oder eben min. max. avg. (der kürzeste Weg ist offensichtlich gerade ein Pixel zum nächsten Punkt, interessant sind mehr der mittlere und der längste Weg).

In Anlehnung an Deinen Vorschlag, Furtbichler, könnte man also die Randpunkte der Kreise nehmen und damit schon mal eingrenzen. Die Menge aller Punkte innerhalb des Kreises fällt weg, das reduziert den Aufwand.

Alternativ: ich gehe für jeden weissen Punkt alle (bekannten) Objekte durch und schaue, wie weit sie entfernt sind.

Je mehr ich darüber nachdenke, desto eher wird klar, dass der Ansatz falsch ist, es pixelbasiert zu lösen und nicht anhand der Koordinaten der Objekte ...
Angehängte Grafiken
Dateityp: jpg example.jpg (30,3 KB, 4x aufgerufen)
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.688 Beiträge
 
Delphi 2007 Enterprise
 
#4

AW: Abstand (min, max, avg) in Bitmap

  Alt 13. Dez 2011, 15:31
Darauf zielte meine Fragerei auch ab Wenn du die Mittelpunkte und Radien hast, wird das Problem ja fast schon trivial. Man kann sich zwar nicht sparen alle "weissen Pixel" durchzugehen, aber dann musst du ja nur noch die Abstände zu deinen Mittelpunkten minus der Radien errechnen.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.688 Beiträge
 
Delphi 2007 Enterprise
 
#5

AW: Abstand (min, max, avg) in Bitmap

  Alt 13. Dez 2011, 20:23
Mal obiges in Code gegossen, da ich leider zuhause aber kein Delphi habe in C#. Aber das geht hoffe ich als Pseudocode durch (Achtung, grausig Quick&Dirty):
Code:
      public int[] CentersX, CentersY;
      public int[] Radii;
      
      public float MinDist(int x, int y)
      {
         float min = float.MaxValue;
         for (int i=0; i<CentersX.Length; i++)
         {
            float xx = x-CentersX[i];
            float yy = y-CentersY[i];
            float tmp = (float)(Math.Sqrt(xx*xx+yy*yy)-(float)Radii[i]);
            if (tmp<min) min = tmp;
         }
         return min;
      }
      
      void Button1Click(object sender, EventArgs e)
      {
         Bitmap b = new Bitmap(pictureBox1.Width, pictureBox1.Height);
         // Zufällige Kreise erzeugen. 4-9 Stück, mit Radius von 50-100 und Mittelpunkt im Bild
         Random rng = new Random();
         int count = (int)(rng.NextDouble()*5)+5; // im Bild unten war count = 9
         CentersX = new int[count];
         CentersY = new int[count];
         Radii = new int[count];
         for (int i=0; i<count; i++)
         {
            CentersX[i] = (int)(rng.NextDouble()*pictureBox1.Width);
            CentersY[i] = (int)(rng.NextDouble()*pictureBox1.Height);
            Radii[i] = (int)(rng.NextDouble()*50)+50;
         }
         for (int y=0; y<pictureBox1.Height; y++)
         {
            for (int x=0; x<pictureBox1.Width; x++)
            {
               float f = MinDist(x, y);
               // die Verwurstung mit 127 ist nur so, damit ich nachher nett auf Grauwerte zwischen 0 und 254 skalieren kann,
               // und die Abnahme in der Farbe doppelt so schnell ist wie die eigentliche Distanz. War optisch netter.
               if ((f>0) && (f<=127))
               {
                  int c = (int)((127-f)*2f);
                  b.SetPixel(x, y, Color.FromArgb(255, c, c, c));
               }
               else
               {
                  b.SetPixel(x, y, Color.Black);
               }
            }
         }
         pictureBox1.Image = b;
      }
Das Bild im Anhang ist so entstanden. Zumindest bei konstanten Radien ist man da, wie ich vermutet hatte, ganz ganz nah an der Delaunay-Triangulation. Vielleicht ist über diesen Weg noch etwas für dich herauszuholen, weil auch wenn man mit o.g. Variante "nur" O(Width*Height*CircleCount) hat, ist es zumindest für Echtzeiteinsätze kaum geeignet. (Der Code von mir unter C# brauchte für 800x600 Pixel große Bilder so runde 200-300ms auf einem Core i7 950.)
Edit: Schaut ein wenig aus wie ein Kalottenmodell


Eine ganz andere Idee wäre noch Gaussfilterung des Ausgangsbildes. Bei geeignet großem Radius des Filters sollte sich nachher ein zumindest ähnliches Bild ergeben, nur ist ein so großer, akkurater Gaussfilter auch nicht gerade der Performance bester Freund, und man würde da keine echten Distanzen bekommen, sondern nur ablesen können, an welchen Stellen sich die "Ridges" in den Mitten zwischen den Kreisen befänden. Am Ende muss man schließlich egal wie jeden Pixel einzeln anfassen.
Noch eine Methode wäre eine "missbrauchte" Shepard Interpolation, die aber das gleiche Laufzeitverhalten wie die oben implementierte Version hat.
Angehängte Grafiken
Dateityp: png kreise.png (50,7 KB, 8x aufgerufen)
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)

Geändert von Medium (13. Dez 2011 um 20:32 Uhr)
  Mit Zitat antworten Zitat
cltom

Registriert seit: 22. Sep 2005
230 Beiträge
 
Delphi 12 Athens
 
#6

AW: Abstand (min, max, avg) in Bitmap

  Alt 14. Dez 2011, 09:39
whow, das ist immer wieder unglaublich, wie schnell man hier hochwertiges Futter bekommt. Ich schaue mir das mal durch, vielen Dank!
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:08 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz