描述、优点
使用glsl来代替opencv的undistort 和 鱼眼矫正,并且最后使用opencv的LUT给glsl 来使用,来达到加速的目的,并且做到和opencv 一模一样的效果,达到实时视频的加速矫正。
优点: 没有cuda,也可以做到实时视频矫正,包含各类板子和amd的cpu,intel核显
矫正的基本作用就是消除径向畸变和切向畸变
鱼眼镜头使用等距畸变模型(EQUIDISTANT),而普通镜头使用布朗-康拉德模型。二者的关键区别在于:
下面分别说明普通镜头和鱼眼镜头
1 顶点和片段着色器
1.1 顶点着色器
#version 330 core
layout(location = 0) in vec2 position;
layout(location = 1) in vec2 texCoord;
out vec2 vTexCoord;
void main() {
gl_Position = vec4(position, 0.0, 1.0);
vTexCoord = texCoord;
}
1.2 片段着色器
小于70度左右的摄像头使用opencv的undistort函数
片段着色器最重要的就是opengl的坐标系,观察一下顶点数据
// 顶点数据
float vertices[] = {
// 位置 // 纹理坐标
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f
};
纹理坐标是 0,0 到 1.0,0.0 到 1.0.1,0 到 0.0,1.0 , 也就是左下角,右下角,右上角,左上角,,首先转换成像素坐标,坐标是从下到上的, 而图像坐标,或者我们说opencv 坐标Y轴是从上到下的。
1.3 undistort
#version 330 core
uniform sampler2D inputImage;
uniform mat3 cameraMatrix;
uniform mat3 cameraMatrixInv;
uniform vec4 distortionCoeffs;
uniform vec2 imageSize;
in vec2 vTexCoord;
out vec4 fragColor;
void main() {
//-----------------------------------------------------------
// 第一步:将纹理坐标转换为OpenCV像素坐标
//-----------------------------------------------------------
// OpenGL纹理坐标 -> OpenCV像素坐标 (Y翻转)
vec2 pixelCoord = vec2(
vTexCoord.x * imageSize.x,
(1.0 - vTexCoord.y) * imageSize.y
);
//-----------------------------------------------------------
// 第二步:转换为相机坐标系(应用内参逆变换)
//-----------------------------------------------------------
vec3 cameraCoord = cameraMatrixInv * vec3(pixelCoord, 1.0);
vec2 xyn = cameraCoord.xy / cameraCoord.z;
//-----------------------------------------------------------
// 第三步:应用畸变模型
//-----------------------------------------------------------
float x = xyn.x;
float y = xyn.y;
float r2 = x*x + y*y;
// 径向畸变
float radial = 1.0 + distortionCoeffs.x*r2 + distortionCoeffs.y*r2*r2;
// 切向畸变
vec2 tangential = vec2(
2.0*distortionCoeffs.z*x*y + distortionCoeffs.w*(r2 + 2.0*x*x),
distortionCoeffs.z*(r2 + 2.0*y*y) + 2.0*distortionCoeffs.w*x*y
);
vec2 distorted = xyn * radial + tangential;