Our project is to convert a person's photo into a 3D Avatar. In this case, we need to extract the face contour, obtain the head model based on the photos, and map the human photos and paste them on the model.
Our team originally intended to use SFS to get the face model, but after in-depth research, we found that SFS is a very high-end field and difficult, so we decided to first make a common face model, then adjust the face model according to the photo.
Since I am mainly responsible for the establishment of the face model, I will focus on how to use OpenGL to read the model.
First, we will introduce OpenGL.
OpenGL stands for open graphics library, which is an open graphical program interface. It is the most widely accepted 2D/3D graphic API in the industry. Although direct3d is also a very good graphic API, but it is only used in windows. OpenGL is not only used for windows, but also for Unix/Linux and other systems. It is applicable to large computers and various specialized computers (such as medical display devices. In addition, the basic commands of OpenGL are not related to hardware, or even platform.
More importantly, it is closely integrated with the C language, which is easy for those who have learned the C language. If you want to map data with a computer but do not know where to start, if you only use C language, we recommend that you learn OpenGL.
The OBJ file here does not appear during programming. It is used to compile the application file. The OBJ file here refers to a standard 3D model file format developed by alias | wavefront for its workstation-based 3D modeling and animation software "Advanced visualizer. It is suitable for intercommunication between 3D software models, and OBJ files can be exported using 3D Max.
An OBJ file is a text file format that can be opened directly on a wordpad. After opening it, you will find it very concise and neat. Below is an example of the OBJ file.
For details about its file structure, you can find more details online. Here we only focus on vertex data. V indicates the vertex of the ry, VT indicates the coordinate point of the texture, vn indicates the normal of the vertex, F indicates the index number, and a left slash (/) indicates: f vertex index/map coordinate index/normal index. Index Numbers refer to the order of points. Suppose there are four points, point 1, point 2, point 3, and point 4. The connection sequence of F 1 2 3 4 is 1, 2, 3, 4, and the connection sequence of F 1 3 2 4 is 1, 3, 2, 4.
Then we can write the program and read the OBJ file. First use fopen to read the file, and then let the program read the file row by row. We can see that there are two lines of useless information at the beginning of the file: do not operate after reading these two lines.
Next, this line is connected to a material file. MTL, but since I have specified a texture in the OpenGL file, this line does not work either.
Continue. Read the location where the object is defined.
The OBJ file in the preceding example has only one object named skin_hi:
Each such structure defines an object. We should also define an object data type in the program.
This is the data type I defined. Objects shows the total number of objects in the entire OBJ file and points to each object at the same time. An object is the number of V and F contained in an object. It is the same as the number of V, vn, VT, and f stored in the object, therefore, it is not pointed out.
F data type is used to store f v/VT/VN. Points, texture coordinates, and discoveries corresponding to each index are stored in X [I] [0], X [I] [1], X [I] [2], when S = 4, use X [0] ~ X [3] storage, when S = 3, use X [0] ~ X [2] storage.
Vettex, vnormal, and VT use float X, Y, and Z. However, because VT corresponds to a plane image, only X and Y are used.
Okay. Next, if you encounter a vertex in the vertex array, a normal in the normal array, and so on. Pay attention to the application of the memory space to successfully read the file.
When writing the program that reads the OBJ file, the most profound feeling is all kinds of data. You must keep a clear mind at all times or it will be easy to mix up. In fact, I can further optimize this data structure. After all, it is inconvenient to use nested data structures. During the writing process, I found that its index value (that is, the number after F) is constantly accumulated, not every object starts from 1, that is, we can only define objects, but not objects, because we don't care about the number of objects in a file. We only need to draw all objects. The accumulated F value makes it possible to put all vertices in an array, instead of separating the vertices of each object into an array as I do.
Okay, read the OBJ file. Next we should plot it.
First, when initializing the OpenGL environment, add
Add to the drawing function
Glbegin () and glend () are the parts drawn by OpenGL. glbegin () parameters reflect the drawing type, and glvertex3f () Is the function of drawing points. The following code shows how OpenGL draws triangles.
Glbegin (gl_triangles );
Glvertex3f (0.0f, 1.0f, 0.0f );
Glvertex3f (-1.0f,-1.0f, 0.0f );
Glvertex3f (1.0f,-1.0f, 0.0f );
Glend ();
The following is an example of our project.
Original
Rotate
Zoom in
Eye zoom-in and eye zoom-in are the coordinates of the eyes. Although the effect is somewhat blunt, it reflects our ability to change some coordinate points. The problem we currently encounter in our project is how to convert the two-dimensional points on the photos into three-dimensional points in the space, or how to associate the photos with the models.
Through this project, we have learned a lot. Personally, it inspires my interest in OpenGL and I have a better understanding of programming. In addition, the entire project has gained a deeper understanding of project production and team cooperation.