首页 文章

从Image到OpenGL中用户定义的点集(点 Cloud )的纹理映射

提问于
浏览
2

我在世界上有一套三维点 . 使用OpenCV我已经校准了相机的外部参数 .

所以现在我能够将3-D点映射到2-D图像中的相应像素 .

即[X Y Z]我在图像中有相应的[u v] .

在OpenGL中,我已经对世界三维点进行了规范化并定义了一个表面,我想要完成纹理映射 .

The 3-D surface obtained from the code looks like in the figure below.

3-D SURFACE in OPENGL

It is a bowl shaped surface .

现在我想将图像中的纹理映射到OpenGL中的三维点 .

我有的信息:

1. 3-D co-ordinates of a parabolic surface in openGL obtained from world points.

2. Corresponding 2-D Image coordinates and R-G-B colour info of pixels.

我该怎么做呢

Here is my code snippet for getting the 3-D points lying on the model surface shown in the link, using real world coordinates

Also it stores the corresponding (u v) pixel coordinate's RGB colour info in image for rendering

for (int z_3D = 0; z_3D < 30; z_3D+=1)
{
    for (int x_3D = 0; x_3D < 102; x_3D+=1)
    {
        for (int y_3D = 0; y_3D < 135.5; y_3D+=1)
        {

            //3-D point in real world(in cms)
            x = x_3D;
            y = y_3D;
            z = z_3D;
            object_point[0].x = x;
            object_point[1].y = y;
            object_point[2].z = z;


            //Project 3-D point to 2-D image and get the corresponding (u,v)
            //rvec and tvec Obtained using SolvPnP in openCV
            projectPoints(object_point, rvec_front, tvec_front, cameraMatrix_Front, distCoeffs_Front, check_front_image_pts);


            //Store colour information in the corresponding 2-D point
            //Points not lying on the surface is black
            rgb.r = 0;
            rgb.g = 0;
            rgb.b = 0;



            //Convert real world coordinates into openGl coordinates(-1 to +1)
            x = (x - CHART_WIDTH / 2) / (CHART_WIDTH / 2);
            y = -(y - CHART_LENGTH / 2) / (CHART_LENGTH / 2);
            z = z / CHART_HEIGHT;


            //Parabolic surface model
            float x_4 = x*x*x*x;
            float y_4 = y*y*y*y;


            if (x_4 + y_4 <  r_4)
            {           
                //Store 3-D point
                vertex_obj.vertex_x.push_back(x);
                vertex_obj.vertex_y.push_back(y);
                vertex_obj.vertex_z.push_back((x_4 + y_4) / (a_4));

                /**/
                //Store colour information in the corresponding 2-D point
                rgb.r = front.at<Vec3b>(check_front_image_pts[0].y, check_front_image_pts[0].x)[2];
                rgb.g = front.at<Vec3b>(check_front_image_pts[0].y, check_front_image_pts[0].x)[1];
                rgb.b = front.at<Vec3b>(check_front_image_pts[0].y, check_front_image_pts[0].x)[0];

                //printf("%f %f %f\n", rgb.r, rgb.g, rgb.b);


                vertex_obj.vertex_colour.push_back(rgb);

            }
            else if (sqrt((x_4 + y_4 - r_4)*(x_4 + y_4 - r_4)) < 0.0001)
            {

                //Store 3-D point
                vertex_obj.vertex_x.push_back(x);
                vertex_obj.vertex_y.push_back(y);
                //vertex_obj.vertex_z.push_back(1.0);
                vertex_obj.vertex_z.push_back((x_4 + y_4) / (a_4)+0.0001);

                /*
                //Store colour information in the corresponding 2-D point
                rgb.r = front.at<Vec3b>(check_front_image_pts[0].y, check_front_image_pts[0].x)[2];
                rgb.g = front.at<Vec3b>(check_front_image_pts[0].y, check_front_image_pts[0].x)[1];
                rgb.b = front.at<Vec3b>(check_front_image_pts[0].y, check_front_image_pts[0].x)[0];*/

                vertex_obj.vertex_colour.push_back(rgb);

            }

        }
    }
}

This is my rendering code snippet

void render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


glLoadIdentity();                 // Reset the model-view matrix

glRotated(ph, 1, 0, 0);
glRotated(th, 0, 1, 0);

glBegin(GL_POINTS);

for (int i = 0; i < vertex_obj.vertex_x.size(); i++)
{
    //Give the colour info from the pixel in the image
    glColor3f(vertex_obj.vertex_colour[i].r/255.0, vertex_obj.vertex_colour[i].g/255.0, vertex_obj.vertex_colour[i].b/255.0);

    //Give the vertex of points lying on the surface defined
    glVertex3f(vertex_obj.vertex_x[i], vertex_obj.vertex_y[i], vertex_obj.vertex_z[i]);
}


//glColor3f(0, 0, 1);
//glVertex2f(1.0, -1.0);

glEnd();


glutSwapBuffers();

}

QUESTIIONS

  • 如何使用图像填充曲面 .

I am aware that only a part of the surface is going to be filled based on the 3-D and the corresponding 2-D image coordinates.

  • 另外如果我给顶点赋予颜色,我该如何在空隙中插入颜色 . OpenGL插入已知形状,如三角形和四边形 .

但这几乎是一个随机点 Cloud ,我想在最近的像素之间进行插值 .

我该怎么做呢 .

2 回答

  • 0

    我假设纹理图像的形状类似于您要将其绘制到的表面,例如应用于3D半球的人脸?

    首先,将表面定义为曲面,而不是点 Cloud . 您已经为曲面上的点生成顶点坐标,因此只需将它们链接到三角形网格中即可 . (GL_TRIANGLE_STRIP)

    其次,不要将颜色应用于曲面的顶点 . 改为设置纹理坐标 . (在OpenGL中,它们通常被称为s,而不是u,v但其含义是相同的 . )顶点颜色应该只是纯白色 . 使用glTexture2D将图像传递给OpenGL .

    通过这种方式,您可以让GPU查找纹理坐标,插入并填充表面,而不是编写自己的代码 .

    哦,你正在使用非常老式的glBegin..glEnd块 . 在其他人做之前,你真的需要学习如何使用顶点数组或最好是OpenGL 4 VBO .

    希望这可以帮助 .

  • 0

    如果要在实时搜索基于体素的密集映射时执行此操作,可以使用不同的技术 . 如果性能不是主要问题,并且您希望在opengl应用程序中执行此操作,则可以使用delnauy三角测量等算法对点 Cloud 进行三角测量,然后使用uv进行纹理映射 . 如果您希望它是离线过程,您可以使用meshlab,如软件导出到三维的三维格式并在opengl应用程序中加载它 .

相关问题