我有大量的鱼眼镜头拍摄的照片。由于我想对照片进行一些图像处理(例如边缘检测),因此我想消除桶形失真,这会严重影响我的效果。纠正FishEye镜头的桶形失真校正算法 - 未能用Java实现
经过一番研究和大量的阅读文章,我发现这page:他们描述了一个算法(和一些公式)来解决这个问题。
M = A * rcorr^3 + B * rcorr^2 + C * rcorr + d
RSRC =(A * rcorr^3 + B * rcorr^2 + C * rcorr + d)* rcorrRSRC =从源图像的中心的像素的距离
rcorr =校正图像
A,b,C =图像 d的失真=线性图像的缩放从中心像素的距离
我用这些公式并试图在Java应用程序中实现这一点。不幸的是,它不工作,我没有成功。 “修正”图像看起来不像原始照片,而是在中间显示一些神秘的圈子。看看这里:
http://imageshack.us/f/844/barreldistortioncorrect.jpg/ (这曾经是一个白色的牛在前面的蓝色墙壁的照片)
这里是我的代码:
protected int[] correction(int[] pixels) {
//
int[] pixelsCopy = pixels.clone();
// parameters for correction
double paramA = 0.0; // affects only the outermost pixels of the image
double paramB = -0.02; // most cases only require b optimization
double paramC = 0.0; // most uniform correction
double paramD = 1.0 - paramA - paramB - paramC; // describes the linear scaling of the image
//
for(int x = 0; x < dstView.getImgWidth(); x++) {
for(int y = 0; y < dstView.getImgHeight(); y++) {
int dstX = x;
int dstY = y;
// center of dst image
double centerX = (dstView.getImgWidth() - 1)/2.0;
double centerY = (dstView.getImgHeight() - 1)/2.0;
// difference between center and point
double diffX = centerX - dstX;
double diffY = centerY - dstY;
// distance or radius of dst image
double dstR = Math.sqrt(diffX * diffX + diffY * diffY);
// distance or radius of src image (with formula)
double srcR = (paramA * dstR * dstR * dstR + paramB * dstR * dstR + paramC * dstR + paramD) * dstR;
// comparing old and new distance to get factor
double factor = Math.abs(dstR/srcR);
// coordinates in source image
double srcXd = centerX + (diffX * factor);
double srcYd = centerY + (diffX * factor);
// no interpolation yet (just nearest point)
int srcX = (int)srcXd;
int srcY = (int)srcYd;
if(srcX >= 0 && srcY >= 0 && srcX < dstView.getImgWidth() && srcY < dstView.getImgHeight()) {
int dstPos = dstY * dstView.getImgWidth() + dstX;
pixels[dstPos] = pixelsCopy[srcY * dstView.getImgWidth() + srcX];
}
}
}
return pixels;
}
我的问题是:
1)这个公式是否正确?
2)我是否犯了一个错误将该公式转换为软件?
3)还有其他的算法(例如How to simulate fisheye lens effect by openCV?或wiki/Distortion_(光学)),它们更好吗?
感谢您的帮助!
边缘附近的像素的正方形网格说明了很多问题可能是什么。无论您的算法是否适用于任何照片,我都不知道。一个可能的原因是它不起作用,因为你可能会过度纠正失真。 – AJMansfield
正如我在下面提到的,我尝试将b设置为一个无限小的值。它给出了不同的结果(不再有球面校正),但仍然不显示相同的图像。请看这里:http://imageshack.us/f/191/barreldistortioncorrect.jpg/ – Lucas
可能无限小的b值在_other_方向过矫? – AJMansfield