Android電話でOpenCVを使用して回線を検出しようとしています。「Tutorial1Basic-2。UseOpenCVCamera」サンプルを変更しました。 Hough Line Transform)も使用しています。 例として。しかし、私はポイントに対して奇妙な数(少なくとも私が奇妙な数であると信じているもの)を取得しています。bについては1000から-1000の範囲です。
私はコードを完全に理解していません(主に1000 *(aまたは-b)の加算/減算に関する部分)。
結局、線がまったく見えません。
誰かが私に手を貸してくれませんか?また、さらに情報が必要な場合はお知らせください。
capture.retrieve(mGray, Highgui.CV_CAP_Android_GREY_FRAME);
Imgproc.Canny(mGray, mIntermediateMat, 80, 100);
Imgproc.HoughLines(mIntermediateMat, mLines, 1, Math.PI/180, 100);
Scalar color = new Scalar(0, 0, 255);
double[] data;
double rho, theta;
Point pt1 = new Point();
Point pt2 = new Point();
double a, b;
double x0, y0;
for (int i = 0; i < mLines.cols(); i++)
{
data = mLines.get(0, i);
rho = data[0];
theta = data[1];
a = Math.cos(theta);
b = Math.sin(theta);
x0 = a*rho;
y0 = b*rho;
pt1.x = Math.round(x0 + 1000*(-b));
pt1.y = Math.round(y0 + 1000*a);
pt2.x = Math.round(x0 - 1000*(-b));
pt2.y = Math.round(y0 - 1000 *a);
Core.line(mIntermediateMat, pt1, pt2, color, 3);
}
Imgproc.cvtColor(mIntermediateMat, mRgba, Imgproc.COLOR_GRAY2BGRA, 4);
Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);
if (Utils.matToBitmap(mRgba, bmp))
return bmp;
bmp.recycle();
return null;
HoughLineP を使用して、フレーム内の線を見つけて描画します。
これが私のコードです...これがお役に立てば幸いです。
Mat mYuv = new Mat();
Mat mRgba = new Mat();
Mat thresholdImage = new Mat(getFrameHeight() + getFrameHeight() / 2, getFrameWidth(), CvType.CV_8UC1);
mYuv.put(0, 0, data);
Imgproc.cvtColor(mYuv, mRgba, Imgproc.COLOR_YUV420sp2RGB, 4);
Imgproc.cvtColor(mRgba, thresholdImage, Imgproc.COLOR_RGB2GRAY, 4);
Imgproc.Canny(thresholdImage, thresholdImage, 80, 100, 3);
Mat lines = new Mat();
int threshold = 50;
int minLineSize = 20;
int lineGap = 20;
Imgproc.HoughLinesP(thresholdImage, lines, 1, Math.PI/180, threshold, minLineSize, lineGap);
for (int x = 0; x < lines.cols(); x++)
{
double[] vec = lines.get(0, x);
double x1 = vec[0],
y1 = vec[1],
x2 = vec[2],
y2 = vec[3];
Point start = new Point(x1, y1);
Point end = new Point(x2, y2);
Core.line(mRgba, start, end, new Scalar(255,0,0), 3);
}
Bitmap bmp = Bitmap.createBitmap(getFrameWidth(), getFrameHeight(), Bitmap.Config.ARGB_8888);
if (Utils.matToBitmap(mRgba, bmp))
return bmp;
mIntermediateMat
画像に線を引きますが、mRgba
画像を返します。そのため、線が表示されません。
b
の-1000..1000の範囲は正しいです。 HoughLines
は、線の角度とゼロからの距離を返します(別名rhoおよびtheta)。それらを描画するには、それらを2点に変換する必要があります。 1000は画像のサイズです。2000x2000の画像に描画する場合は、2000に増やしてください。そうしないと、線が画像全体と交差しません。
HoughLines
はHoughLinesP
とは異なるアルゴリズムです。 HoughLines
は、画像全体を横切る線のみを検索します。 HoughLinesP
は、より短い線分を返します。
これがビジュアルスタジオの私のコードです。お役に立てば幸いです。
void drawLines(Mat &input, const std::vector<Vec2f> &lines) {
for (int i = 0; i < lines.size(); i++) {
float alpha = CV_PI/2-atan(input.rows/input.cols);
float r_max;
float r_min;
float r = lines[i][0];
float theta = lines[i][1];
if (theta<alpha || theta>CV_PI-alpha) {
r_max = input.cols*cos(theta);
r_min = input.rows*sin(theta);
if (r > r_max) {
Point pt1(input.cols, (r - input.cols*cos(theta)) / sin(theta));
Point pt2((r - input.rows*sin(theta)) / cos(theta), input.rows);
line(input, pt1, pt2, Scalar(255, 0, 0), 1);
}
else if (r < r_max && r > r_min) {
Point pt1(r / cos(theta), 0);
Point pt2((r - input.rows*sin(theta)) / cos(theta), input.rows);
line(input, pt1, pt2, Scalar(255, 0, 0), 1);
}
else {
Point pt1(r / cos(theta), 0);
Point pt2(0, r / sin(theta));
line(input, pt1, pt2, Scalar(255, 0, 0), 1);
}
}
else {
r_min = input.cols*cos(theta);
r_max = input.rows*sin(theta);
if (r > r_max) {
Point pt1(input.cols, (r - input.cols*cos(theta)) / sin(theta));
Point pt2((r - input.rows*sin(theta)) / cos(theta), input.rows);
line(input, pt1, pt2, Scalar(0, 0, 255), 1);
}
else if (r < r_max && r > r_min) {
Point pt1(input.cols, (r - input.cols*cos(theta)) / sin(theta));
Point pt2(0, r / sin(theta));
line(input, pt1, pt2, Scalar(0, 0, 255), 1);
}
else {
Point pt1(r / cos(theta), 0);
Point pt2(0, r / sin(theta));
line(input, pt1, pt2, Scalar(0, 0, 255), 1);
}
}
}
これが私が投稿したコードに関するロジックに関する2つのグラフです。
アルファの説明
R_max && r_minの説明