【问题标题】:HoughLines() - Drawing the lines and getting their positionHoughLines() - 绘制线条并获取它们的位置
【发布时间】:2016-02-16 05:36:28
【问题描述】:

我是 openCv 和一般图像处理的新手。我需要从这样的相机输入中实时绘制线条及其位置:

我已经有了来自精明边缘检测的图像,但是在应用霍夫线并尝试使用以下代码将其绘制到该图像时,我发现:

int main(int argc, char* argv[]){   
  Mat input;
  Mat HSV;
  Mat threshold;
  Mat CannyThresh;
  Mat HL;

 //video capture object to acquire webcam feed
 cv::VideoCapture capture;
 capture.open(0);
 capture.set(CV_CAP_PROP_FRAME_WIDTH, 640);
 capture.set(CV_CAP_PROP_FRAME_HEIGHT, 480);

 //start an infinite loop where webcam feed is copied to cameraFeed matrix
 //all operations will be performed within this loop

 while (true){ 

    capture.read(input);
    cvtColor(input, HSV, COLOR_BGR2HSV); //hsv
    inRange(HSV, Scalar(H_MIN, S_MIN, V_MIN), Scalar(H_MAX, S_MAX, V_MAX), threshold);//thershold
    MorphOps(threshold);//morph operations on threshold image
    Canny(threshold, CannyThresh, 100, 50); //canny edge detection

    std::vector<Vec4i> lines;
    HoughLines(CannyThresh, lines, 1, CV_PI/180, 150, 0, 0 );

    for( size_t i = 0; i < lines.size(); i++ )
    {
        float rho = lines[i][0], theta = lines[i][1];
        Point pt1, pt2;
        double a = cos(theta), b = sin(theta);
        double x0 = a*rho, y0 = b*rho;
        pt1.x = cvRound(x0 + 1000*(-b));
        pt1.y = cvRound(y0 + 1000*(a));
        pt2.x = cvRound(x0 - 1000*(-b));
        pt2.y = cvRound(y0 - 1000*(a));
        line( input, pt1, pt2, Scalar(0,0,255), 3, CV_AA);
    } 

    imshow("camera", input);
    waitKey(30);
    
  }
return 0;
}

我得到以下异常:

1- 我不能说我真的理解那个代码,但是你能告诉我为什么它不能工作吗?。

2- 如果我设法让它工作,我怎样才能得到水平线的 Y 坐标?我需要知道另一个物体是否在这个物体的内部、下方或上方。所以我需要这张图片上两条水平线在 Y 轴上的位置(检测到的粗线),这样我就可以确定另一个对象在这个“矩形”中的位置。

编辑 #1

我复制了完整的代码。正如您在第二张图片中看到的那样,调试器不会抛出任何错误。但在程序的控制台中显示OpenCV Error:Assertion failed (channels() == CV_MAT_CN(dtype)) in cv::Mat::copyTo, file C:\builds\master_packSlave-Win32-vc12-shared\opencv\modules\core\src\copy.cpp, line 281。调用堆栈中的最后一个调用也是这样的: &gt; KernelBase.dll!_RaiseException@16() Unknown,我开始认为是 opencv 问题而不是代码问题,可能是那个 dll 的问题。

编辑#2

我换行了

 std::vector<Vec4i> lines; // this line causes exception

 std::vector<Vec2f> lines;

现在它进入了 for 循环。但它现在给出了另一个运行时错误(另一个分段错误。我认为它与这些值有关:

我认为他们可能会超出范围,有什么想法吗?

【问题讨论】:

  • 使用调试器得到错误信息
  • 用调试器信息编辑。
  • 您可能在发行版中使用调试库,反之亦然。或使用其他编译器或体系结构(x86 与 x64)编译的库。

标签: c++ opencv image-processing real-time hough-transform


【解决方案1】:

我不确定,但这可能是因为您正在尝试画一条线,因为您有一个 3 通道图像(使用 Scalar(b,g,r)),但您真正拥有的是单通道图像(我想CannyThreshCanny() 的输出)。

您可以尝试使用以下方法将图像更改为彩色版本:

Mat colorCannyThresh = CannyThresh.clone();
cvtColor(colorCannyThresh, colorCannyThresh, CV_GRAY2BGR);

或者您可以使用Scalar([0~255]) 画一条线,将您的line() 调用更改为:

line(CannyThresh, pt1, pt2, Scalar(255), 3, CV_AA);

同样,由于它不是一个完整的代码,我不确定情况是否如此,但它可能是。

关于问题2,“水平线的Y坐标”是什么意思?

编辑

inRange()之后,threshold是一个Mat,大小与HSV和CV_8U类型(inRange())相同,即CV_8U*3(3通道->H.S.V)。你确定threshold,在MorphOps()之后,是CV_8U*1(单通道),还是Canny() expects

如果您的目标是查找矩形内的内容,您可能需要阅读minAreaRect()

【讨论】:

  • 谢谢你的回答,我会检查的。我用更多信息编辑了第二个问题
  • 我试过你说的,可惜没用,还有什么办法吗?
  • 用调试器信息编辑,并完成代码
  • @angel208 编辑了答案。你能不能说一下程序在哪一行崩溃了?
  • 就在for( size_t i = 0; i &lt; lines.size(); i++ ),如果我删除所有循环,程序运行正常,我什至可以显示精明的图像。即使我评论循环内的所有内容,它也会崩溃。再次,调试器没有抛出任何错误,问题是当我执行程序时,它就像一个分段错误。
猜你喜欢
  • 2022-01-16
  • 2013-05-03
  • 2021-11-19
  • 1970-01-01
  • 1970-01-01
  • 2018-03-15
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
相关资源
最近更新 更多