半哑铃状图象识别——要求高精度优化算法【诚邀各位斑竹各位豪杰共同探讨研究】

清晨曦月
博客专家认证
2008-03-09 09:56:47
希望高手不吝赐教!!
情况是这样的:
有若干幅连续的图象——一个半哑铃形的存在渐变色的运动(平动加转动)物体各个时刻的照片,背景颜色复杂且不同时刻不同,我希望准确识别出这个半哑铃形物体的球部分的中心。我已经实现了该图象背景的严格的过滤函数,调用该函数即可严格区分背景和该物体边缘。该图象大约800*600象素。
简化后的问题:
1、800*600象素的纯黑色背景图片上,某位置有一个半哑铃形(0==0的一半0=)物体,该物体在图片上是完整的,但有恰好在边缘的情况。
2、该物体球部分实际为正圆,但在图片上与背景存在过度象素。
3、该物体柄部分为圆柱体,图象上呈现为矩形,但这个矩形的两边并不一定平行于计算机屏幕的X、Y轴。
4、该物体圆部分及柄与圆结合部分为白色,柄另一端为棕色,中间为过度色(实际图上柄小而球大,柄大约3象素宽,球半径15):
白白 白色与棕色过度 棕
0=====================
要求:
给出识别该物体圆球部分的中心即图片上的圆的圆心算法;算法误差小于0.05象素,耗时小于50毫秒。



...全文
364 43 打赏 收藏 举报
写回复
43 条回复
切换为时间正序
请发表友善的回复…
发表回复
ttsffgg 2008-03-31
  • 打赏
  • 举报
回复
把这个作为中考数学最后一题!!!
清晨曦月 2008-03-30
  • 打赏
  • 举报
回复
不错!高手年年见啊,今年特别多啊。。。。。。。。。。。。
Tiger_Zhao 2008-03-26
  • 打赏
  • 举报
回复
首先扫描出一个外接矩形,那么矩形与物体的接触部分有以下几种情况
·3个点,1条线段
·4个点
·5个点
·根据哑铃柄的长短变化可能有6个点
总之将线段抛弃,只留下接触点,那么球体与外接矩形至少有两个接触点。

以最典型的4个点(下图)为例:
分别做经过接触点A、B、C、D并且与矩形边垂直的执行,这些直线在矩形内相交与点O1、O2、O3、O4,那么球心必定是这些交点之一。
用排除法直到只剩下一个点:
·球心必定在物体内(白色)——排除O2、O4
·球心到接触点距离相同(AO1=BO1,CO3=DO3)——不一定排除O3
·接触点与球心的对称点(如A'、B')必定为边界点——这个判断比较麻烦,而且不做也可以
·如果剩下多个点(只有哑铃柄的倾斜度±40°时发生),那么取到接触点(也就是外接矩形)距离大的点。

ttsffgg 2008-03-25
  • 打赏
  • 举报
回复
[Quote=引用 34 楼 jennyvenus 的回复:]
异色就是不是背景的,也就是白的。呵呵,从左到右扫描一行颜色,遇到黑色的背景色++,其他的前景色++,多行下来,前景色最多的就是球心的Y坐标。

[/Quote]
如果那个柄是横着的 又正好横向扫描到柄?
ttsffgg 2008-03-25
  • 打赏
  • 举报
回复
一个窗体
一个pictutrbox 打开autosize 和autoredraw
手动载入pictutrbox 的图像 这里以上面贴出来的图为例子 并且只处理黑白两种颜色 需要把图片弄干净点,把杂色去掉

Private Declare Function GetPixel _
Lib "gdi32" (ByVal hdc As Long, _
ByVal X As Long, _
ByVal Y As Long) As Long

Private Declare Function SetPixel _
Lib "gdi32" (ByVal hdc As Long, _
ByVal X As Long, _
ByVal Y As Long, _
ByVal crColor As Long) As Long

Const pi = 3.141592654

Const D As Long = 86 '圆直径单位,像素

Const P As Long = 28 '圆直径的三分之一,单位,像素

Const L As Long = 130 '圆中心到柄末大概的距离,单位,像素

Dim i As Long, j As Long '循环用临时变量

Dim H As Long, W As Long '存放图片的宽高, 读取变量比读取控件属性快很多.....

Dim pHdc As Long '存放图片的场景, 读取变量比读取控件属性快很多.....

Dim r As Long '存放返回的颜色

Dim p1x As Long, p1y As Long '粗略算出的第一点

Dim bx As Long, by As Long '粗略算出的柄的端的点

Dim ex As Long, Ey As Long '最后得到的精确中心点

Private Sub cmdCommand1_Click()

H = Picture1.Height / 15
W = Picture1.Width / 15

pHdc = Picture1.hdc

For i = 0 To H Step P
For j = 0 To W Step P
r = GetPixel(pHdc, j, i)

