HoughLines() - 绘制线条并获得它们的位置

时间:2015-11-14 20:35:32

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

我是openCv和图像处理的新手。我需要从相机输入中实时绘制线条及其位置,如下所示: enter image description here

我已经拥有来自canny边缘检测的图像,但是当应用hough线并尝试使用以下代码将其绘制到该图像时,我发现:

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

我收到以下异常: enter image description here

1-我不能说我真的明白那段代码,但是你能告诉我它为什么不起作用吗?

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

编辑#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。调用堆栈中的最后一个调用是这样的:> KernelBase.dll!_RaiseException@16() Unknown,我开始的东西是一个opencv问题,而不是代码问题,可能是那个dll。

编辑#2

我改变了行

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

代表

 std::vector<Vec2f> lines;

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

我认为他们可能会偏离范围,任何想法?

1 个答案:

答案 0 :(得分:0)

我不确定,但可能是因为你有一个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);

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

关于Question2,你的意思是&#34;水平线的Y坐标?&#34;

修改

inRange()之后,threshold是与Mat大小相同的HSV和CV_8U类型(inRange()),这意味着它是CV_8U * 3 (3通道 - > HSV)。您确定thresholdMorphOps()是CV_8U * 1(单通道),Canny() expects吗?

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