Domo is Ksuke. In 03, which came up with a method for creating a 3D model from a photograph, we will project it into a three-dimensional space. Click here for Part 2 https://qiita.com/Ksuke/items/8a3a2faa90263b439f8b
* Caution * </ b> This article only gives the end of what I came up with and tried, so it could end up with abrupt material or Bad End.
Procedure </ b>
The code here and there is the last one.
The image is projected in 3D space as it is in 2D data. The term projection is used because it shines light on the objects in the image and sets the values to extract the shadows that are not exposed to the light. The image is like overlaying 100 images into a space. By doing this, ・ A space that matches the silhouette of an object when viewed from the front ・ A space that matches the silhouette of an object when viewed from the side when viewed from the front ・ A space that matches the silhouette of an object when viewed from above Is completed.
Extend to 3D data
#A two-dimensional image is stretched and projected in the three-dimensional direction.
def imgProject(img,imgSize):
#By repeatedly arranging the image in the z-axis direction, the image is thickened and stretched for projection.
projectSpace = np.tile(img[:,:,None],(1,1,imgSize))
#Returns the projected space
return projectSpace
#Project a background-separated image into a three-dimensional space as a point cloud object(Trace on!)
imgProjectSpaces = [imgProject(sepBackImg,imgSize) for sepBackImg in sepBackImgs]
I projected the image into 3D space, but the orientation of the objects in each space is different. The front of the object should be in front of the space created from the image of the object taken from the front, and the side of the object should be in front of the space created from the image of the object taken from the side. .. Here, the axes are swapped to align the orientation. Make sure that the front of the object is in front of the space in all spaces. By doing this ・ A space that matches the silhouette of an object when viewed from the front ・ A space that matches the silhouette of an object when viewed from the side ・ A space that matches the silhouette of an object when viewed from above Is completed.
Orientation adjustment
#According to the original image, the surface that comes to the front of the space is different from the front, side, and top of the cup.
#Align the axes so that the front of the cup is in front of you in all spaces.
transposeValues = [(0,1,2),(0,2,1),(2,1,0)]
transposedSpaces = [imgProjectSpace.transpose(*transposeValue) for imgProjectSpace,transposeValue in zip(imgProjectSpaces,transposeValues)]
When the orientations of each space are matched, all the spaces are piled up. By stacking, a space that matches the silhouette of the object is created when viewed from the front, side, or above.
Overlay
#By superimposing the point clouds in each space, create a point cloud that looks the same silhouette as the photo when viewed from the front, side, or top surface.
imgProjectSpace = transposedSpaces[0]
for transposedSpace in transposedSpaces[1:]:
imgProjectSpace = imgProjectSpace*transposedSpace
Finally, check if the code works fine.
Run the code below in blender
For dynamic 1
#Create a list of coordinates of the point cloud position from the space just projected
imgCoords = [binary2coords(imgProjectSpace) for imgProjectSpace in imgProjectSpaces]
#Shift width of the vertices of each image
offsets = [[-50,-150,-50],[-50,-50,-50],[-50,50,-50]]
#Name when registering the vertices of each image as an object
names = ['frontSpace','sideSpace','topSpace']
#Draw vertices
[addObj(coords=imgCoord,name = name,offset=offset) for imgCoord,name,offset in zip(imgCoords,names,offsets)]
If an object like this (a point cloud named) is displayed, it is successful.
Run the code below in blender
For dynamic confirmation 2
#Create a list of coordinates of the position of the point cloud from the space where the axes are adjusted.
imgCoords = [binary2coords(transposedSpace) for transposedSpace in transposedSpaces]
#Shift width of the vertices of each image
offsets = [[-150,-150,-50],[-150,-50,-50],[-150,50,-50]]
#Name when registering the vertices of each image as an object
names = ['frontTransposedSpace','sideTransposedSpace','topTransposedSpace']
#Draw vertices
[addObj(coords=imgCoord,name = name,offset=offset) for imgCoord,name,offset in zip(imgCoords,names,offsets)]
If an object like this (a point cloud named) is displayed, it is successful.
Run the code below in blender
For dynamic 3
addObj(coords=binary2coords(imgProjectSpace),name = "objectSpace",offset=[-250,-50,-50])
If an object like this (a point cloud named) is displayed, it is successful.
By the way, if you execute the above three for confirmation at the same time, it looks like this
Now that we have finally created a 3D display of the object in the point cloud, I would like to generate polygons and their vertices from the point cloud.
2020/9/18 postscript Part 4 has been released. https://qiita.com/Ksuke/items/144c06f128b015b001dd
If you add it after the previous code, it should work.
Code summary(Function)
#A two-dimensional image is stretched and projected in the three-dimensional direction.
def imgProject(img,imgSize):
#By repeatedly arranging the image in the z-axis direction, the image is thickened and stretched for projection.
projectSpace = np.tile(img[:,:,None],(1,1,imgSize))
#Returns the projected space
return projectSpace
Code summary(Execution code)
#Project a background-separated image into a three-dimensional space as a point cloud object(Trace on!)
imgProjectSpaces = [imgProject(sepBackImg,imgSize) for sepBackImg in sepBackImgs]
#The surface that comes to the front of the space according to the original image is different from the front, side, and top of the cup.
#Align the axes so that the front of the cup comes to the front in all spaces.
transposeValues = [(0,1,2),(0,2,1),(2,1,0)]
transposedSpaces = [imgProjectSpace.transpose(*transposeValue) for imgProjectSpace,transposeValue in zip(imgProjectSpaces,transposeValues)]
#By superimposing the point clouds in each space, create a point cloud that looks the same silhouette as the photo when viewed from the front, side, or top surface.
imgProjectSpace = transposedSpaces[0]
for transposedSpace in transposedSpaces[1:]:
imgProjectSpace = imgProjectSpace*transposedSpace
print("step03:projection of image in 3D space is success\n")
#For confirmation display below(It has nothing to do with the main flow, so it will probably disappear in the next round)
#Create a list of coordinates of the point cloud position from the space just projected
imgCoords = [binary2coords(imgProjectSpace) for imgProjectSpace in imgProjectSpaces]
#Shift width of the vertices of each image
offsets = [[-50,-150,-50],[-50,-50,-50],[-50,50,-50]]
#Name when registering the vertices of each image as an object
names = ['frontSpace','sideSpace','topSpace']
#Draw vertices
[addObj(coords=imgCoord,name = name,offset=offset) for imgCoord,name,offset in zip(imgCoords,names,offsets)]
#Create a list of coordinates of the position of the point cloud from the space where the axes are adjusted.
imgCoords = [binary2coords(transposedSpace) for transposedSpace in transposedSpaces]
#Shift width of the vertices of each image
offsets = [[-150,-150,-50],[-150,-50,-50],[-150,50,-50]]
#Name when registering the vertices of each image as an object
names = ['frontTransposedSpace','sideTransposedSpace','topTransposedSpace']
#Draw vertices
[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