我在尝试使用OpenGL着色器来实现鱼眼相机去畸变和透视转换,但在去畸变这里遇到了问题。
下面是我分别得到的去畸变图和投影图,可以看出去畸变图中仍然存在部分畸变,在投影变换后畸变会更加明显。
下面是我片段着色器的代码:
#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得到的去畸变图测试了着色器中投影转换部分的代码,可以得出正常的结果,所以猜测问题应该出在畸变模型部分,请问有什么建议吗?非常感谢
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/freeglut.h>
void selectFont(int size, int charset, const char* face)//选择字体对象(包括格式)
{
HFONT hFont = CreateFontA(size, 0, 0, 0, FW_MEDIUM, 0, 0, 0,
charset, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, face);
HFONT hOldFont = (HFONT)SelectObject(wglGetCurrentDC(), hFont);//选择字体对象,返回旧的对象
DeleteObject(hOldFont);//删除旧的对象
}
void drawCNString(const char* str)
{
int len, i;
wchar_t* wstring;
HDC hDC = wglGetCurrentDC();
GLuint list = glGenLists(1);
// 计算字符的个数
// 如果是双字节字符的(比如中文字符),两个字节才算一个字符
// 否则一个字节算一个字符
len = 0;
for (i = 0; str[i] != '\0'; ++i)
{
if (IsDBCSLeadByte(str[i]))
++i;
++len;
}
// 将混合字符转化为宽字符
wstring = (wchar_t*)malloc((len + 1) * sizeof(wchar_t));
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, wstring, len);
wstring[len] = L'\0';
// 逐个输出字符
for (i = 0; i<len; ++i)
{
wglUseFontBitmapsW(hDC, wstring[i], 1, list);
glCallList(list);
}
// 回收所有临时资源
free(wstring);
glDeleteLists(list, 1);
}
void display(void) {
glClear(GL_COLOR_BUFFER_BIT);
selectFont(48, GB2312_CHARSET, "微软雅黑");
glColor3f(1.0f, 1.0f, 0.0f);//设置字体颜色
glRasterPos2f(-0.7f, -0.1f);
drawCNString("像天使依赖着翅膀");
selectFont(48, DEFAULT_CHARSET, "楷体");
glColor3f(0.0f, 1.0f, 0.0f);
glRasterPos2f(-0.7f, -0.6f);
drawCNString("像海豚依赖海洋");
glutSwapBuffers();
}
int main(int argc, char ** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(640, 480);
glutInitWindowPosition(100, 100);
glutCreateWindow("Hello ");
display();
glutMainLoop();
return 0;
}
你好,请问问题解决了吗