Lass uns mit PatchMatch spielen.
Eine grobe Übersicht über PatchMatch ist Finde Ähnlichkeiten in einem Bild und einem anderen! Es ist ein Algorithmus namens.
In Photoshop werden bestimmte Teile aus einem Bild gelöscht.
Die Idee der Basis ist wie folgt.
1. 1. Stellen Sie die Entsprechung zwischen allen Pixeln des Hauptbilds und des Zielbilds zufällig ein.
Letztendlich wird dieses Korrespondenzpaar ein Paar ähnlicher Pixel sein.
2. Basierend auf der Idee, dass benachbarte Pixel wahrscheinlich Teile desselben Teils sind
Vergleichen Sie die aktuelle Ähnlichkeit mit der Ähnlichkeit benachbarter Pixel.
Wenn es größer ist (höhere Ähnlichkeit) als die aktuell eingestellte Ähnlichkeit, wird es auf diesen Wert aktualisiert.
3. 3. Wiederholen Sie unten
PatchMatch wird manchmal wie Template Matching verwendet. Außerdem basiert auf der gemeinsamen Idee, dass benachbarte Teile gleich sein werden Die gleiche Seite ist die gleiche Tiefe! Unter diesem Gesichtspunkt wird Colmap verwendet, um die Tiefe abzuschätzen. Es ist eine Theorie, die allgemein anwendbar zu sein scheint.
Der wichtige Punkt in diesem Artikel ist Wenn Sie PatchMatch verwenden, können Sie ähnliche Teile in zwei Bildern sehen. Dies bedeutet, dass es auf Pixelebene beurteilt werden kann.
Da der Feature-Point-Abgleich ein Prozess mit Feature-Punkten ist, Es wird leicht von der Umgebung beeinflusst, und wenn die Anzahl der Feature-Punkte gering ist, schlägt die Verarbeitung fehl.
Mit PatchMatch können Sie die Anzahl der Übereinstimmungen erhöhen, oder? Lassen Sie uns in diesem Sinne mit der folgenden Verarbeitung spielen.
1. Führen Sie Patch Match mit 2 Bildern aus. Berechnen Sie mit SAD einen Satz von Pixeln, die allen Pixeln ähnlich sind
2. Führen Sie Ransac für die beiden übereinstimmenden Paare aus. Ausreißer entfernen.
Mal sehen, wie genau und in vielen Fällen PatchMatch abgeglichen werden kann. Als nächstes werde ich versuchen, Punkte mithilfe des RGBD-Bildes und der Informationen zu internen Parametern zu gruppieren und auszurichten. Wenn Sie gut zusammenpassen können, Möglicherweise können Sie sich gut ausrichten, ohne von Rauschen betroffen zu sein.
3. 3. Punktgruppierung aus einem Satz extrahierter Pixel
4. Richten Sie die extrahierten Punkte aus
Richten Sie sich mit dem Parameter 5.4 an der Hauptpunktgruppe aus
https://github.com/MingtaoGuo/PatchMatch
Der obige Code wird für den Kernverarbeitungsteil ausgeliehen. Wenn Sie es so verwenden, wie es ist, wird Marias Gesicht zu einem Avatar Ändern Sie diese Option, um nur das Ausführungsergebnis von PatchMatch zu verwenden.
reconstruction.py
def reconstruction(f, A, B,AdepthPath="",BdepthPath=""):
A_h = np.size(A, 0)
A_w = np.size(A, 1)
temp = np.zeros_like(A)
srcA=[]
dstB=[]
colorA=np.zeros_like(A)
colorB=np.zeros_like(A)
for i in range(A_h):
for j in range(A_w):
colorA[i, j, :] = A[[i],[j],:]
colorB[i, j, :] = B[f[i, j][0], f[i, j][1], :]
temp[i, j, :] = B[f[i, j][0], f[i, j][1], :]
srcA.append([i,j])
dstB.append([f[i, j][0], f[i, j][1]])
#Wenden Sie als Nächstes die ähnlichen Pixel an, die durch Patch Match erhalten wurden.
#Ein Bild, das Bild A unter Verwendung der Pixel von Bild B rekonstruiert
cv2.imwrite('colorB.jpg', colorB)
cv2.imwrite('colorA.jpg', colorA)
src=np.array(srcA)
dst=np.array(dstB)
print(src.shape)
print(dst.shape)
srcA_pts = src.reshape(-1, 1, 2)
dstB_pts = dst.reshape(-1, 1, 2)
# RANSAC
print(srcA_pts.shape)
print(dstB_pts.shape)
M, mask = cv2.findHomography(srcA_pts, dstB_pts, cv2.RANSAC, 5.0)
matchesMask = mask.ravel().tolist()
im_h = cv2.hconcat([A,B])
cv2.imwrite('outputMerge.jpg', im_h)
outputA = np.zeros_like(A)
outputB = np.zeros_like(A)
for i in range(srcA_pts.shape[0]):
if mask[i] == 0: continue
srcIm = [srcA_pts[i][0][0],srcA_pts[i][0][1]]
dstIm = [dstB_pts[i][0][0],dstB_pts[i][0][1]]
outputA[srcIm[0],srcIm[1],:]=A[srcIm[0],srcIm[1],:]
outputB[dstIm[0],dstIm[1],:]=B[dstIm[0],dstIm[1],:]
im_h = cv2.hconcat([outputA, outputB])
cv2.imwrite('outputMatch.jpg', im_h)D
im_h = cv2.hconcat([A, B])
for i in range(srcA_pts.shape[0]):
if mask[i] == 0: continue
srcIm = [srcA_pts[i][0][0],srcA_pts[i][0][1]]
dstIm = [dstB_pts[i][0][0],dstB_pts[i][0][1]]
cv2.line(im_h, (srcIm[0], srcIm[1]),
(dstIm[0]+int(1280 * 0.3), dstIm[1]),
(0, 255, 0), thickness=1, lineType=cv2.LINE_4)
cv2.imwrite('outputMatchAddLine.jpg', im_h)
if AdepthPath!="":
#Wenn Bildtiefen-Daten / interne Parameter vorhanden sind,
#Versuchen Sie, Punkte zu gruppieren und mit übereinstimmenden Informationen auszurichten.
#Nur PatchMatch A Die folgende Verarbeitung ist nicht erforderlich
import open3d as o3d
def CPD_rejister(source, target):
from probreg import cpd
import copy
type = 'rigid'
tf_param, _, _ = cpd.registration_cpd(source, target, type)
result = copy.deepcopy(source)
result.points = tf_param.transform(result.points)
return result, tf_param.rot, tf_param.t, tf_param.scale
def Register(pclMVS_Main, pclMVS_Target):
# CPD : step1 Run CPD for SfM Data
result, rot, t, scale = CPD_rejister(pclMVS_Target, pclMVS_Main)
# CPD : step2 Apply CPD result for MVS Data
lastRow = np.array([[0, 0, 0, 1]])
ret_R = np.array(rot)
ret_t = np.array([t])
ret_R = scale * ret_R
transformation = np.concatenate((ret_R, ret_t.T), axis=1)
transformation = np.concatenate((transformation, lastRow), axis=0)
return transformation, rot, t, scale
def getPLYfromNumpy_RGB(nplist, colorList):
# nplist = np.array(nplist)
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(nplist)
pcd.colors = o3d.utility.Vector3dVector(colorList)
return pcd
def numpy2Dto1D(arr):
if type(np.array([])) != type(arr):
arr = np.array(arr)
if arr.shape == (3, 1):
return np.array([arr[0][0], arr[1][0], arr[2][0]])
if arr.shape == (2, 1):
return np.array([arr[0][0], arr[1][0]])
else:
assert False, "numpy2Dto1D:Nicht kompatibel"
def TransformPointI2C(pixel2D, K):
X = float(float(pixel2D[0] - K[0][2]) * pixel2D[2] / K[0][0])
Y = float(float(pixel2D[1] - K[1][2]) * pixel2D[2] / K[1][1])
Z = pixel2D[2]
CameraPos3D = np.array([[X], [Y], [Z]])
return CameraPos3D
def getDepthCSPerView(path):
import csv
#Tiefendatenerfassung
in_csvPath = path
with open(in_csvPath) as f:
reader = csv.reader(f)
csvlist = [row for row in reader]
return csvlist
#Tiefendaten(CSV)
Adepthlist = getDepthCSPerView(AdepthPath)
Bdepthlist = getDepthCSPerView(BdepthPath)
pclA=[]
pclB=[]
colorA=[]
colorB=[]
ALLpclA=[]
ALLpclB=[]
ALLcolorA=[]
ALLcolorB=[]
#Der Tiefenwert ist 1.Stellen Sie die Reichweite von 5 m zur Punktgruppe wieder her
depth_threshold = 1.5 #Meter
depth_scale = 0.0002500000118743628
threshold = depth_threshold / depth_scale
#Interne Parameter der RGB-Kamera
# width: 1280, height: 720, ppx: 648.721, ppy: 365.417, fx: 918.783, fy: 919.136,
retK = np.array([[918.783, 0, 648.721],
[0, 919.136, 365.417],
[0, 0, 1]])
cnt = 0
for y in range(len(Adepthlist)):
for x in range(len(Adepthlist[0])):
ADepth = float(Adepthlist[y][x])
BDepth = float(Bdepthlist[y][x])
if (ADepth == 0 or ADepth > threshold) or (BDepth == 0 or BDepth > threshold):
continue
AXYZ = TransformPointI2C([x,y, ADepth], retK)
BXYZ = TransformPointI2C([x,y, BDepth], retK)
ALLpclA.append(numpy2Dto1D(AXYZ))
ALLpclB.append(numpy2Dto1D(BXYZ))
color = A[int(srcIm[0])][int(srcIm[1])]
ALLcolorA.append([float(color[0] / 255), float(color[1] / 255), float(color[2] / 255)])
color = B[int(dstIm[0])][int(dstIm[1])]
ALLcolorB.append([float(color[0] / 255), float(color[1] / 255), float(color[2] / 255)])
ALLpclA = getPLYfromNumpy_RGB(ALLpclA,ALLcolorA)
ALLpclB = getPLYfromNumpy_RGB(ALLpclB,ALLcolorB)
o3d.io.write_point_cloud("ALL_pclA_Before.ply", ALLpclA)
o3d.io.write_point_cloud("ALL_pclB_Before.ply", ALLpclB)
for i in range(srcA_pts.shape[0]):
if mask[i] == 0: continue
srcIm = [srcA_pts[i][0][0], srcA_pts[i][0][1]]
dstIm = [dstB_pts[i][0][0], dstB_pts[i][0][1]]
ADepth = float(Adepthlist[int(srcIm[0])][int(srcIm[1])])
BDepth = float(Bdepthlist[int(dstIm[0])][int(dstIm[1])])
if (ADepth == 0 or ADepth > threshold) or (BDepth == 0 or BDepth > threshold):
continue
AXYZ = TransformPointI2C([int(srcIm[1]), int(srcIm[0]), ADepth], retK)
BXYZ = TransformPointI2C([int(dstIm[1]), int(dstIm[0]), BDepth], retK)
pclA.append(numpy2Dto1D(AXYZ))
pclB.append(numpy2Dto1D(BXYZ))
color = A[int(srcIm[0])][int(srcIm[1])]
colorA.append([float(color[0] / 255), float(color[1] / 255), float(color[2] / 255)])
color = B[int(dstIm[0])][int(dstIm[1])]
colorB.append([float(color[0] / 255), float(color[1] / 255), float(color[2] / 255)])
pclA = getPLYfromNumpy_RGB(pclA,colorA)
pclB = getPLYfromNumpy_RGB(pclB,colorB)
o3d.io.write_point_cloud("pclA_Before.ply", pclA)
o3d.io.write_point_cloud("pclB_Before.ply", pclB)
trans, rot, t, scale = Register(pclA, pclB)
pclB.transform(trans)
o3d.io.write_point_cloud("pclA_After.ply", pclA)
o3d.io.write_point_cloud("pclB_After.ply", pclB)
ALLpclB.transform(trans)
o3d.io.write_point_cloud("ALL_pclA_After.ply", ALLpclA)
o3d.io.write_point_cloud("ALL_pclB_After.ply", ALLpclB)
Ich werde es versuchen.
Das ist
so was. Ich verstehe nicht wirklich. Extrahiert und zeigt die übereinstimmenden Pixel an und die Ausreißer wurden durch Ransac entfernt.
Ich weiß nicht mehr als nein. Aber irgendwie scheinen die Formen zu passen. Ich bin der Meinung, dass es zur Verfolgung, Bewegungserkennung usw. verwendet werden kann.
Ich weiß nicht, ob die Antwort mit dem vorherigen Ergebnis übereinstimmt, aber Lassen Sie uns die Punktgruppen der beiden Gesichtspunkte basierend auf den extrahierten Informationen ausrichten.
3. 3. Punktgruppierung aus einem Satz extrahierter Pixel
4. Richten Sie die extrahierten Punkte aus
Richten Sie sich mit dem Parameter 5.4 an der Hauptpunktgruppe aus
Das ist
so was.
Hmm! Es ist subtil! das ist alles.
[Zusatz]
Das vorherige Ergebnis war in der Tiefe nicht genau Mit verschiedenen Daten validiert.
Es ist eine Gruppe von Punkten voller Lärm, Liegt es daran, dass der zweidimensionale Abgleich erfolgreich ist? Ich konnte natürlich gut zusammenpassen.
Ich habe nur Ransac verwendet, um Ausreißer während des Abgleichs zu entfernen. Da ich eine Gruppe von Punkten erstellt habe, werde ich beim nächsten Mal den Abstand der übereinstimmenden Punkte berücksichtigen Versuchen Sie, die Ausreißer zu entfernen.
Recommended Posts