[PYTHON] Ich habe mir eine Möglichkeit ausgedacht, aus einem Foto ein 3D-Modell zu erstellen. 0 Projektion in den 3D-Raum

Domo ist Ksuke. Im Jahr 03, das eine Methode zum Erstellen eines 3D-Modells aus einem Foto entwickelte, werden wir es in einen dreidimensionalen Raum projizieren. Klicken Sie hier für Teil 2 https://qiita.com/Ksuke/items/8a3a2faa90263b439f8b

* Achtung * </ b> Dieser Artikel gibt nur das Ende dessen an, was ich mir ausgedacht und versucht habe, sodass es zu abruptem Material oder schlechtem Ende kommen kann.

Versuchen

Vorgehensweise </ b>

  1. Erweitern Sie das Bild (2D-Daten) auf 3D-Daten
  2. Ausrichtung anpassen
  3. Überlagerung

Der Code hier und da ist der letzte.

1. Erweitern Sie das Bild (2D-Daten) auf 3D-Daten

Das Bild wird im 3D-Raum projiziert, da es sich um 2D-Daten handelt. Der Begriff Projektion wird verwendet, weil er die Objekte im Bild beleuchtet und die Werte festlegt, um die Schatten zu extrahieren, die dem Licht nicht ausgesetzt sind. Das Bild ist wie das Überlagern von 100 Bildern in einem Raum. Auf diese Weise ・ Ein Raum, der von vorne gesehen der Silhouette des Objekts entspricht ・ Ein Raum, der der Silhouette des Objekts bei Betrachtung von der Seite von vorne entspricht ・ Ein Raum, der von vorne gesehen der Silhouette des Objekts entspricht Abgeschlossen.

Auf 3D-Daten erweitern



#Ein zweidimensionales Bild wird gestreckt und in dreidimensionale Richtung projiziert.
def imgProject(img,imgSize):
    
    #Durch wiederholtes Anordnen des Bildes in Richtung der Z-Achse wird das Bild zur Projektion verdickt und gedehnt.
    projectSpace = np.tile(img[:,:,None],(1,1,imgSize))
    
    #Gibt den projizierten Raum zurück
    return projectSpace


#Projizieren Sie das vom Hintergrund getrennte Bild als Punktgruppenobjekt in einen dreidimensionalen Raum(Verfolgen Sie weiter!)
imgProjectSpaces = [imgProject(sepBackImg,imgSize) for sepBackImg in sepBackImgs]

2. Ausrichtung anpassen

Ich habe das Bild in einen dreidimensionalen Raum projiziert, aber die Ausrichtung der Objekte in jedem Raum ist unterschiedlich. Die Vorderseite des Objekts sollte sich vor dem Raum befinden, der aus dem von vorne aufgenommenen Bild des Objekts erstellt wurde, und die Seite des Objekts sollte sich vor dem Raum befinden, der aus dem von der Seite aufgenommenen Bild des Objekts erstellt wurde. .. Hier werden zum Ausrichten der Ausrichtung die Achsen ausgetauscht. Stellen Sie sicher, dass sich die Vorderseite des Objekts in allen Räumen vor dem Raum befindet. Auf diese Weise ・ Ein Raum, der von vorne gesehen der Silhouette des Objekts entspricht ・ Ein Raum, der von der Seite gesehen der Silhouette des Objekts entspricht ・ Ein Raum, der von oben gesehen der Silhouette des Objekts entspricht Abgeschlossen.

Orientierungsanpassung



#Die Oberfläche, die gemäß dem Originalbild zur Vorderseite des Raums kommt, unterscheidet sich von der Vorderseite, der Seite und der Oberseite der Tasse.
#Richten Sie die Achsen so aus, dass die Vorderseite des Bechers in allen Räumen vor Ihnen liegt.
transposeValues = [(0,1,2),(0,2,1),(2,1,0)]
transposedSpaces = [imgProjectSpace.transpose(*transposeValue) for imgProjectSpace,transposeValue in zip(imgProjectSpaces,transposeValues)]

3. Überlagerung

Wenn die Ausrichtungen jedes Raums übereinstimmen, überlappen sich alle Räume. Durch Stapeln wird ein Raum erstellt, der der Silhouette des Objekts entspricht, wenn er von vorne, von der Seite oder von oben betrachtet wird.

Überlagerung



#Erstellen Sie durch Überlagern der Punktgruppen in jedem Bereich eine Punktgruppe, die von vorne, von der Seite oder von der Oberseite aus gesehen dieselbe Silhouette wie das Foto aufweist.
imgProjectSpace = transposedSpaces[0]
for transposedSpace in transposedSpaces[1:]:
    imgProjectSpace = imgProjectSpace*transposedSpace

Funktionsprüfung

Überprüfen Sie abschließend, ob der Code ordnungsgemäß funktioniert.

Bestätigung der Erweiterung auf 1,3-dimensionale Daten

Führen Sie den folgenden Code im Mixer aus

Für dynamische 1



#Erstellen Sie eine Liste mit Koordinaten der Position der Punktgruppe aus dem gerade projizierten Raum
imgCoords = [binary2coords(imgProjectSpace) for imgProjectSpace in imgProjectSpaces]

#Verschieben Sie die Breite der Scheitelpunkte jedes Bildes
offsets = [[-50,-150,-50],[-50,-50,-50],[-50,50,-50]]

#Name beim Registrieren der Eckpunkte jedes Bildes als Objekt
names = ['frontSpace','sideSpace','topSpace']

#Scheitelpunkte zeichnen
[addObj(coords=imgCoord,name = name,offset=offset) for imgCoord,name,offset in zip(imgCoords,names,offsets)]
    

