Android OpenCV 绘制霍夫线

发布于 2024-12-12 12:11:05 字数 1341 浏览 1 评论 0原文

我正在尝试在 Android 手机上使用 OpenCV 来检测线条。我修改了“教程 1 基础 - 2. 使用 OpenCV 相机”示例。我还使用 霍夫线变换 作为示例。 然而,我得到了奇怪的数字(至少我认为是奇怪的数字)。 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;

I am trying to use OpenCV on an android phone to detect lines. I modified the 'Tutorial 1 Basic - 2. Use OpenCV Camera' sample. I am also using Hough Line Transform as an example.
However, I am getting weird numbers (at least what I believe to be weird numbers) for the points. In the range 1000 to -1000 for b.

I don't fully understand the code (mostly the part about adding/subtracting 1000 * (a or -b)).

In the end I do not see the lines at all.

Could anyone give me a hand? Also let me know if you need more information.

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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

窗影残 2024-12-19 12:11:05

我正在使用 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;

I am using HoughLineP to find lines in my frame and draw them back out.

Here is my code... hope this helps.

    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;
柳絮泡泡 2024-12-19 12:11:05

您将线条绘制到 mIntermediateMat 图像,但返回 mRgba 图像。这就是为什么你看不到线条的原因。

b 的 -1000..1000 范围是正确的。 HoughLines 返回从零开始的线角度和距离(又名 rhotheta)。要绘制它们,您需要将它们转换为两个点。 1000 是图像尺寸,如果您要绘制 2000x2000 图像,请将它们增加到 2000,否则线条将不会穿过整个图像。

HoughLinesHoughLinesP 是不同的算法。 HoughLines 仅查找穿过整个图像的线。 HoughLinesP 返回较短的线段。

You draw the lines to the mIntermediateMat image, but returning mRgba image. That's why you don't see the lines.

The -1000..1000 range for b is correct. HoughLines returns a line angle and distance from zero (a.k.a. rho and theta). To draw them, you need to convert them to two points. The 1000's are the image dimensions, if you would draw to a 2000x2000 image, increase them to 2000 or otherwise the lines will not cross the entire image.

HoughLines is different algorithm from HoughLinesP. HoughLines only finds lines, that cross the entire image. HoughLinesP returns shorter line segments.

从此见与不见 2024-12-19 12:11:05

这是我的 Visual Studio 代码,希望对您有所帮助。

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);
            }
    }

}

这是关于我发布的代码逻辑的两张图表。

alpha 的解释

alpha 的解释

r_max && 的解释r_min

r_max && r_min 的解释

Here is my code for visual studio, hope it helps.

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);
            }
    }

}

Here are 2 graphs about the logic about my code I posted.

The explanation of alpha

The explanation of alpha

The explanation of r_max && r_min

The explanation of r_max && r_min

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文