我是openCv和图像处理的新手。我需要从相机输入中实时绘制线条及其位置,如下所示:
我已经拥有来自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;
}
1-我不能说我真的明白那段代码,但是你能告诉我它为什么不起作用吗?
2-如果我设法让它工作,我怎样才能获得水平线的Y坐标?我需要知道另一个物体是否在这个物体的内部,下方或上方。所以我需要在这张图片上的2条水平线的Y轴上的位置(检测到的粗线),所以我可以确定另一个对象的位置&#34;矩形&#34;。
我复制了完整的代码。正如您在第二张图片中看到的那样,调试器不会抛出任何错误。但是在程序的控制台中它显示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。
我改变了行
std::vector<Vec4i> lines; // this line causes exception
代表
std::vector<Vec2f> lines;
现在它进入for循环。但它现在给出另一个运行时错误(另一个分段错误。我认为它与这些值有关:
我认为他们可能会偏离范围,任何想法?
答案 0 :(得分:0)
我不确定,但可能是因为你有一个3通道图像(使用Scalar(b,g,r)
),你可能会尝试绘制一条线,但你真正拥有的是什么是一个单通道图像(我想CannyThresh
是Canny()的输出。)
您可以尝试使用以下内容将图像更改为彩色版本:
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)。您确定threshold
后MorphOps()
是CV_8U * 1(单通道),Canny() expects吗?
如果您的目标是查找矩形内的内容,则可能需要阅读minAreaRect()。