🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Q&A

1回答

9333閲覧

OpenCVで理想点にキャリブレーションする方法について

cab

総合スコア4

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

0グッド

0クリップ

投稿2019/12/21 04:49

前提・実現したいこと

C# + OpenCvSharp3を用いて「カメラで撮像した歪みのあるグリッドパターンを理想点でキャリブレーションし、歪みのないグリッドパターン画像に変換」したいと考えています。

処理の流れは以下の通りとなります。
1.撮像したグリッドパターン画像を読み込み、円の中心点の座標を検出
2.中心点の座標に対応する理想点の座標を入力
3.上記の座標値からカメラ行列を求め、理想点の位置に変換するよう、射影変換(WarpPerspective())を行う。
カメラから取得したイメージ
理想の結果
現状の結果

発生している問題・エラーメッセージ

テスト用に作成した画像では上手くいっているように見えたのですが、実際のカメラから取得する画像だと、左右上下に歪みが残っている状況となっています。(添付とは別のカメラ画像です。サイズとしては5000×5000 pixel程度になります)
本件、ソースコードに何か問題があるのでしょうか?
または、理想点にキャリブレーションするのであれば、この方法が良いというものがあれば、ご教授のほど、よろしくお願いいたします。

該当のソースコード

C#ソースコード
https://robotics.stackexchange.com/questions/14417/opencv-get-topdown-view-of-planar-pattern-by-using-intrinsic-and-extrinsic-from ←こちらのサイトのコードを参考にさせていただいてます)

Mat src_img = new Mat();

string path = @"..\src_img.jpg"; src_img = new Mat(path, ImreadModes.Color); SimpleBlobDetector.Params param = new SimpleBlobDetector.Params(); param.MaxArea = 100000; SimpleBlobDetector.Create(param); Mat current = src_img; Cv2.CvtColor(src_img, current, ColorConversionCodes.BGR2GRAY); OpenCvSharp.Size pattern = new OpenCvSharp.Size(7, 5); var disPts = new List<MatOfPoint2f>(); MatOfPoint2f grid = new MatOfPoint2f(); bool isFoundCorner; isFoundCorner = Cv2.FindCirclesGrid(current, pattern, OutputArray.Create(grid), FindCirclesGridFlags.SymmetricGrid, SimpleBlobDetector.Create(param)); disPts.Add(grid); var object_points = new List<Point3f>(); for (int i = 0; i < 5; i++) { for (int j = 0; j < 7; j++) { object_points.Add(new Point3f(99 + j * 100, 99 + i * 100, 0.0F)); } } var objects = new List<MatOfPoint3f>(); MatOfPoint3f oPointMat = new MatOfPoint3f(7 * 5, 1, object_points.ToArray()); objects.Add(oPointMat); Mat distCoeffs = new Mat(5, 1, MatType.CV_64F); Mat[] rvecs; Mat[] tvecs; Mat intrinsic = new Mat(3, 3, MatType.CV_64F); OpenCvSharp.Size imgsize = new OpenCvSharp.Size(src_img.Width, src_img.Height); Cv2.CalibrateCamera(objects, disPts, imgsize, intrinsic, distCoeffs, out rvecs, out tvecs); Mat tempImg = new Mat(); Cv2.Undistort(images[0], tempImg, intrinsic, distCoeffs); var transData = new double[] { 0, 0, tvecs[0].At<double>(0), 0, 0, tvecs[0].At<double>(1), 0, 0, tvecs[0].At<double>(2) }; Mat translate = new Mat(3, 3, MatType.CV_64F, transData); Mat rotation = new Mat(); Cv2.Rodrigues(rvecs[0], rotation); Mat transRot = new Mat(3, 3, MatType.CV_64F); rotation.Col.Get(0).CopyTo(transRot.Col.Get(0)); rotation.Col.Get(1).CopyTo(transRot.Col.Get(1)); translate.Col.Get(2).CopyTo(transRot.Col.Get(2)); Mat dist_img = new Mat(); Mat matPerspective = intrinsic * transRot; Cv2.WarpPerspective(tempImg, dist_img, matPerspective, imgsize ,InterpolationFlags.WarpInverseMap); Cv2.ImShow("CalWARP", dist_img); Cv2.ImWrite(@"..\dist_img.jpg", dist_img);

試したこと

途中で作成したカメラ行列のパラメータを編集しましたが、樽型に拡大していくだけで、理想の効果は得られませんでした。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

「校正精度が悪いです」という話なのでしょうか?
であれば,もっと真面目に内部パラメータの校正作業に取り組めば改善しないのですか?

投稿2019/12/22 01:11

fana

総合スコア11985

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cab

2019/12/22 01:18

ご連絡ありがとうございます。 パラメータの編集も行いましたが、精度が悪いのは外枠のグリッドのみらしく、外枠を修正しても、今度は内部側が樽型になってしまう状況となっています。 WarpPerspective以外に、理想点通りに画像を変形出来れば良いのですが…
fana

2019/12/23 01:13

Cv2.Undistort ← これに食わせている内部パラメータの精度が問題なのでは?という話です. で,その精度面の悪さは Cv2.CalibrateCameraによる内部パラメータの校正を,1画像から得たデータだけで行っていることに由来するのではないか?と.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問