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.
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.
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
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