Frage

Ich arbeite daran, Objekte, die auf der Farbe basierend auf der Farbe basieren, und ich habe die EMGUCV-Bibliothek verwendet, um mein Color-Image in Binäres Schwarz-Weiß-Bild zu schwellen.Die Thresholding selbst war ziemlich schnell, 50ms auf 320x240-Bild.Ich benutze RG-Chromatizitätsfarbraum, also gibt es notwendigerweise Berechnungen.

Jetzt versuche ich, es mit Zeigern zu beschleunigen, aber das Ergebnis ist sehr ähnlich, was ich mit EMGUCV (ca. 50ms pro Bild) tat.

Ich möchte fragen, wenn es etwas Fachmann gibt, der mir helfen kann, was ich falsch mache.Hier ist mein kurzer Code-Snippet meiner Farbschwellenwertung.Es basiert auf diesem ein http://www.bobpowell.net/onebit.htm .

generasacodicetagpre.
War es hilfreich?

Lösung

Sie machen für jedes Pixel viel unnötiger Math, um genaue Werte zu berechnen, nur um zu überprüfen, ob sie in einigen Grenzen sind.Sie können die Vergleiche vereinfachen, indem Sie einige Anpassungen an die Grenzwerte vorstellen.

Die einfachste Substitution ist für die Sättigung.Sie machen eine quadratische Wurzel, die Sie vermeiden können, indem Sie die Grenzwerte stattdessen quadrieren können. generasacodicetagpre.

Ein ähnlicher Trick kann mit dem Winkel verwendet werden.Anstatt den Winkel mit math.atan zu berechnen, falten Sie heraus, was diese Grenzwerte in Ihren R- und G-Reihen gleichsetzen.

Andere Tipps

Ich bin nicht sicher, ob es schneller ist.Aber hier habe ich einen Tipp geschrieben, wie manArbeit mit Bitmaps sehr schnell.

Für die Vollständigkeit wird hier eine modifizierte Version von Thresholding-Image in RG-Chromatizitätsfarbraum ist mehr als zweimal schneller als die Version in meiner Frage.

public static Bitmap ThresholdRGChroma(Bitmap original, Rectangle roi, double angle,
            double width, double satMin, double satMax)
        {
            Bitmap bimg = new Bitmap(original.Width, original.Height, PixelFormat.Format1bppIndexed);

BitmapData imgData = original.LockBits(new Rectangle(0, 0, original.Width, original.Height), ImageLockMode.ReadOnly, original.PixelFormat); BitmapData bimgData = bimg.LockBits(new Rectangle(0, 0, bimg.Width, bimg.Height), ImageLockMode.ReadWrite, bimg.PixelFormat); int pixelSize = 3; double r, g, sat, m; double satMin2 = satMin * satMin; double satMax2 = satMax * satMax; double cr = Math.Sin((2 * Math.PI * angle) / 360.0); double cg = Math.Cos((2 * Math.PI * angle) / 360.0); // Instead of (Math.Cos(2 * width / 180.0) + 1) / 2.0 I'm using pre-calculated <1; 0> values. double w2 = -width; unsafe { byte* R, G, B; byte* row; int RGBSum; for (int y = original.Height - 1; y >= 0; y--) { row = (byte*)imgData.Scan0 + (y * imgData.Stride); for (int x = original.Width - 1; x >= 0; x--) { B = &row[x * pixelSize]; G = &row[x * pixelSize + 1]; R = &row[x * pixelSize + 2]; RGBSum = *R + *G + *B; if (RGBSum == 0) { SetIndexedPixel(x, y, bimgData, false); continue; } r = (double)*R / RGBSum - _rgChromaOriginX; g = (double)*G / RGBSum - _rgChromaOriginY; m = cr * r + cg * g; sat = r * r + g * g; if (m > 0 && m * m > w2 * w2 * sat && sat >= satMin2 && sat <= satMax2) SetIndexedPixel(x, y, bimgData, true); else SetIndexedPixel(x, y, bimgData, false); } } } bimg.UnlockBits(bimgData); original.UnlockBits(imgData); return bimg; }

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top