If r <> 0 Then
If GetPixel(pHdc, j + P, i) <> 0 And GetPixel(pHdc, j, i + P) <> 0 And GetPixel(pHdc, j, i - P) <> 0 And GetPixel(pHdc, j - P, i) <> 0 Then
p1x = j: p1y = i '粗略的算出了大概的位置,误差在三分之一的直径以内

GoTo b:
End If
End If

Next
Next

b:

For i = 1 To 359 Step 6 '找出相对于大概的圆心,柄端的位置
bx = p1x + L * Sin(i * pi / 180)
by = p1y + L * Cos(i * pi / 180)

If GetPixel(pHdc, bx, by) <> 0 Then
Call SetPixel(pHdc, bx, by, &HFF&)

Exit For

End If

Next

If bx > p1x Then
If by > p1y Then '柄端在右下方时

For i = p1x To 0 Step -1

If GetPixel(pHdc, i, p1y) = 0 Then
ex = ((D / 2) - (p1x - i)) + p1x

Exit For

End If

Next

For i = p1y To 0 Step -1

If GetPixel(pHdc, p1x, i) = 0 Then
Ey = ((D / 2) - (p1y - i)) + p1y

Exit For

End If

Next

Else

'柄端在右上方时 '懒得写了
End If

Else

If by > p1y Then
'在左下方

Else

'在左上方

End If
End If

Call SetPixel(pHdc, ex, Ey, &HFF&)
Picture1.Refresh

End Sub
清晨曦月 2008-03-25
  • 打赏
  • 举报
回复
就到这里吧。。。。。讨论结束。。。朋友给了一个核心DLL,问题很圆满的解决了。。。。虽然是DLL……


楼上所说我实在没有办法帮助你,因为这方面我也是初学。0.05个像素是能达到的,甚至有的要求精度更高,我用的是彩色的图片,我涉及的方法都是没有经过二值化的,而且都没有读整个图片的全部像素,省去了这个过程,因为我感觉很耗时,采用的方法是比较像素的差异,不过是一个突发奇想得到的比较方式而已,实际上效率比网上常见的比较方式速度要低一些,但是适应性非常好。。。关于你说的变形,正是造成误差的一个主要原因,我的解决思路是利用对称性,无论变形成什么样,只要变形是对称的就可以确定中心。

晚上回家结贴,在办公室不好长时间上
cquyyang 2008-03-25
  • 打赏
  • 举报
回复
LZ你好,今天我是第一次听说了 种子填充算法, 大略的在CNKI上搜罗了一些论文看了,但是看的不是很明白,特别是快速行进法。大概的实现原理可否告知,在此谢过了,我的邮箱是cquyyang@yahoo.com.cn。

本人愚钝,有一点疑问,还麻烦LZ告知一二:我看了一些基本的种子填充算法,需要判断种子周边连通像素是否在区域内,对此判断是否会有信息丢失?造成图像成像变形,特别在RGB变化的情况下。

LZ想精确到0.05个像素,在这种情况下,这个指标我觉得很恐怖。
原因有一下几点:
1.图像采集设备自身的噪声影响,会导致物体图像形状有变化(LZ应该是将图像二值化了吧)。我曾用过灰度矩检测物体边缘,而后最小二乘法拟合直线交点(距物体边缘约500个像素),在此情况下拟合误差都在2个像素以内。
2.光学系统的畸变。这个畸变会导致在不同位置的物体形状不一样。不知道LZ使用摄像机标定到了几阶,常用校正只校正了1阶,并且还是径向校正。同时光学系统的设计时所谓的校正,并不是全场校正,只是在部分位置校正了的。

LZ说边缘存在渐变,这是很正常的。艾利斑的大小可能影响了周边像素,即光学系统的分辨率可能低于你的采集设备分辨率。同时光学系统的7种像差也会导致边缘模糊。CCD或者CMOS自身的噪声也会造成,所以边缘模糊是正常的。

本人孤陋寡闻,在此还要向各位前辈学习。
forbearORfolie 2008-03-19
  • 打赏
  • 举报
回复
关注
清晨曦月 2008-03-19
  • 打赏
  • 举报
回复
啊。。这么个意思。。。。。。。。。。。。。。。。。。。。。。。。。传说那要逐行扫描。。。。。。。。
智能卡_Snooper 2008-03-18
  • 打赏
  • 举报
回复
异色就是不是背景的,也就是白的。呵呵,从左到右扫描一行颜色,遇到黑色的背景色++,其他的前景色++,多行下来,前景色最多的就是球心的Y坐标。
清晨曦月 2008-03-18
  • 打赏
  • 举报
回复
实际上我的程序是VB 2005写的,.NET区里面人气太NB了,没敢去。。。.NET下获取颜色速度还可以。。。。

找到每行、列,异色点最多的............我没理解上去。。。。。。。。。。。。。。。。。。。。
异色是什么意思。。
智能卡_Snooper 2008-03-18
  • 打赏
  • 举报
