2012-08-15 61 views
4

我正在开发一个项目,在该项目中需要检测图像中的红色激光线。这是我想到的策略。使用OpenCV激光线检测

  1. 分离图像中的R,G,B通道。
  2. 阈值高强度值的图像。
  3. 使用所产生的3个二进制图像,执行元素方式操作R & &!克& &!湾(& &是逻辑AND,!是逻辑NOT)。
  4. 生成的矩阵是一个二进制图像,在激光所在区域有1。

这与Matlab上的一些测试图像。但我的问题是,这需要在C/C++中使用OpenCV来实现。

我试过了大部分库函数,但似乎没有直观/简单的方式处理二进制图像并对它们执行逻辑操作。

有人可以请我指出你认为我可能会觉得有用的OpenCV函数/方法吗?我认为cvThresholdImage可以用于阈值处理,但这非常关键。

+2

这可能更适合[DSP Stack Exchange](http://dsp.stackexchange.com/faq)。如果你认为它可能更适合,也许它会在那里迁移。首先检查。我不参加,所以我可能是错的。 (请勿交叉邮寄)。 – Bart 2012-08-15 15:40:53

+0

你能展示一个图片的例子吗?也真的考虑将此问题迁移到DSP,您的问题就是关于数字信号处理。 – ffriend 2012-08-15 17:27:03

+2

我可以看到这个问题在这里是如何适用的。据我了解,他并不是要求检测激光的技术,他已经开发了他的技术。他所要求的是关于使用openCV来实现该技术的信息。 – Hammer 2012-08-15 19:27:54

回答

3

那么你已经想出了openCV中的第1步和第2步呢?如果您只是试图使用逻辑运算符,openCV可让您访问原始数据,然后您可以使用逻辑运算符对其进行操作。假设您已经分成三个通道并且阈值为

//three binary images in the format you specified above 
cv::Mat g; 
cv::Mat b; 
cv::Mat r; 
uchar* gptr = g.data(); 
uchar* bptr = b.data(); 
uchar* rptr = r.data(); 

//assuming the matrix data is continuous you can just iterate straight through the data 
if(g.isContinuous()&&r.isContinuous()&&b.isContinuous()) 
{ 
    for(int i = 0; i < g.rows*g.cols; i++) 
    { 
    rptr[i] = rptr[i]&&!bptr[i]&&!gptr[i]; 
    } 
} 

r现在包含您描述的输出。如果你不想覆盖r,你也可以将它复制到一个新的矩阵中。

有几种方法可以遍历cv :: Mat并访问所有数据点,而C++提供了所有您可能需要的逻辑运算符。就我所知,openCV不提供矩阵逻辑运算符功能,但您可以非常方便地编写自己的代码,如上所示。

编辑 正如QuentinGeissmann所建议的,您可以使用bitwise_not和bitwise_and函数完成同样的事情。我不知道它们存在。我怀疑使用它们会比较慢,因为数据必须遍历遍历的次数,但可以用较少的代码完成。

cv::bitwise_not(g,g); 
cv::bitwise_not(b,b); 
cv::bitwise_and(b,g,b); 
cv::bitwise_and(r,b,r); 
//r now contains r&&!b&&!g 
+0

锤子,谢谢你的回应。是的 - 这几乎是我正在寻找的东西。将在此工作并回复你。你建议使用cv :: Mat而不是IplImage? – tetradeca7tope 2012-08-16 16:35:36

+1

@ tetradeca7tope这实在只是一个偏好问题。 cv :: Mat是另一个来自C接口的新的C++接口。我只有C++的经验,所以我不能真正告诉你有关差异。我听说你应该避免混合它们,所以如果你已经致力于Iplimage,也许你应该坚持。你可以直接访问它的.imageData,而不是.data,用于cv :: Mat – Hammer 2012-08-16 16:41:41

+0

直观地说,使用cv :: bitwise_not /和...的速度要慢一些,如果最终结果是“最适合你”尝试两个:) – 2012-08-16 19:08:14