使用SimpleCV库的findBlob函数时Pygame出现分段错误
我一直在用SimpleCV来寻找可以用于自动驾驶机器人的图像块。问题出现在我调用SimpleCV中的findBlobs命令时。当我完全遮住Kinect摄像头的镜头时,PyGame就崩溃了,并给我报了这个错误:
致命的Python错误:(pygame降落伞)段错误
有时候它能正常工作,但有时候即使镜头没有被遮挡也会崩溃。通常在我运行超过大约三十秒的时候,它几乎总是会崩溃。我已经重新安装并修复了SimpleCV中的许多问题,还尝试重新安装Pygame,但似乎都没有帮助。此外,我使用的是X-Box的Kinect作为我的摄像头源。我正在使用Ubuntu 11.04。
这是我的确切代码:
from SimpleCV import *
from SimpleCV.Display import *
from time import sleep
k = Kinect()
dis = Display()
while 1:
depth = k.getDepth()
depth = depth.invert()
depth = depth.erode()
blobs = depth.findBlobs(threshval=127, minsize=10, maxsize=0)
if blobs:
blobs.draw()
depth.save(dis)
sleep(0)
4 个回答
致命的Python错误: (pygame降落伞) 段错误
这意味着某段代码崩溃了,现在你需要调试它来找出问题。我猜你正在学习一些东西;不妨顺便学一下如何调试 ;-)
有时候它能正常工作,但有时候却崩溃,即使镜头没有被挡住。当我运行超过大约三十秒时,它几乎总是会崩溃。
这些都是堆损坏或数据竞争的经典症状。
我已经重新安装并修复了SimpleCV中的许多问题,还尝试重新安装Pygame,但似乎没有帮助。
你为什么会认为这样做会有帮助呢?你的问题看起来根本就不是安装问题。
那么你该怎么做呢:在Linux上调试堆损坏问题的工具是valgrind。你可以这样运行它:
valgrind python your-code.py
不幸的是,默认的Python安装对Valgrind并不友好,上面的命令可能会产生很多“未初始化内存读取”的错误。你需要使用这个抑制 文件来抑制大部分错误。
你可能需要集中注意力在包含非Python部分的错误上(尤其是SimpleCV)。你要寻找的是 invalid {read,write} ... N bytes after block ...
。
如果你找到这样的错误,可以尝试用GDB进一步调试,或者向SimpleCV的开发者报告,希望能有所帮助。
如果没有找到错误,你可以构建一个对Valgrind友好的Python版本(说明),然后再试一次。
如果上述运行是Valgrind干净的,那么你可能遇到的是数据竞争,而不是堆损坏。可以使用 ThreadSanitizer 再次检查。
这里是SimpleCV的开发者Anthony:
你能试着改一下最后一行吗:
sleep(0.01)
这样做是想看看是不是有什么问题导致处理速度不够快。我最近升级到了Ubuntu 11.04,我觉得自从10.10版本以来,有几个Python的bug需要我解决。
另外,如果你能把这个问题发到我们的反馈区,我会很感激的:
http://github.com/ingenuitas/SimpleCV/issues
大家好,我是Kat,我写了SimpleCV的blob库。
在我们发布1.1版本后,发现这个blob库有几个问题。其中两个主要问题是:第一个是这个库会触发Python的最大递归深度限制,然后就停止运行了。第二个问题是来自底层的OpenCV封装,当blob生成器没有检测到任何blob时,会导致pygame出错。
现在的解决办法是使用我们GitHub仓库主分支上的版本。修复过的版本也会在本月底发布的新SimpleCV 1.2版本中提供。如果你想手动修复代码,我在下面贴了修复的代码片段:
在BlobMaker.py大约第55行
def extractFromBinary(self,binaryImg,colorImg, minsize = 5, maxsize = -1):
#fix recursion limit bug
sys.setrecursionlimit(1000000)
if (maxsize <= 0):
maxsize = colorImg.width * colorImg.height
retVal = []
#fix all black image bug
test = binaryImg.meanColor()
if( test[0]==0.00 and test[1]==0.00 and test[2]==0.00):
return FeatureSet(retVal)
seq = cv.FindContours( binaryImg._getGrayscaleBitmap(), self.mMemStorage, cv.CV_RETR_TREE, cv.CV_CHAIN_APPROX_SIMPLE)
retVal = self._extractFromBinary(seq,False,colorImg,minsize,maxsize)
del seq
return FeatureSet(retVal)