Nur eine kleine Frage am Rande:
Resampling bezieht sich hier doch strikt auf die klassische Mittelwertbildung ein einem n x n Pixelbereich.
Sobald man etwas anderes macht z.B. bikubisch interpoliert, Verkleinern mit Schärfen auswählt oder so etwas wie einen Lancoz-Filter verwendet (also im Prinzip das nutzt was Photoshop anbietet) sieht das mit dem Rauschen wieder anders aus, oder?
O.B.d.A. können wir uns bei einer
orthogonalen Bild-Transformation (d.h. einer Transformation, bei der die beiden Koordinatenachsen senkrecht aufeinander stehen)
auf die Transformation einer Koordinate beschränken. n-dimensionale Systeme transformiert man, indem man alle Koordinaten getrennt transformiert.
Resampeln ist das Umrechnen eines mindestens in einer Richtung
diskretisierten bzw. abgetastenen Signals (Umgangsdeutsch: digital) von einer Basis in eine andere Basis.
Das Signal braucht dazu nicht quantisiert zu sein (d.h. es kann wertekontinuierlich sein), auch braucht das Signal nicht äquidistant abgetastet zu sein.
Die generische Formel (für
FIR-Filter) dazu lautet:
x_j ist dabei das Eingangssignal, y_i das Ausgangssignal, A_ij sind Zahlen.
Wenn wir uns
O.B.d.A. auf Filter beschränken, die eine Verstärkung von 1 haben, muß für alle i
gelten. Aufwandsmäßig zerfällt die Filterung in zwei Teile:
- A_ij bestimmen
- Sum x_j A_ij berechnen
Der numerische Aufwand für die erste Operation ist meist sehr klein, dafür steckt dort das KnowHow der Filterung. Die zweite Operation ist trivial, dort steckt aber der numerische Aufwand.
Beschränken wir uns auf umsetzbare FIR-Filter
Die zweite Operation ist trivial, weil einfach nur x0 * A0 + x1 * A1 + x2 * A2 + x3 * A3 + ... berechnet werden muß. Für jeden Pixel. Zu Zeiten des 386 und 486 war das aufwendig.
Heutige CPUs sind etwa um den Faktor 30.000 schneller geworden.
Die erste Operation hält sich in Grenzen, wenn einer der folgenden Bedingungen erfüllt ist:
- mehrdimensionale Filterung für A*B*... Pixel erfordert A+B+... Filtersätze. Worst Case!
- bei eindimensionalen Filtern wiederholen sich bei rationalen Umrechnungsfaktoren die Filter nach einer gewissen Periode. Der schlimmste Fall ist so in der Praxis 44,1 kHz auf 48 kHz (147:160), was je nach Richtung 147 oder 160 Filtersätze erfordert.
Beschränken wir uns auf Filter endlicher Länge L (sonst gibt es etwas Probleme mit der Berechenbarkeit), so vereinfacht sich die Formel zu:
Code:
L-1
y_i = Sum x_(n_i + j) A_ij
j=0
L ist hierbei die Länge, n_i sind die Einsatzpunkte der Filter, A_ij die Filterkoeffizienten.
Ein Filtersatz in C würde dann z.B. so aussehen:
Code:
struct {
int n ; // Offset des ersten Samples, der in die Berechnung eingeht
int L ; // Länge des FilterSets
float A[L]; // Wichtungskoeffizienten (Summe = 1)
} FSet_t ;
Ein Filter so:
Code:
struct {
int N ; // Nach Abarbeitung der M FilterSets (es sind dabei M Outputs entstanden) wird im Eingangsdatenstrom um N weitergesprungen
int M ; // Anzahl der FilterSets
FSet_t F[M]; // die M Filtersets
} F_t ;
und die generische Filterroutine:
Code:
void
DoFilter (float* Y, float const* X, struct F_t const* const p)
{
for (;;)
{
for (i = 0; i < p->M; i++ )
{
sum = 0;
for (j = 0; j < p->F[i].L; j++ )
sum += X[p->F[i].n+j] * p->F[i].A[j];
Y[i] = sum;
}
Y += p->M;
X += p->N;
}
}
Beispiel 1: Einfacher Filter aus 1 mach 2:
Code:
{
1,
2,
{
{ 0, 1, {1.0 } },
{ -1, 4, {0.1, 0.4, 0.4, 0.1 } }
}
}
Beispiel 2: Einfacher Filter aus 2 mach 3:
Code:
{
2,
3,
{
{ 0, 1, {1.0 } },
{ -1, 4, {0.2, 0.5, 0.3, 0.1 } },
{ -1, 4, {0.1, 0.3, 0.5, 0.2 } }
}
}