[PYTHON] J'ai trouvé un moyen de créer un modèle 3D à partir d'une photo.0 Projection vers l'espace 3D

Domo est Ksuke. En 03, qui a proposé une méthode pour créer un modèle 3D à partir d'une photographie, nous allons le projeter dans un espace tridimensionnel. Cliquez ici pour la partie 2 https://qiita.com/Ksuke/items/8a3a2faa90263b439f8b

* Attention * </ b> Cet article ne donne que la fin de ce que j'ai trouvé et essayé, donc ça pourrait finir avec du matériel abrupt ou Bad End.

Essayer

Procédure </ b>

  1. Extension de l'image (données 2D) aux données 3D
  2. Réglage de l'orientation
  3. Superposition

Le code ici et là est le dernier.

1. Extension de l'image (données 2D) aux données 3D

L'image est projetée dans l'espace 3D car il s'agit de données 2D. Le terme projection est utilisé car il éclaire les objets de l'image et définit les valeurs pour extraire les ombres qui ne sont pas exposées à la lumière. L'image est comme superposer 100 images dans un espace. En faisant cela, ・ Un espace qui correspond à la silhouette de l'objet vu de face ・ Un espace qui correspond à la silhouette de l'objet vu de côté lorsqu'il est vu de face ・ Un espace qui correspond à la silhouette de l'objet vu de face Est terminé.

Extension aux données 3D



#Une image bidimensionnelle est étirée et projetée dans la direction tridimensionnelle.
def imgProject(img,imgSize):
    
    #En disposant de manière répétée l'image dans la direction de l'axe z, l'image est épaissie et étirée pour la projection.
    projectSpace = np.tile(img[:,:,None],(1,1,imgSize))
    
    #Renvoie l'espace projeté
    return projectSpace


#Projeter l'image séparée par l'arrière-plan dans un espace tridimensionnel en tant qu'objet de groupe de points(Tracez!)
imgProjectSpaces = [imgProject(sepBackImg,imgSize) for sepBackImg in sepBackImgs]

2. Réglage de l'orientation

J'ai projeté l'image dans un espace tridimensionnel, mais l'orientation des objets dans chaque espace est différente. L'avant de l'objet doit être en face de l'espace créé à partir de l'image de l'objet prise de face, et le côté de l'objet doit être devant l'espace créé à partir de l'image de l'objet prise de côté. .. Ici, pour aligner l'orientation, les axes sont remplacés. Assurez-vous que l'avant de l'objet est devant l'espace dans tous les espaces. En faisant cela ・ Un espace qui correspond à la silhouette de l'objet vu de face ・ Un espace qui correspond à la silhouette de l'objet vu de côté ・ Un espace qui correspond à la silhouette de l'objet vu d'en haut Est terminé.

Réglage de l'orientation



#La surface qui vient à l'avant de l'espace selon l'image originale est différente de l'avant, du côté et du haut de la tasse.
#Alignez les axes de manière à ce que l'avant de la tasse soit devant vous dans tous les espaces.
transposeValues = [(0,1,2),(0,2,1),(2,1,0)]
transposedSpaces = [imgProjectSpace.transpose(*transposeValue) for imgProjectSpace,transposeValue in zip(imgProjectSpaces,transposeValues)]

3. Superposition

Lorsque les orientations de chaque espace correspondent, tous les espaces se chevauchent. En empilant, un espace qui correspond à la silhouette de l'objet est créé lorsqu'il est vu de face, de côté ou au-dessus.

Recouvrir



#En superposant les points dans chaque espace, créez des points qui ressemblent à la même silhouette que la photo lorsqu'ils sont vus depuis la surface avant, latérale ou supérieure.
imgProjectSpace = transposedSpaces[0]
for transposedSpace in transposedSpaces[1:]:
    imgProjectSpace = imgProjectSpace*transposedSpace

Contrôle de fonctionnement

Enfin, vérifiez si le code fonctionne correctement.

Confirmation de l'extension aux données 1,3 dimensions

Exécutez le code ci-dessous dans blender

Pour dynamique 1



#Créer une liste de coordonnées de la position du groupe de points à partir de l'espace qui vient d'être projeté
imgCoords = [binary2coords(imgProjectSpace) for imgProjectSpace in imgProjectSpaces]

#Décaler la largeur des sommets de chaque image
offsets = [[-50,-150,-50],[-50,-50,-50],[-50,50,-50]]

#Nom lors de l'enregistrement des sommets de chaque image en tant qu'objet
names = ['frontSpace','sideSpace','topSpace']

#Dessiner des sommets
[addObj(coords=imgCoord,name = name,offset=offset) for imgCoord,name,offset in zip(imgCoords,names,offsets)]
    