回复
我最开始想的是扫描线的方法,先用固定步长,从上到下扫,800*600的需要扫描60条线,每线至少80个点,以确定半球的最大位置,由于vb的point实在太慢,直接搜索内存又不在行,所以一直没进一步研究。

后来看了看边沿检索,又不知道检索出的边沿到底存到了什么地方。

按俺的想法,
1)用扫描的方法来决定大概的位置,由于找到半球的大概位置之后,后面的数据就不用再扫描,两次扫描可以以上次的为基准,所以速度也可能不慢。
此步结果,假如球在100, 100,半径为15的话,可能得到的位置为(90, 90), ( 110, 90),(90, 110), (110,90)4个点异色。由此得到球心在此4点组成的矩形中。
2)用二分法分别在前面选中的矩形中扫描,找到每行、列,异色点最多的。
清晨曦月 2008-03-18
  • 打赏
  • 举报
回复

我有一个想法,不知道行不行
这个半哑铃形状的球部分和其他球完全相同,如果通过其他球取得球边缘遍历的话,用这个边缘遍历去匹配这个半哑铃形状,匹配度最大的位置就是圆位置,从而确定圆心。。。。精确度应该是蛮高的。。。。。。。。

可惜我不知道如何匹配才好,甚至连边缘遍历的代码都没写过。。。。。。。。。。。。。。。。
清晨曦月 2008-03-18
  • 打赏
  • 举报
回复
..............效率和精确度在这里确实是矛盾。。。。
现在头很大,最初的模型上是有多个球体的除了这个半哑铃以外还有一些颜色和这个不一样的,实际上我已经把那些球体的球心准确的判断出来了,误差小于0.01(用双精度浮点算的),一共有这样的球40个,他们都是绿色的,这时耗时100毫秒多一点,当然在这判断过程中也识别到了这个半哑铃形状的东西,因为它不仅形状特殊,颜色也和其他的不一样。。。。。是白的。。
这个问题困扰我很长时间了,用了各种办法,判断这个半哑铃的时候精确度都不行(我写了一段程序生成一个类似的图,这时就知道准确的圆心了)

晕的要死啊
智能卡_Snooper 2008-03-17
  • 打赏
  • 举报
回复
捡的光盘倒没什么,估计市面上也就5块钱,楼主想要VC的代码俺可以发给你。
qiu5208 2008-03-17
  • 打赏
  • 举报
回复
学习中。。。。。。。。
forbearORfolie 2008-03-17
  • 打赏
  • 举报
回复
说个不成熟的想法:

既然,这个问题简化成了一幅二值静止图象,可不可以这样,
分别从四个方向扫描
1.从左至右逐列,从前至后逐行,和相反的两个方向
2.当在任何方向遇到第一个非黑的象素点时就保存坐标。
3.通过比较这四个点的坐标,(假设是正圆),
必定有两个点(扫描线与圆的切点)坐标符合下面两个表达式
x1-x2+(y1-y2)=0 或 x1-x2+(y2-y1)=0其中之一,所以圆心的坐标就是 x1>x2,?x1,x2;y1>y2,?y2,y1
我自己感觉太理想化了
清晨曦月 2008-03-16
  • 打赏
  • 举报
回复
四分法比 for x as inte =0 to w step 10要快吗。。。。。还是顺序执行。。。。
楼上思路还是找种子,然后。。。一直爬出来4个点,,,,,,,取距离相等的3个点,,而后解方程(x-a)^2+(y-b)^2=r^2。。。


。。。这个算法误差和我用的取种子,取横弦,得中点,从终点做纵弦纵弦中点即圆心(初步判断),若此圆心与四个交点距离不等则
取相等的三个点,求圆。。。。。


的思路效率差不多,精确度还是没有变化。。。。。。。
qiu5208 2008-03-15
  • 打赏
  • 举报
回复
LZ对速度的要求比较高,昨天研究了一下,
菜鸟再说两句.
1.找初始位置,可以用四分找法,
直接判断图片矩形的中点是否存在哑铃, 过这中点的横,纵,两条线可以把矩形分成4个小矩形.
再找4个小矩形的中点是否存在哑铃, 再把4小矩形一分成16个更小的矩形.
再判断,再分,递归这一过程即可.直到找到一个原始点.

2 .找出原始点后,以此点开始爬虫,找出最顶点,最左点,最右点,最下点.
举例,找最顶点,从原始点开始向上移动一个象素,不能上则左,不能左则右,就是不能下,和回头(原先走过的点)
同样,递归此过程即可.

3,找出4个极点后,看图片即可知道,不论图片如何旋转
一定有三个极点属于圆周上的点.判断出这三点应该不是难事.
4,三点确定一个圆,算出圆心.


ydlchina 2008-03-14
  • 打赏
  • 举报
回复
学习
加载更多回复(23)
相关推荐
发帖
API

1482

社区成员

VB API
社区管理员
  • API
加入社区
帖子事件
创建了帖子
2008-03-09 09:56
社区公告
暂无公告