Wenn ein Objekt wie dieses (eine Gruppe benannter Punkte) angezeigt wird, ist es erfolgreich. キャプチャ.PNG

2. Bestätigung der Orientierungseinstellung

Führen Sie den folgenden Code im Mixer aus

Zur dynamischen Bestätigung 2



#Erstellen Sie eine Liste mit Koordinaten der Position der Punktgruppe aus dem Bereich, in dem die Achse angepasst wird
imgCoords = [binary2coords(transposedSpace) for transposedSpace in transposedSpaces]

#Verschieben Sie die Breite der Scheitelpunkte jedes Bildes
offsets = [[-150,-150,-50],[-150,-50,-50],[-150,50,-50]]

#Name beim Registrieren der Eckpunkte jedes Bildes als Objekt
names = ['frontTransposedSpace','sideTransposedSpace','topTransposedSpace']

#Scheitelpunkte zeichnen
[addObj(coords=imgCoord,name = name,offset=offset) for imgCoord,name,offset in zip(imgCoords,names,offsets)]

Wenn ein Objekt wie dieses (eine Gruppe benannter Punkte) angezeigt wird, ist es erfolgreich. キャプチャ.PNG

3. Bestätigung der Überlagerung

Führen Sie den folgenden Code im Mixer aus

Für dynamische 3


addObj(coords=binary2coords(imgProjectSpace),name = "objectSpace",offset=[-250,-50,-50])

Wenn ein Objekt wie dieses (eine Gruppe benannter Punkte) angezeigt wird, ist es erfolgreich. キャプチャ.PNG

Übrigens, wenn Sie die obigen drei zur Bestätigung gleichzeitig ausführen, sieht es so aus キャプチャ.PNG

Nächster?

Nachdem wir nun endlich eine dreidimensionale Anzeige des Objekts in der Punktgruppe erstellt haben, möchte ich aus der Punktgruppe Polygone und deren Eckpunkte generieren.

Nachtrag 2020/9/18 Teil 4 wurde veröffentlicht. https://qiita.com/Ksuke/items/144c06f128b015b001dd

Codeübersicht

Wenn Sie es nach dem vorherigen Code hinzufügen, sollte es funktionieren.

Funktionsausgabe

Codeübersicht(Funktionsausgabe)



#Ein zweidimensionales Bild wird gestreckt und in dreidimensionale Richtung projiziert.
def imgProject(img,imgSize):
    
    #Durch wiederholtes Anordnen des Bildes in Richtung der Z-Achse wird das Bild zur Projektion verdickt und gedehnt.
    projectSpace = np.tile(img[:,:,None],(1,1,imgSize))
    
    #Gibt den projizierten Raum zurück
    return projectSpace

Ausführungscode

Codeübersicht(Ausführungscode)



#Projizieren Sie das vom Hintergrund getrennte Bild als Punktgruppenobjekt in einen dreidimensionalen Raum(Verfolgen Sie weiter!)
imgProjectSpaces = [imgProject(sepBackImg,imgSize) for sepBackImg in sepBackImgs]

#Die Oberfläche, die gemäß dem Originalbild zur Vorderseite des Raums kommt, unterscheidet sich von der Vorderseite, der Seite und der Oberseite der Tasse.
#Richten Sie die Achsen so aus, dass die Vorderseite des Bechers in allen Räumen nach vorne kommt.
transposeValues = [(0,1,2),(0,2,1),(2,1,0)]
transposedSpaces = [imgProjectSpace.transpose(*transposeValue) for imgProjectSpace,transposeValue in zip(imgProjectSpaces,transposeValues)]

#Erstellen Sie durch Überlagern der Punktgruppen in jedem Bereich eine Punktgruppe, die von vorne, von der Seite oder von der Oberseite aus gesehen dieselbe Silhouette wie das Foto aufweist.
imgProjectSpace = transposedSpaces[0]
for transposedSpace in transposedSpaces[1:]:
    imgProjectSpace = imgProjectSpace*transposedSpace

print("step03:projection of image in 3D space is success\n")


#Zur Bestätigung unten anzeigen(Es hat nichts mit dem Hauptfluss zu tun, daher wird es wahrscheinlich in der nächsten Runde verschwinden)

#Erstellen Sie eine Liste mit Koordinaten der Position der Punktgruppe aus dem gerade projizierten Raum
imgCoords = [binary2coords(imgProjectSpace) for imgProjectSpace in imgProjectSpaces]

#Verschieben Sie die Breite der Scheitelpunkte jedes Bildes
offsets = [[-50,-150,-50],[-50,-50,-50],[-50,50,-50]]

#Name beim Registrieren der Eckpunkte jedes Bildes als Objekt
names = ['frontSpace','sideSpace','topSpace']

#Scheitelpunkte zeichnen
[addObj(coords=imgCoord,name = name,offset=offset) for imgCoord,name,offset in zip(imgCoords,names,offsets)]
    

#Erstellen Sie eine Liste mit Koordinaten der Position der Punktgruppe aus dem Bereich, in dem die Achse angepasst wird
imgCoords = [binary2coords(transposedSpace) for transposedSpace in transposedSpaces]

#Verschieben Sie die Breite der Scheitelpunkte jedes Bildes
offsets = [[-150,-150,-50],[-150,-50,-50],[-150,50,-50]]

#Name beim Registrieren der Eckpunkte jedes Bildes als Objekt
names = ['frontTransposedSpace','sideTransposedSpace','topTransposedSpace']

#Scheitelpunkte zeichnen
[addObj(coords=imgCoord,name = name,offset=offset) for imgCoord,name,offset in zip(imgCoords,names,offsets)]
    

addObj(coords=binary2coords(imgProjectSpace),name = "objectSpace",offset=[-250,-50,-50])

Recommended Posts