Bilineare Interpolationsfunktion bei nichtlinearer Koordinatenkonvertierung mit Python und Numpy

Zweck

Bei der Koordinatenkonvertierung in der Bildverarbeitung ist es üblich, die Koordinaten des Originalbildes, die dem Index von (i, j) des konvertierten Bildes entsprechen, unter Verwendung der inversen Konvertierung zu erhalten und durch ein Verfahren wie Bilinear zu interpolieren.

In C und C ++ usw. hatte ich keine andere Wahl, als Doppelschleifen zu drehen, aber in Numpy und Python wollte ich nicht so viel wie möglich für Schleifen verwenden, also schrieb ich einen Code, der effizient zu sein scheint [eine Seite auf Github]( Ich habe es unter https://github.com/NitishMutha/equirectangular-toolbox/blob/master/nfov.py gefunden und es für mich selbst geändert.

Es ist unnötig zu erwähnen, dass bei der Affine- oder Projektionskonvertierung die Verwendung der dedizierten OpenCV-Bibliothek schneller ist.

Code-Fluss

1. Suchen Sie die Koordinaten des Originalbilds, auf das sich die Konvertierung bezieht

Erstellen Sie vor der Konvertierung ein Array, das den Koordinatenindex von (i, j) aufzeichnet. Wenn Sie ein Array mit arange erstellen und mit Kachel oder Wiederholung überlagern, können Sie dies in kürzester Zeit tun.

Im folgenden Beispiel wird es vom Bildzentrum cx, cy subtrahiert, normalisiert und dann mit dem Umfangsverhältnis multipliziert, um es in sphärische Polarkoordinaten umzuwandeln, aber es ist dasselbe.

xline = (np.arange(wid)-cx)*2*pi/wid
yline = -(np.arange(hei)-cy)*pi/hei
Xsline = np.tile(xline,hei)
Ysline = yline.repeat(wid,axis=0)

Jetzt müssen Sie nur noch verschiedene nichtlineare Transformationen auf diese Sequenzen anwenden. Einfache Funktionen wie Sinus-Cosinus und Logarithmus werden in Numpy vorbereitet. Wenn Sie sie also unverändert an das Array übergeben, werden sie alle einheitlich verarbeitet und sind viel schneller als das Schreiben einer for-Anweisung.

2. Erhalten Sie das konvertierte Bild basierend auf den erhaltenen Koordinaten durch bilineare Interpolation.

Die Pixelwerte, die den zuvor erhaltenen Koordinaten entsprechen, werden interpoliert und schließlich in die Form des Bildes umgeformt.

Wenn im folgenden Code die Maximal- und Minimalwerte des Pixelindex überschritten werden, wird eine Schleife ausgeführt. Im Allgemeinen ist es jedoch besser, einen Wert wie 0 aufzufüllen.

def _bilinear_interpolation_loop(frame, screen_coord):
    ''' Calculate 
    input: frame and its subpixel coordinate [x,y]
    '''
    frame_height,frame_width,frame_channel =frame.shape
    #uf = np.mod(screen_coord[0],1) * frame_width  # long - width
    #vf = np.mod(screen_coord[1],1) * frame_height  # lat - height

    x0 = np.floor(screen_coord[0]).astype(int)  # coord of pixel to bottom left
    y0 = np.floor(screen_coord[1]).astype(int)
    uf = screen_coord[0]  # long - width
    vf = screen_coord[1]  # lat - height
    x2 = np.add(x0, np.ones(uf.shape).astype(int))  # coords of pixel to top right
    y2 = np.add(y0, np.ones(vf.shape).astype(int))
    
    # Assume Loop 
    x2 = np.where(x2 > frame_width-1, 0, x2)
    y2 = np.where(y2 > frame_height-1, 0, y2)
    
    base_y0 = np.multiply(y0, frame_width)
    base_y2 = np.multiply(y2, frame_width)

    A_idx = np.add(base_y0, x0)
    B_idx = np.add(base_y2, x0)
    C_idx = np.add(base_y0, x2)
    D_idx = np.add(base_y2, x2)

    flat_img = np.reshape(frame, [-1, frame_channel])
    #print(flat_img.shape)
    A = np.take(flat_img, A_idx, axis=0)
    B = np.take(flat_img, B_idx, axis=0)
    C = np.take(flat_img, C_idx, axis=0)
    D = np.take(flat_img, D_idx, axis=0)
    
    wa = np.multiply(x2 - uf, y2 - vf)
    wb = np.multiply(x2 - uf, vf - y0)
    wc = np.multiply(uf - x0, y2 - vf)
    wd = np.multiply(uf - x0, vf - y0)
    #print(wa,wb,wc,wd)
    # interpolate
    AA = np.multiply(A.astype(np.float32), np.array([wa, wa, wa]).T)
    BB = np.multiply(B.astype(np.float32), np.array([wb, wb, wb]).T)
    CC = np.multiply(C.astype(np.float32), np.array([wc, wc, wc]).T)
    DD = np.multiply(D.astype(np.float32), np.array([wd, wd, wd]).T)
    out = np.reshape(np.round(AA + BB + CC + DD).astype(np.uint8), [frame_height, frame_width, 3])
    return out

Ausführungsbeispiel

Im folgenden Blog habe ich ein Bild erstellt, als die All-Sky-Kamera basierend auf dem Bild der zylindrischen Projektion mit normaler Entfernung virtuell gedreht wurde.

https://ossyaritoori.hatenablog.com/entry/2019/12/10/RICOH_THETA_SC%E3%81%A7%E5%A4%9A%E9%87%8D%E9%9C%B2%E5%85%89%E3%83%BB%E5%90%88%E6%88%90%E3%82%92%E3%81%97%E3%81%A6Pixel4%E3%81%BF%E3%81%9F%E3%81%84%E3%81%AB%E3%82%AF%E3%83%AA%E3%82%A2%E3%81%AA

Recommended Posts

Bilineare Interpolationsfunktion bei nichtlinearer Koordinatenkonvertierung mit Python und Numpy
Empfohlene Umgebung und Verwendung bei der Entwicklung mit Python
Längen- und Breitengradkoordinaten ↔ UTM-Koordinatenkonvertierung mit Python
Ich habe Funktionssynthese und Curry mit Python versucht
Ergebnisse bei der Beschleunigung numerischer Berechnungen mit Python und Numba
[Tipps] Differenzberechnung erster Ordnung und inverse Konvertierung [Python / Numpy]
Visualisieren Sie den Bereich der internen und externen Einfügungen mit Python
Probleme beim Erstellen eines CSV-JSON-Konvertierungstools mit Python
Crawlen mit Python und Twitter API 1-Einfache Suchfunktion
Python- und Numpy-Tipps
Verknüpfen Sie Python Enum mit einer Funktion, um es aufrufbar zu machen
Lassen Sie uns ein PRML-Diagramm mit Python, Numpy und matplotlib erstellen.
[Python] Hinweise beim Versuch, Numpy mit Cython zu verwenden
Programmieren mit Python und Tkinter
Ver- und Entschlüsselung mit Python
[Python] Berechnungsmethode mit numpy
SMO mit Python + NumPy implementiert
Nichtlineare Funktionsmodellierung in Python
Fehler beim Spielen mit Python
Python mit Pyenv und Venv
Funktioniert mit Python und R.
Automatische Bildinterpolation mit OpenCV und Python (Fast Marching Method, Navier-Stokes)
Fehler und Lösung bei der Installation von Python3 mit Homebrew auf einem Mac (Catalina 10.15)
Crawlen mit Python und Twitter API 2-Implementierung der Benutzersuchfunktion
[Python] Fehler- und Lösungsnotiz bei Verwendung von venv mit pyenv + anaconda
Umgang mit Fehlern bei der Installation von Python und Pip mit Choco
Lösen mit Ruby, Python und numpy AtCoder ABC054 B Matrixberechnung
[python3] Implementieren Sie die Debug-Protokollausgabefunktion einfach mit Protokollierung und Klicken
"Gauß-Prozess und maschinelles Lernen" Gauß-Prozessregression nur mit Python-Numpy implementiert