Si un objet comme celui-ci (un groupe de points nommé) est affiché, il réussit. キャプチャ.PNG

2. Confirmation du réglage de l'orientation

Exécutez le code ci-dessous dans blender

Pour confirmation dynamique 2



#Créer une liste de coordonnées de la position du groupe de points à partir de l'espace où l'axe est ajusté
imgCoords = [binary2coords(transposedSpace) for transposedSpace in transposedSpaces]

#Décaler la largeur des sommets de chaque image
offsets = [[-150,-150,-50],[-150,-50,-50],[-150,50,-50]]

#Nom lors de l'enregistrement des sommets de chaque image en tant qu'objet
names = ['frontTransposedSpace','sideTransposedSpace','topTransposedSpace']

#Dessiner des sommets
[addObj(coords=imgCoord,name = name,offset=offset) for imgCoord,name,offset in zip(imgCoords,names,offsets)]

Si un objet comme celui-ci (un groupe de points nommé) est affiché, il réussit. キャプチャ.PNG

3. Confirmation de la superposition

Exécutez le code ci-dessous dans blender

Pour dynamique 3


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

Si un objet comme celui-ci (un groupe de points nommé) est affiché, il réussit. キャプチャ.PNG

À propos, si vous exécutez les trois ci-dessus pour confirmation en même temps, cela ressemble à ceci キャプチャ.PNG

prochain?

Maintenant que nous avons enfin créé un affichage tridimensionnel des objets dans des groupes de points, nous aimerions générer des polygones et leurs sommets à partir des groupes de points.

PostScript 2020/9/18 La partie 4 a été publiée. https://qiita.com/Ksuke/items/144c06f128b015b001dd

Résumé du code

Si vous l'ajoutez après le code précédent, cela devrait fonctionner.

Edition de fonction

Résumé du code(Edition de fonction)



#Une image bidimensionnelle est étirée et projetée dans la direction tridimensionnelle.
def imgProject(img,imgSize):
    
    #En disposant de manière répétée l'image dans la direction de l'axe z, l'image est épaissie et étirée pour la projection.
    projectSpace = np.tile(img[:,:,None],(1,1,imgSize))
    
    #Renvoie l'espace projeté
    return projectSpace

Code d'exécution

Résumé du code(Code d'exécution)



#Projeter l'image séparée par l'arrière-plan dans un espace tridimensionnel en tant qu'objet de groupe de points(Tracez!)
imgProjectSpaces = [imgProject(sepBackImg,imgSize) for sepBackImg in sepBackImgs]

#La surface qui vient à l'avant de l'espace selon l'image originale est différente de l'avant, du côté et du haut de la tasse.
#Alignez les axes de manière à ce que l'avant de la tasse vienne à l'avant dans tous les espaces.
transposeValues = [(0,1,2),(0,2,1),(2,1,0)]
transposedSpaces = [imgProjectSpace.transpose(*transposeValue) for imgProjectSpace,transposeValue in zip(imgProjectSpaces,transposeValues)]

#En superposant les points dans chaque espace, créez des points qui ressemblent à la même silhouette que la photo lorsqu'ils sont vus depuis la surface avant, latérale ou supérieure.
imgProjectSpace = transposedSpaces[0]
for transposedSpace in transposedSpaces[1:]:
    imgProjectSpace = imgProjectSpace*transposedSpace

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


#Pour l'affichage de confirmation ci-dessous(Cela n'a rien à voir avec le flux principal, donc il disparaîtra probablement au prochain tour)

#Créer une liste de coordonnées de la position du groupe de points à partir de l'espace qui vient d'être projeté
imgCoords = [binary2coords(imgProjectSpace) for imgProjectSpace in imgProjectSpaces]

#Décaler la largeur des sommets de chaque image
offsets = [[-50,-150,-50],[-50,-50,-50],[-50,50,-50]]

#Nom lors de l'enregistrement des sommets de chaque image en tant qu'objet
names = ['frontSpace','sideSpace','topSpace']

#Dessiner des sommets
[addObj(coords=imgCoord,name = name,offset=offset) for imgCoord,name,offset in zip(imgCoords,names,offsets)]
    

#Créer une liste de coordonnées de la position du groupe de points à partir de l'espace où l'axe est ajusté
imgCoords = [binary2coords(transposedSpace) for transposedSpace in transposedSpaces]

#Décaler la largeur des sommets de chaque image
offsets = [[-150,-150,-50],[-150,-50,-50],[-150,50,-50]]

#Nom lors de l'enregistrement des sommets de chaque image en tant qu'objet
names = ['frontTransposedSpace','sideTransposedSpace','topTransposedSpace']

#Dessiner des sommets
[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