neozhaoliang / surround-view-system-introduction

A full Python implementation for real car surround view system
MIT License
858 stars 303 forks source link

尝试使用OpenGL着色器实现环视拼接时遇到的去畸变问题 #57

Closed maGnet2C-cmd closed 1 year ago

maGnet2C-cmd commented 1 year ago

您好,我在尝试使用OpenGL着色器来实现您的工程,但在去畸变这里遇到了问题。 下面是我分别得到的去畸变图和投影图,可以看出去畸变图中仍然存在部分畸变,在投影变换后畸变会更加明显。 result_undist result_proj 下面是我片段着色器的代码:

#version 330 core

in vec2 textureCoords;

uniform sampler2D inputTexture;
uniform float windowWidth;
uniform float windowHeight;
uniform float textureWidth;
uniform float textureHeight;
uniform float scaleTest;

mat3 inverseMatrix = mat3(
    4.2612641166,   13.003206285,   -2228.5388394338,
    0.0517394913,   10.0787253178,  -262.8409400879,
    -0.0010467339,  0.0241003739,   1.0
);

mat3 cameraMatrix = mat3(
    302.4530598322, 0.0,            496.64001463163,
    0.0,            320.7461859439, 331.19980984361,
    0.0,            0.0,            1.0
);

mat3 inverseCamMat = mat3(
    0.00330629817,  0.0,            -1.6420399744,
    0.0,            0.003117729980, -1.0325915766,
    0.0,            0.0,            1.0
);

vec4 distortVector = vec4(-4.3735601598704078e-02, 2.1692522970939803e-02, -2.6388839028513571e-02, 8.4123126605702321e-03);

void main() {
    //投影图坐标到去畸变图坐标
    vec3 frameCoords = vec3(textureCoords.x * windowWidth, textureCoords.y * windowHeight, 1.0);
    vec3 m = inverseMatrix[2] * frameCoords;
    float zed = 1.0 / (m.x + m.y + m.z);
    frameCoords = frameCoords * zed;
    float xTrans = inverseMatrix[0][0]*frameCoords.x + inverseMatrix[0][1]*frameCoords.y + inverseMatrix[0][2]*frameCoords.z;
    float yTrans = inverseMatrix[1][0]*frameCoords.x + inverseMatrix[1][1]*frameCoords.y + inverseMatrix[1][2]*frameCoords.z;
    vec2 coords = vec2(xTrans/windowWidth, yTrans/windowHeight);
    //gl_FragColor = texture(inputTexture, coords);

    //去畸变图坐标到畸变原图坐标
    float i = coords.x * windowWidth * 1.5 - 300;
    float j = coords.y * windowHeight * 1.5 - 250;
    float xc = inverseCamMat[0][0]*i + inverseCamMat[0][2];
    float yc = inverseCamMat[1][1]*j + inverseCamMat[1][2];
    float r = sqrt(xc*xc + yc*yc);
    float degree = atan(r);
    float rd = degree + distortVector[0]*pow(degree,3) + distortVector[1]*pow(degree,5) + distortVector[2]*pow(degree,7) + distortVector[3]*pow(degree,9);
    rd *= scaleTest;
    float scale = rd / r;
    float x = xc * scale;
    float y = yc * scale;
    float u = cameraMatrix[0][0]*x + cameraMatrix[0][2];
    float v = cameraMatrix[1][1]*y + cameraMatrix[1][2];
    vec2 finalCoords = vec2(u/textureWidth, v/textureHeight);

    if (finalCoords.x>=0.0 && finalCoords.x<=1.0 && finalCoords.y>=0.0 && finalCoords.y<=1.0) {
        gl_FragColor = texture(inputTexture, finalCoords);
    } else {
        gl_FragColor = vec4(0.0,0.0,0.0,0.0);
    }
}

其中投影转换部分我参考了这里,去畸变部分我参考了这里 另外scaleTest是我引入的一个出射角因子,上面的结果图是在该因子等于1.02左右时得到的,如果等于1的话畸变会更加明显。 我使用OpenCV得到的去畸变图测试了着色器中投影转换部分的代码,可以得出您工程中类似的结果,所以猜测问题应该出在畸变模型部分,请问有什么建议吗?非常感谢