imresize - versuchen zu verstehen, die bikubische interpolation
Ich versuche zu verstehen, die Funktion:
function [weights, indices] = contributions(in_length, out_length, ...
scale, kernel, ...
kernel_width, antialiasing)
if (scale < 1) && (antialiasing)
% Use a modified kernel to simultaneously interpolate and
% antialias.
h = @(x) scale * kernel(scale * x);
kernel_width = kernel_width / scale;
else
% No antialiasing; use unmodified kernel.
h = kernel;
end
Verstehe ich nicht wirklich was bedeutet diese Zeile bedeutet
h = @(x) scale * kernel(scale * x);
meine Waage ist 0,5
kernel ist kubisch.
Aber anders als das, was bedeutet es?
Ich denke, es ist wie erstellen Sie eine Funktion, die aufgerufen werden, später ?
Du musst angemeldet sein, um einen Kommentar abzugeben.
imresize
führt anti-aliasing, wenn das downsizing ein Bild, indem Sie einfach die Erweiterung der cubic-kernel, sondern als eine diskrete pre-processing Schritt.Für eine
kernel_width
4 Pixel (8 nach re-skaliert), wo diecontributions
- Funktion nutzt 10 Nachbarn für jedes pixel, daskernel
vsh
(skaliert kernel) Aussehen (denormalisiert, ignorieren, x-Achse):Dies ist einfacher, als erste bei einer low-pass-filter oder GAUSS-Faltung in einem separaten pre-processing Schritt.
Die kubische kernel definiert ist, an der Unterseite der
imresize.m
als:PDF-Datei, auf die verwiesen wird Papier.
Den relevanten Teil der Gleichung (15):
Dies ist eine spezifische version der Allgemeinen interpolation Gleichungen für
a = -0.5
in den folgenden Gleichungen:a
ist normalerweise so eingestellt, -0.5, oder -0.75. Beachten Sie, dassa = -0.5
entspricht der Kubische Hermite-spline, die ständig und haben ein kontinuierliches ersten derivitive. OpenCV scheint zu verwenden -0.75.Jedoch, wenn Sie edit [OPENCV_SRC]\modules\imgproc\src\imgwarp.cpp und ändern Sie den code :
zu:
und Wiederaufbau OpenCV (Tipp: deaktivieren Sie CUDA und gpu-Modul für kurze compile-Zeit), dann erhalten Sie die gleichen Ergebnisse. Finden Sie die passende Ausgabe in meine andere Antwort auf eine ähnliche Frage vom OP.
Dies ist eine Art von follow-up auf Ihre Vorherige Fragen über den Unterschied zwischen
imresize
in MATLAB undcv::resize
in OpenCV gegeben eine bikubische interpolation.War ich interessiert, mich heraus zu finden, warum es einen Unterschied. Dies sind meine Erkenntnisse (wie ich verstanden habe die algorithmen, bitte korrigieren Sie mich, wenn ich keine Fehler machen).
Denken, zum ändern der Größe eines Bilds als eine planare transformation von ein Eingabebild der Größe
M-by-N
zu einem ausgabebild der GrößescaledM-by-scaledN
.Das problem ist, dass die Punkte nicht unbedingt passen auf das diskrete Gitter, daher erhalten Intensitäten der Pixel im ausgabebild, müssen wir interpolieren die Werte von einigen der benachbarten Proben (in der Regel erfolgt in umgekehrter Reihenfolge, das heißt für jeden pixel-Ausgabe, finden wir den entsprechenden nicht-ganzzahlige Punkt in der input-Raum und interpolieren um ihn herum).
Dies ist, wo Interpolations-algorithmen unterscheiden sich durch die Wahl der Größe der Nachbarschaft und die Gewichts-Koeffizienten geben zu jedem Punkt in dieser Gegend. Die Beziehung kann Erster oder höherer Ordnung (wobei die variable beteiligt ist der Abstand von der inverse-Mapping-non-integer Beispiel auf der diskreten Punkte auf der original-Bild-raster). In der Regel weisen Sie höhere GEWICHTE, um näher Punkte.
Blick auf
imresize
in MATLAB, hier sind die GEWICHTE von Funktionen für die lineare und kubische Kernel:(Diese im Grunde die Rückkehr der interpolation Gewicht einer Probe auf der Grundlage, wie weit es ist, von einem interpolierten Punkt).
Dies ist, wie diese Funktionen Aussehen:
Beachten Sie, dass der linear-kernel (stückweise lineare Funktionen auf [-1,0] und [0,1] Intervalle, und Nullen an anderer Stelle) arbeitet auf der 2-benachbarten Punkte, während die kubische kernel (stückweise kubische Funktionen auf die Intervalle [-2,-1], [-1,1], und [1,2], Nullen und anderswo) funktioniert auf 4 benachbarte Punkte.
Hier ist eine illustration für den 1-dimensionalen Fall, der zeigt, wie man interpoliert den Wert
x
aus den diskreten Punktef(x_k)
mit Hilfe einer kubischen kernel:Die kernel-Funktion
h(x)
ist ausgerichtet aufx
die Lage der Punkt interpoliert werden. Der interpolierte Wertf(x)
ist die gewichtete Summe der benachbarten diskreten Punkten (2 Links und 2 rechts), skaliert durch den Wert der interpolation der Funktion an diesen diskreten Punkten.Sagen, wenn der Abstand zwischen
x
und der nächste Punkt istd
(0 <= d < 1
), der interpolierte Wert an der Stellex
werden:wo die Reihenfolge der Punkte ist wie folgt (beachten Sie, dass
x(k+1)-x(k) = 1
):Nun, da die Punkte diskret sind und die Stichprobe in gleichmäßigen Abständen, und die kernel-weite ist in der Regel klein ist, wird die interpolation kann formuliert werden, die kurz und prägnant als convolution Betrieb:
Das Konzept erstreckt sich auf 2 Dimensionen einfach, indem Sie zuerst die Interpolation entlang einer dimension, und dann die Interpolation auf der anderen dimension mit den Ergebnissen der vorherigen Schritt.
Hier ist ein Beispiel für die Bilineare interpolation, die in der 2D-Ansicht 4 benachbarten Punkte:
Wird die bikubische interpolation in 2D verwendet 16 benachbarte Punkte:
Zuerst haben wir interpolieren entlang der Zeilen (die roten Punkte) mit dem 16 grid-Muster (pink). Dann haben wir interpolieren entlang der anderen dimension (rote Linie) mit den interpolierten Punkte aus dem vorherigen Schritt. In jedem Schritt, ist eine regelmäßige 1D-interpolation durchgeführt wird. In diese Gleichungen sind zu lang und kompliziert für mich zu arbeiten von hand!
Nun, wenn wir gehen zurück zu den
cubic
Funktion in MATLAB, es tatsächlich entspricht die definition des convolution-Kernels gezeigt, in der Referenz-Papier wie Gleichung (4). Hier ist die gleiche Sache genommen von Wikipedia:Können Sie sehen, dass in der obigen definition, MATLAB wählte einen Wert von
a=-0.5
.Nun der Unterschied zwischen der Implementierung in MATLAB und OpenCV ist, dass OpenCV wählte einen Wert von
a=-0.75
.Dies ist vielleicht nicht sofort klar, aber den code nicht berechnen, die Begriffe der cubic-convolution-Funktion (aufgelistet nach rechts nach Gleichung (25) in der Papier -):
Können wir sicherstellen, dass mit Hilfe der Symbolic Math Toolbox:
Diese Ausdrücke können wie folgt umgeschrieben werden:
die den Begriffen entsprechen, die aus der obigen Gleichung.
Offensichtlich der Unterschied zwischen MATLAB und OpenCV läuft darauf hinaus, mit einem anderen Wert für die freie Sicht
a
. Nach Ansicht der Autoren des Papiers, ein Wert von0.5
ist die bevorzugte Wahl, da es impliziert, dass bessere Eigenschaften für die approximation-Fehler als jede andere Wahl füra
.a
schwer ist der code in beiden Implementierungen. Wenn wir wollen, dass Sie übereinstimmen, In MATLAB würden Sie ändern müssen, um den built-inimresize
- Funktion (die ich noch nie gerne zu tun), und in OpenCV würden Sie kompilieren das ganze aus Quellen, die nur für das werfen einer tine Wert! Es würde interessant sein zu sehen, wenn die OP nicht änderna
in OpenCV zu-0.5
und stellt sicher, dass wir erhalten identische Ergebnisse zwischen den beiden Implementierungen.. Letztes mal habe ich es versucht, ich erinnere mich, es unter 10 Minuten kompiliert OpenCV von Grund auf.a = -0.5f
gibt identische Ergebnisse zu MATLAB. Ich aktualisierte meine Antwort, um auf Ihre andere Frage, aber ich werde noch ein bisschen auf meine Antwort auch hier. Das kompilieren dauerte etwa 6 Minuten auf meinem i7 laptop mit einer normalen HDD, btw. 🙂 Einfach deaktivieren, CUDA!