Domanda

Come esercitazione didattica per me Sto scrivendo un'applicazione in grado di mediare una serie di immagini. Questo è spesso usato in astrofotografia per ridurre il rumore.

La biblioteca che sto utilizzando è Magick ++ e ho riuscito a scrivere effettivamente l'applicazione. Ma, purtroppo, la sua lenta. Questo è il codice che sto usando:

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

Le medie codice 10 immagini passando attraverso ogni pixel e aggiungendo intensità dei pixel di ciascun canale in un doppia vettore. La funzione medio poi prende vettore come un parametro e medie il risultato. Questa media viene quindi utilizzato in corrispondenza del pixel corrispondente in stackedImage - che è l'immagine risultante. Funziona bene, ma come ho già detto, io non sono felice con la velocità. Ci vogliono 2 minuti e 30s secondi su una macchina Core i5. Le immagini sono da 8 megapixel e 16 bit TIFF. Capisco che il suo un sacco di dati, ma ho visto fare più velocemente in altre applicazioni.

E 'la mia ciclo questo è lento o è pixelColor (x, y) un modo lento per pixel di accesso in un'immagine? Esiste un modo più veloce?

È stato utile?

Soluzione

Perché usare vettori / matrici a tutti?

Perché non

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;

Questo evita 36 chiamate di funzione su oggetti vettoriali per pixel.

E si può ottenere prestazioni ancora migliori utilizzando una PixelCache dell'intera immagine al posto degli oggetti Image originali. Vedere la sezione "basso livello di pixel di accesso" della documentazione linea Magick ++ per l'immagine

Poi il ciclo interno diventa

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

Ora che hai rimosso anche 10 chiamate a PixelColor, 10 costruttori ColorRGB, e 30 funzioni d'accesso per pixel.

Nota, questo è tutto teoria; Non ho ancora testato qualsiasi di esso

Altri suggerimenti

Commenti:

  • Perché utilizzare vettori per red, blue e green? Perché l'utilizzo push_back in grado di eseguire riassegnazioni e collo di bottiglia di elaborazione. Si potrebbe invece allocare una sola volta tre array di 10 colori.
  • Non poteva dichiarare rgb al di fuori dei cicli al fine di alleviare pila di costruzioni e distruzioni inutili?
  • non Magick ++ hanno un modo per le immagini medie?

Nel caso in cui chiunque altro vuole immagini media per ridurre il rumore, e non si sente come troppo "esercizio educativo" ; -)

ImageMagick può fare la media di una sequenza di immagini come questa:

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

Si può anche fare il filtraggio mediana e gli altri, cambiando la parola mean nel comando precedente a quello che vuoi, per esempio:.

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

È possibile ottenere un elenco delle operazioni disponibili con:

identify -list evaluate

Output

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top