私は魚眼レンズで撮影した写真を大量に撮影しています。写真上でいくつかの画像処理(エッジ検出など)を行いたいので、結果を大きく左右するバレル歪みを取り除きたい。 FishEyeレンズを補正するためのバレル歪み補正アルゴリズム - Javaでの実装に失敗しました
は、いくつかの研究と読み取りの記事の多くの後、私はこの pageを見つけました:彼らはこの問題を解決するためのアルゴリズム(およびいくつかの式)を記述します。Mは、*のrcorr^3 + B * rcorr^2 + C * rcorr + D
RSRC =(*のrcorr^3 + B * rcorr^2 + C * rcorr + D)* rcorrを=RSRC =ソース画像の中心からの画素の距離
rcorr =補正画像
画像の、B、画像 DのC =歪み=線形スケーリング中心からの画素の距離私はこれらを使用
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;
}
私の質問は以下のとおりです。)この式は正しいですか?
2)私はその数式をソフトウェアに変えて間違いを犯しましたか?
3)他にもアルゴリズムがあります(例えば、How to simulate fisheye lens effect by openCV?またはwiki/Distortion_(光学))。
ありがとうございました!
エッジ付近のピクセルの正方形のグリッドは、問題の可能性についてたくさん言います。あなたのアルゴリズムがどんな写真にもかかわらず、私は分かりません。それがうまくいかない理由の1つは、歪みが過剰補正されている可能性があるということです。 – AJMansfield
私が下で述べたように、私は無限小の値にbを設定しようとしました。結果は異なりますが(球面補正はありません)、同じ画像は表示されません。ここをクリックしてください:http://imageshack.us/f/191/barreldistortioncorrect.jpg/ – Lucas
_other_方向では、極端に小さいb値が過補正されることがありますか? – AJMansfield