C++
OpenCV
OpenCVDay 14

line関数での無限遠直線もどき

はじめに

OpenCVを使っていて、画像上にline関数で二点間ラインを引くことってよくありますよね。
で、たまーに無限遠直線で描きたいなーって時ありません?僕はありませんでした。
ただ、3次元上の直線を2次元に持ってくる時に必要性が生じ、急遽作ることに。
その時の線の描き方をご紹介。(line関数はご存知だと思うので割愛)
目的
データの検証とか

入力データ

まずはデータが必要です
データは、ax+by+c=0とそれらのmixとmaxを用意します。(min,maxが用意できなければ、直線方程式の値から抽出)

図2.png
図1 直線方程式のCSV

座標を作ってあげよう

元の座標空間がないと描けないですよね。それをmin,maxのデータから作ってあげます。

drawLine.cpp
width = (x_max-y_min) + 2000 //ここは気分で;
height = (y_max-x_min) + 1000;
cv::Mat img = cv::Mat::zeros(cv::Size(width, height), CV_8UC3);

線を描いてあげよう

直線方程式ax+by+c=0をy=ax+bに変換します。
これでPoint(x1,y1)とPoint(x1,y2)ができるようにまりますね。

drawLine.cpp
//ax+by+c=0の式をy=ax+bに変換
a2 = b1 / a1;
b2 = (-b1 / a1) * x1 + y1;

x1 = (0 - b2) / a2;
x2 = (y_max - b2) / a2;
y2 = a2 * 0 + b2;

ただし、このまま描いたんじゃ上手く行きません。座標がマイナスだったり、変化が小数点以下だったりするので、単位を変えてあげます。

drawLine.cpp
//座標を合わせるためにシフト
x1 += 10;
y1 += 10;
x2 += 10;
y2 += 10;

//単位統一
x1 *= 100;
y1 *= 100;
x2 *= 100;
y2 *= 100;

cv::line(img, cv::Point(x1, 0), cv::Point(x2, height), cv::Scalar(255, 255, 255), 5, 5);

これで描けたのがこちら
img.jpg
図2 線描画

まあこれが何なのかって言うと、点群という3次元データ上の交線を描画してるんですね。
これを元データと照らし合わせて~とか使うんですが、元データ3次元なんでね、ここに2次元で載せてもわけわからんと思います。

最後に

他の方々と比べ物にならないカス記事ですいません。許してください、なんでもします。
あと私が調べた限り、OpenCVには二点間の描画関数しかなかったのですが、無限遠直線で描ける関数や、もっとよい方法があれば教えて頂けると幸いです。