エピポーラ線の計算
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
F行列に基づき,エピポーラ線の情報を計算してくれる
#contents
*void cvComputeCorrespondEpilines( CvMat* points, int whi...
fmatrixの情報に基づき,points内の点に対応する直線の方程式...
**引数 [#id5db63c]
-points:CvMat*型の点
-whichImage:1から2への投影か,2から1への投影か.1か2を指...
-fmatrix:F行列
-lines:CvMat*型の直線の方程式
**返り値 [#w5b621d4]
-void型なのでなし.
*void computeCorrespondEpilines( Mat& points, int whichIm...
-C++インタフェース版
-linesがCvMat型からVec3fのvectorに変わってる
*解説 [#w5117b84]
-pointsは2xN,Nx2,3xN,Nx3のいずれか(Nは点数)
-なお,計算してくれるのは直線の方程式だけなので,描画の作...
-whichImageには1か2を指定
--1:1枚目の点→2枚目の直線に(F行列をそのまま使用)
--2:2枚目の点→1枚目の直線に(F行列を転置して使用)
--[[F行列計算時>F行列の計算]]の順序がポイント
-linesに格納されるベクトル&mimetex(l);の特性
--&mimetex( l^\top [\begin{array}x y 1\end{array}\left]^\...
--&mimetex( a * x + b * y + c = 0);
--&mimetex( a^2+b^2=1);となるよう正規化されている
*サンプルコード [#a62b1957]
#geshi(c++,number){{
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <iostream>
const char windowName[] = "Test";
const char LeftImageFileName[] = "hogehoge\\Left.jpg";
const char RightImageFileName[] = "hogehoge\\Right.jpg";
const int pointCount = 10;
using namespace cv;
int main(int argc, char** argv);
// 対応する特徴点を適当に読み込む関数.
void readPointsLeft(const Mat& imageLeft, Mat& pointsLef...
void readPointsRight(const Mat& imageRight, Mat& pointsR...
// エピポーラ線を描画する関数
void drawEpilines(Mat& image, std::vector<Vec3f> lines, ...
// 直線の方程式があるx座標を通過するときのy座標を求める
inline double solveY(Vec3f efficient, double x);
// ×点を描画する関数
void drawCross(Mat& image, Mat& points);
// 画像を2枚描画する関数
void showBothImage(Mat *image);
int main(int argc, char** argvv){
// 2枚の画像.
Mat inputImage[2];
inputImage[0] = imread(LeftImageFileName); //...
inputImage[1] = imread(RightImageFileName); //...
// 2枚とも表示
showBothImage(inputImage);
// 各画像から特徴点を読み込む
// 今回は事前に取った特徴点をハードコーディング...
Mat points[2];
readPointsLeft(inputImage[0], points[0]);
readPointsRight(inputImage[1], points[1]);
// 画像に特徴点を×として描画
for(int i = 0;i < 2;i++){
drawCross(inputImage[i], points[i]);
}
// 2枚とも表示
showBothImage(inputImage);
Mat FMatrix; // F行列用変数
std::vector<uchar> mask; // F行列計算に使われた...
// F行列を計算
// ここでwhichImageの1か2が決まる↓ここに入るのが...
FMatrix = findFundamentalMat(points[0], points[1...
// ↑ここ...
for(int i = 0;i < 2;i++){
std::vector<Vec3f> lines;
// F行列と特徴点から,エピポーラ線の方程...
computeCorrespondEpilines(points[i], 1+i...
// ↑で計算されたエピポーラ線の方程式を元...
drawEpilines(inputImage[1-i], lines, mas...
}
// 2枚とも表示
showBothImage(inputImage);
// ウィンドウを破棄
destroyWindow(windowName);
return 0;
}
// 特徴点の座標を格納する関数
// 格納方法は適当で良いが,格納順に注目
void readPointsLeft(const Mat& imageLeft, Mat& pointsLef...
static float points[] = { 17,175, // x1, ...
370,24, // x2, ...
192,456, // :
614,202, // :
116,111, // :
305,32, // :
249,268, // :
464,157, // :
259,333, // :
460,224};// x10,...
// floatの配列を元にMatを作成
// double (CV_64F)にすると findFundamentalMat で...
// CV_32FC2 にしたのは,データの格納方法をわかり...
pointsLeft = Mat::Mat(cv::Size(1, pointCoun...
}
// 基本的に readPointsLeft と同じ
void readPointsRight(const Mat& imageRight, Mat& pointsR...
static float points[] = { 295,28,
584,221,
67,172,
400,443,
330,9,
480,140,
181,140,
350,265,
176,193,
333,313};
pointsRight = Mat::Mat(cv::Size(1, pointCoun...
}
// 方程式を元に直線を描画する
void drawEpilines(Mat& image, std::vector<Vec3f> lines, ...
// 直線の方程式を格納したvector
std::vector<Vec3f>::iterator it;
// 使われた特徴点フラグ
std::vector<uchar>::iterator itmask;
it = lines.begin();
itmask = mask.begin();
while(it != lines.end()){
if(*itmask == 0){
// mask の値が0ということは,計...
it++;
itmask++;
continue;
}
if((*it)[1]){
// Y軸と交わる直線の場合
double width = image.size().w...
// left は x=0 における直線の通...
Point2d left = Point2d(0.0, ...
// right は x=width における直線...
Point2d right = Point2d(width,...
// 左端から右端に直線を引く
line(image, left, right, Scalar(...
}else{
// Y軸に平行な直線の場合
// x座標は一定なので,あらかじめ...
double x = -(*it)[2]/(*it...
// 画像の上端を通過する座標
Point2d top = Point2d(x, 0.0);
// 画像の下端を通過する座標
Point2d bottom = Point2d(x, ima...
// 上端から下端に直線を引く
line(image, top, bottom, Scalar(...
}
it++;
itmask++;
}
}
// 直線の方程式とx座標からy座標を計算する
inline double solveY(Vec3f efficient, double x){
return - (efficient[0] * x + efficient[2]) / eff...
}
// points で与えた座標を中心に×印を描く
void drawCross(Mat& image, Mat& points){
Point2f cross1 = Point2f(2, 2);
Point2f cross2 = Point2f(2, -2);
for(int i = 0;i < points.size().height;i++){
Point2f point = Point2f(points.at<floa...
line(image, point - cross1, point + cros...
line(image, point - cross2, point + cros...
}
}
// ウィンドウに画像を表示
void showBothImage(Mat *image){
namedWindow(windowName, CV_WINDOW_FREERATIO | CV...
for(int i = 0;i < 2;i++){
imshow(windowName, image[i]);
waitKey(0);
}
}
}}
*実体ファイル [#m91740bc]
-OpenCV1.1以前の場合
--cv/include/cv.h
--cv/src/cvfundam.cpp
-OpenCV2.0,2.1
--opencv/cv.h
--src/cv/cvfundam.cpp
-OpenCV2.2
--opencv2/calib3d/calib3d.hpp
--modules/calib3d/src/fundam.cpp
*実行結果 [#ze886565]
左カメラ画像.見づらいけれど,計10点×印が付いている.&br();
http://tessy.org/wiki/index.php?plugin=attach&pcmd=open&r...
右カメラ画像.見づらいけれど,計10点×印が付いている.&br();
http://tessy.org/wiki/index.php?plugin=attach&pcmd=open&r...
左カメラ画像に引いた,右カメラからのエピポーラ線.何点か...
http://tessy.org/wiki/index.php?plugin=attach&pcmd=open&r...
右カメラ画像に引いた,左カメラからのエピポーラ線.何点か...
http://tessy.org/wiki/index.php?plugin=attach&pcmd=open&r...
*注意 [#b0043d2e]
-N<=3で投影するときは注意が必要.
-&mimetex(\left(\begin{array}{cc}x_1&x_2\\ y_1& y_2 \\ \...
-問題を回避するためには,サンプルコードの様に幅1でマルチ...
-C++インタフェースはCインタフェースのラッパー関数.(2.2で...
ジャンル[[:OpenCV]][[:OpenCV 1.0]][[:OpenCV 1.1]][[:OpenC...
終了行:
F行列に基づき,エピポーラ線の情報を計算してくれる
#contents
*void cvComputeCorrespondEpilines( CvMat* points, int whi...
fmatrixの情報に基づき,points内の点に対応する直線の方程式...
**引数 [#id5db63c]
-points:CvMat*型の点
-whichImage:1から2への投影か,2から1への投影か.1か2を指...
-fmatrix:F行列
-lines:CvMat*型の直線の方程式
**返り値 [#w5b621d4]
-void型なのでなし.
*void computeCorrespondEpilines( Mat& points, int whichIm...
-C++インタフェース版
-linesがCvMat型からVec3fのvectorに変わってる
*解説 [#w5117b84]
-pointsは2xN,Nx2,3xN,Nx3のいずれか(Nは点数)
-なお,計算してくれるのは直線の方程式だけなので,描画の作...
-whichImageには1か2を指定
--1:1枚目の点→2枚目の直線に(F行列をそのまま使用)
--2:2枚目の点→1枚目の直線に(F行列を転置して使用)
--[[F行列計算時>F行列の計算]]の順序がポイント
-linesに格納されるベクトル&mimetex(l);の特性
--&mimetex( l^\top [\begin{array}x y 1\end{array}\left]^\...
--&mimetex( a * x + b * y + c = 0);
--&mimetex( a^2+b^2=1);となるよう正規化されている
*サンプルコード [#a62b1957]
#geshi(c++,number){{
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <iostream>
const char windowName[] = "Test";
const char LeftImageFileName[] = "hogehoge\\Left.jpg";
const char RightImageFileName[] = "hogehoge\\Right.jpg";
const int pointCount = 10;
using namespace cv;
int main(int argc, char** argv);
// 対応する特徴点を適当に読み込む関数.
void readPointsLeft(const Mat& imageLeft, Mat& pointsLef...
void readPointsRight(const Mat& imageRight, Mat& pointsR...
// エピポーラ線を描画する関数
void drawEpilines(Mat& image, std::vector<Vec3f> lines, ...
// 直線の方程式があるx座標を通過するときのy座標を求める
inline double solveY(Vec3f efficient, double x);
// ×点を描画する関数
void drawCross(Mat& image, Mat& points);
// 画像を2枚描画する関数
void showBothImage(Mat *image);
int main(int argc, char** argvv){
// 2枚の画像.
Mat inputImage[2];
inputImage[0] = imread(LeftImageFileName); //...
inputImage[1] = imread(RightImageFileName); //...
// 2枚とも表示
showBothImage(inputImage);
// 各画像から特徴点を読み込む
// 今回は事前に取った特徴点をハードコーディング...
Mat points[2];
readPointsLeft(inputImage[0], points[0]);
readPointsRight(inputImage[1], points[1]);
// 画像に特徴点を×として描画
for(int i = 0;i < 2;i++){
drawCross(inputImage[i], points[i]);
}
// 2枚とも表示
showBothImage(inputImage);
Mat FMatrix; // F行列用変数
std::vector<uchar> mask; // F行列計算に使われた...
// F行列を計算
// ここでwhichImageの1か2が決まる↓ここに入るのが...
FMatrix = findFundamentalMat(points[0], points[1...
// ↑ここ...
for(int i = 0;i < 2;i++){
std::vector<Vec3f> lines;
// F行列と特徴点から,エピポーラ線の方程...
computeCorrespondEpilines(points[i], 1+i...
// ↑で計算されたエピポーラ線の方程式を元...
drawEpilines(inputImage[1-i], lines, mas...
}
// 2枚とも表示
showBothImage(inputImage);
// ウィンドウを破棄
destroyWindow(windowName);
return 0;
}
// 特徴点の座標を格納する関数
// 格納方法は適当で良いが,格納順に注目
void readPointsLeft(const Mat& imageLeft, Mat& pointsLef...
static float points[] = { 17,175, // x1, ...
370,24, // x2, ...
192,456, // :
614,202, // :
116,111, // :
305,32, // :
249,268, // :
464,157, // :
259,333, // :
460,224};// x10,...
// floatの配列を元にMatを作成
// double (CV_64F)にすると findFundamentalMat で...
// CV_32FC2 にしたのは,データの格納方法をわかり...
pointsLeft = Mat::Mat(cv::Size(1, pointCoun...
}
// 基本的に readPointsLeft と同じ
void readPointsRight(const Mat& imageRight, Mat& pointsR...
static float points[] = { 295,28,
584,221,
67,172,
400,443,
330,9,
480,140,
181,140,
350,265,
176,193,
333,313};
pointsRight = Mat::Mat(cv::Size(1, pointCoun...
}
// 方程式を元に直線を描画する
void drawEpilines(Mat& image, std::vector<Vec3f> lines, ...
// 直線の方程式を格納したvector
std::vector<Vec3f>::iterator it;
// 使われた特徴点フラグ
std::vector<uchar>::iterator itmask;
it = lines.begin();
itmask = mask.begin();
while(it != lines.end()){
if(*itmask == 0){
// mask の値が0ということは,計...
it++;
itmask++;
continue;
}
if((*it)[1]){
// Y軸と交わる直線の場合
double width = image.size().w...
// left は x=0 における直線の通...
Point2d left = Point2d(0.0, ...
// right は x=width における直線...
Point2d right = Point2d(width,...
// 左端から右端に直線を引く
line(image, left, right, Scalar(...
}else{
// Y軸に平行な直線の場合
// x座標は一定なので,あらかじめ...
double x = -(*it)[2]/(*it...
// 画像の上端を通過する座標
Point2d top = Point2d(x, 0.0);
// 画像の下端を通過する座標
Point2d bottom = Point2d(x, ima...
// 上端から下端に直線を引く
line(image, top, bottom, Scalar(...
}
it++;
itmask++;
}
}
// 直線の方程式とx座標からy座標を計算する
inline double solveY(Vec3f efficient, double x){
return - (efficient[0] * x + efficient[2]) / eff...
}
// points で与えた座標を中心に×印を描く
void drawCross(Mat& image, Mat& points){
Point2f cross1 = Point2f(2, 2);
Point2f cross2 = Point2f(2, -2);
for(int i = 0;i < points.size().height;i++){
Point2f point = Point2f(points.at<floa...
line(image, point - cross1, point + cros...
line(image, point - cross2, point + cros...
}
}
// ウィンドウに画像を表示
void showBothImage(Mat *image){
namedWindow(windowName, CV_WINDOW_FREERATIO | CV...
for(int i = 0;i < 2;i++){
imshow(windowName, image[i]);
waitKey(0);
}
}
}}
*実体ファイル [#m91740bc]
-OpenCV1.1以前の場合
--cv/include/cv.h
--cv/src/cvfundam.cpp
-OpenCV2.0,2.1
--opencv/cv.h
--src/cv/cvfundam.cpp
-OpenCV2.2
--opencv2/calib3d/calib3d.hpp
--modules/calib3d/src/fundam.cpp
*実行結果 [#ze886565]
左カメラ画像.見づらいけれど,計10点×印が付いている.&br();
http://tessy.org/wiki/index.php?plugin=attach&pcmd=open&r...
右カメラ画像.見づらいけれど,計10点×印が付いている.&br();
http://tessy.org/wiki/index.php?plugin=attach&pcmd=open&r...
左カメラ画像に引いた,右カメラからのエピポーラ線.何点か...
http://tessy.org/wiki/index.php?plugin=attach&pcmd=open&r...
右カメラ画像に引いた,左カメラからのエピポーラ線.何点か...
http://tessy.org/wiki/index.php?plugin=attach&pcmd=open&r...
*注意 [#b0043d2e]
-N<=3で投影するときは注意が必要.
-&mimetex(\left(\begin{array}{cc}x_1&x_2\\ y_1& y_2 \\ \...
-問題を回避するためには,サンプルコードの様に幅1でマルチ...
-C++インタフェースはCインタフェースのラッパー関数.(2.2で...
ジャンル[[:OpenCV]][[:OpenCV 1.0]][[:OpenCV 1.1]][[:OpenC...
ページ名: