首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >激光线检测opencv

激光线检测opencv
EN

Stack Overflow用户
提问于 2015-01-07 10:20:03
回答 1查看 4K关注 0票数 5

我想探测到一个自动系统的激光线。

到目前为止,我的工作是: 1.在rgb通道中分割图像;2.只使用红色通道,因为使用了红色激光线;3.手动获取阈值;4.搜索二进制图像中的值!= 0

对于自动化系统的用例,我不能手动地将其阈值化,有什么想法可以解决这个问题吗?

而且仅仅搜索图像中的最高峰是不够好的,因为阳光的影响。

也许我可以搜索短峰..。因为在激光线的区域内,亮度增加很快,然后在激光线后迅速下降。

我如何在opencv中意识到这一点?

EN

回答 1

Stack Overflow用户

发布于 2015-01-07 17:37:08

更新的

好的,我看了你最新的照片。我的算法可以归结为以下步骤。

  • 在图像中找到最亮的柱(即激光线)
  • 在最亮的柱中找到暗隙
  • 寻找激光线间隙中最亮的相邻柱

步骤1-在图像中找到最亮的柱(即激光线)

最简单的方法是压缩图像,使其仍然是原来的宽度,但只有一个像素高,有效地平均每个垂直列中的像素。然后应用-auto-level进行对比,将其扩展到0-255的整个范围,阈值为95%,以找到最亮的5%以内的所有列。然后寻找已经阈值化为白色的像素(#ffffff)。这是ImageMagick中的一行,如下所示:

代码语言:javascript
复制
convert http://i.stack.imgur.com/1P1zj.jpg -colorspace gray \
    -resize x1!                                             \
    -auto-level                                             \
    -threshold 95% text: | grep -i ffffff

输出:

代码语言:javascript
复制
297,0: (255,255,255)  #FFFFFF  white
298,0: (255,255,255)  #FFFFFF  white
299,0: (255,255,255)  #FFFFFF  white

所以,我现在知道297-299列是激光线的部分。请注意,如果图片稍微旋转,或者激光不是垂直的,则明亮的列将被分割成多个列。为了抵消这一点,您可以将图像的宽度缩小2到3倍,这样相邻的列往往在较小的图像中合并为一列,然后将该列乘以收缩因子以找到原始位置。

这就完成了步骤1,但是在步骤2之前有一个替代方法。

我将图像分割成1像素宽的列,其中包括:

代码语言:javascript
复制
convert input.png -crop 1x +repage line%d.png

现在,我发现最亮的列(一个具有最高平均亮度)具有:

代码语言:javascript
复制
for f in line*; do m=$(convert -format "%[fx:mean]" $f info:);echo $m:$f ;done | sort -g

这给了

代码语言:javascript
复制
...
...
0.559298:line180.png
0.561051:line185.png
0.561337:line306.png
0.562527:line184.png
0.562939:line183.png
0.584523:line295.png
0.590632:line299.png
0.644543:line296.png
0.671116:line298.png
0.71122:line297.png      <--- brightest column = 297

步骤2-在最亮的列中找到暗隙

现在我取297列,自动调整它,所以最暗的部分变成零,最轻的部分变成白色,然后我否定它。

代码语言:javascript
复制
convert line297.png -colorspace gray -auto-level -threshold 20% -negate txt:

...
0,100: (0,0,0)  #000000  black
0,101: (0,0,0)  #000000  black
0,102: (0,0,0)  #000000  black
0,103: (0,0,0)  #000000  black
0,104: (0,0,0)  #000000  black
0,105: (0,0,0)  #000000  black
0,106: (0,0,0)  #000000  black
0,107: (0,0,0)  #000000  black
0,108: (255,255,255)  #FFFFFF  white  <- gap in laser line
0,109: (255,255,255)  #FFFFFF  white  <- gap in laser line
0,110: (255,255,255)  #FFFFFF  white  <- gap in laser line
0,111: (255,255,255)  #FFFFFF  white  <- gap in laser line
0,112: (0,0,0)  #000000  black
0,113: (0,0,0)  #000000  black
...
0,478: (0,0,0)  #000000  black
0,479: (0,0,0)  #000000  black

步骤3-在激光线中寻找最亮的相邻柱

现在,如果我把这个列和它的两边的每一个列相乘,所有不在激光线间隙中的其他列的所有部分都会变成零,而在激光线的空隙中的所有部分都会被乘以,并且在我穿过第297列的任何一侧的时候,所有的部分都会被相加起来。

因此,我检查列240到340,将每一列与前一步的掩模相乘,看看哪一列在激光线的间隙中最亮:

代码语言:javascript
复制
for i in {240..340} ;do n=$(convert line${i}.png mask.png -compose multiply -composite -format "%[mean]" info:);echo $n:$i ;done | sort -g

产出如下:

代码语言:javascript
复制
458.495:248
466.169:249
468.668:247
498.294:260
502.756:250
536.844:259
557.726:258
564.508:251
624.117:252
627.508:253  <--- column 253 is brightest

然后我可以看到253列是激光线最暗的区域中最亮的。所以移位的线在253列。

我确信在opencv中可以很容易地完成这项技术。

原始答案

我可以告诉您一种方法,但不给您任何opencv代码,因为我倾向于使用ImageMagick。我将图像分割成一系列垂直图像,每幅图像宽1像素,即单像素列。然后,我得到所有列的平均亮度,并能立即看到最亮的列。它运行得很好,下面是我测试算法的方法:

代码语言:javascript
复制
Split image into single pixel columns
convert http://i.stack.imgur.com/vMiU1.jpg -crop 1x +repage line%04d.png

看看我们得到了什么:

代码语言:javascript
复制
ls line*
line0000.png    line0128.png    line0256.png    line0384.png    line0512.png
line0001.png    line0129.png    line0257.png    line0385.png    line0513.png
...
line0126.png    line0254.png    line0382.png    line0510.png    line0638.png
line0127.png    line0255.png    line0383.png    line0511.png    line0639.png

是的,640条垂直线。检查一下一个..。

代码语言:javascript
复制
identify line0639.png 
line0639.png PNG 1x480 1x480+0+0 8-bit sRGB 1.33KB 0.000u 0:00.000

是的,它宽1像素,高480像素。

现在求出所有线条的平均亮度,并按亮度排序:

代码语言:javascript
复制
for f in line*; do m=$(convert -format "%[fx:mean]" $f info:);echo $m:$f ;done | sort -g

输出

代码语言:javascript
复制
0.5151:line0103.png
0.521621:line0104.png
0.527829:line0360.png
0.54699:line0356.png
0.567822:line0355.png
0.752827:line0358.png  <--- highest brightness
0.76616:line0357.png   <--- highest brightness

第357和358栏似乎很容易被识别为你的答案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27817156

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档