Frage

Als pädagogische Auszeichnung für mich selbst schreibe ich eine Anwendung, die durchschnittlich ein paar Bilder durchschnittlich kann. Dies wird häufig in der Astrophotographie verwendet, um das Rauschen zu reduzieren.

Die Bibliothek, die ich verwende, ist Magick ++, und es ist mir gelungen, die Anwendung tatsächlich zu schreiben. Aber leider ist es langsam. Dies ist der Code, den ich verwende:

for(row=0;row<rows;row++)
{
    for(column=0;column<columns;column++)
    {
        red.clear(); blue.clear(); green.clear();
        for(i=1;i<10;i++)
        {
            ColorRGB rgb(image[i].pixelColor(column,row));
            red.push_back(rgb.red());
            green.push_back(rgb.green());
            blue.push_back(rgb.blue());
        }
        redVal = avg(red);
        greenVal = avg(green);
        blueVal = avg(blue);
        redVal = redVal*MaxRGB; greenVal = greenVal*MaxRGB; blueVal = blueVal*MaxRGB;
        Color newRGB(redVal,greenVal,blueVal);
        stackedImage.pixelColor(column,row,newRGB);
    }
}

Der Code durchschnittlich 10 Bilder, indem er jedes Pixel durchläuft und die Pixelintensität jedes Kanals in a hinzufügt doppelt Vektor. Die Funktion avg Nimmt dann den Vektor als Parameter und durchschnittlich das Ergebnis. Dieser Durchschnitt wird dann am entsprechenden Pixel in verwendet Stackedimage - Welches ist das resultierende Bild. Es funktioniert gut, aber wie ich bereits erwähnt habe, bin ich mit der Geschwindigkeit nicht zufrieden. Es dauert 2 Minuten und 30 Sekunden auf einer Kern -i5 -Maschine. Die Bilder sind 8 Megapixel und 16 -Bit -Tiffs. Ich verstehe, dass es viele Daten ist, aber ich habe es in anderen Anwendungen schneller gemacht.

Ist es meine Schleife, die langsam oder ist Pixelcolor (x, y) Eine langsame Möglichkeit, in einem Bild auf Pixel zuzugreifen? Gibt es einen schnelleren Weg?

War es hilfreich?

Lösung

Warum überhaupt Vektoren/Arrays verwenden?

Warum nicht

double red=0.0, blue=0.0, green=0.0;
for(i=1;i<10;i++)
{
   ColorRGB rgb(image[i].pixelColor(column,row));
   red+=rgb.red();
   blue+=rgb.blue();
   green+=rgb.green();
}
red/=10;
blue/=10;
green/=10;

Dies vermeidet 36 Funktionsaufrufe auf Vektorobjekten pro Pixel.

Und Sie können mit a noch bessere Leistung erhalten PixelCache des gesamten Bildes statt des Originals Image Objekte. Siehe den Abschnitt "Image Pixel-Zugriff auf niedriger Ebene" der Online Magick ++ Dokumentation für Bild

Dann wird die innere Schleife

PixelPacket* pix = cache[i]+row*columns+column;
red+= pix->red;
blue+= pix->blue;
green+= pix->green;

Jetzt haben Sie außerdem 10 Anrufe an Pixelcolor, 10 Colorrgb -Konstruktoren und 30 Accessor -Funktionen pro Pixel entfernt.

Beachten Sie, das ist alles Theorie; Ich habe nichts davon getestet

Andere Tipps

Kommentare:

  • Warum verwenden Sie Vektoren für red, blue und green? Weil push_back Kann Reallocations und Engpassverarbeitung durchführen. Sie können stattdessen nur einmal drei Arrays mit 10 Farben zuweisen.
  • Könnten Sie nicht erklären? rgb Außerhalb der Schleifen, um einen Stapel unnötiger Konstruktionen und Zerstörungen zu entlasten?
  • Hat Magick ++ keine Möglichkeit zu Durchschnittsbildern?

Nur für den Fall, dass jemand anderes Bilder durchdurchschnittlich möchte, um das Geräusch zu reduzieren, und nicht zu viel anfühlt "Bildungsübung" ;-)

Imagemagick kann eine Abfolge von Bildern wie diesen Mittelwert haben:

convert image1.tif image2.tif ... image32.tif -evaluate-sequence mean result.tif

Sie können auch mittlere Filterung und andere durchführen, indem Sie das Wort ändern mean Im obigen Befehl an alles, was Sie wollen, zB:

convert image1.tif image2.tif ... image32.tif -evaluate-sequence median result.tif

Sie können eine Liste der verfügbaren Vorgänge erhalten mit:

identify -list evaluate

Ausgabe

Abs
Add
AddModulus
And
Cos
Cosine
Divide
Exp
Exponential
GaussianNoise
ImpulseNoise
LaplacianNoise
LeftShift
Log
Max
Mean
Median
Min
MultiplicativeNoise
Multiply
Or
PoissonNoise
Pow
RightShift
RMS
RootMeanSquare
Set
Sin
Sine
Subtract
Sum
Threshold
ThresholdBlack
ThresholdWhite
UniformNoise
Xor
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top