我使用以下代码来尝试检测边界蓝框线:
GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:rawImage]; GPUImageHoughTransformLineDetector *lineFilter = [[GPUImageHoughTransformLineDetector alloc] init]; [stillImageSource addTarget:lineFilter]; GPUImageLineGenerator *lineDrawFilter = [[GPUImageLineGenerator alloc] init]; [lineDrawFilter forceProcessingAtSize:rawImage.size]; __weak typeof(self) weakSelf = self; [lineFilter setLinesDetectedBlock:^(GLfloat *flt,NSUInteger count,CMTime time) { NSLog(@"Number of lines: %ld",(unsigned long)count); GPUImageAlphaBlendFilter *blendFilter = [[GPUImageAlphaBlendFilter alloc] init]; [blendFilter forceProcessingAtSize:rawImage.size]; [stillImageSource addTarget:blendFilter]; [lineDrawFilter addTarget:blendFilter]; [blendFilter useNextFrameForImageCapture]; [lineDrawFilter renderLinesFromArray:flt count:count frameTime:time]; weakSelf.doneProcessingImage([blendFilter imageFromCurrentFramebuffer]); }]; [stillImageSource processImage];
无论edgeThreshold还是1023行,每次运行此命令时,结果输出如下所示:
我不清楚为什么改变门槛没有做任何事情,但我确信我误解了一些事情.任何人对如何做到这一点有任何想法?
解决方法
让我解释这个操作是如何工作的.首先,它检测图像中的边缘.对于确定为边缘的每个像素(现在,我正在使用Canny边缘检测器),提取该像素的坐标.然后使用这些坐标中的每一个在平行坐标空间中绘制一对线(基于Dubská等人在“Real-Time Detection of Lines using Parallel Coordinates and OpenGL”中描述的过程).
线条相交的平行坐标空间中的像素强度会增加.平行坐标空间中最大强度的点表示现实世界场景中存在一条线.
但是,只有强度为局部最大值的像素才表示实线.挑战在于确定局部最大值以抑制来自繁忙场景的噪声.这就是我在这次行动中没有完全解决的问题.在上面的图像中,大量的线条是由于在平行坐标空间中一堆点高于检测阈值,但由于不是局部最大值而未被正确移除.
不过我确实做了一些改进,所以我现在从操作中获得了更清晰的输出(我刚从屏幕的实时视频输入中快速完成了这个):
我在本地非最大抑制滤波器中修复了一个错误,并将其工作区域从3×3扩展到5×5.它仍然留下一堆非最大点,这些点会导致噪音,但它会好得多.
你会注意到这仍然不是你想要的.它在文本中拾取线条,但不是你的盒子.这是因为白色背景上的黑色文字在边缘检测阶段产生非常强烈,非常锐利的边缘,但是白色背景上的浅蓝色选择框需要极低的阈值甚至在任何边缘检测过程中被拾取.
如果您总是要选择一个蓝色选择框,我建议您运行预处理操作以唯一地识别场景中的蓝色对象.一种简单的方法是定义一个自定义滤镜,为每个像素从蓝色中减去红色分量,将负值置于地板上,并将该计算的结果作为红色,绿色和蓝色通道的输出.您甚至可能希望将结果乘以2.0-3.0以加强这种差异.
结果应该是图像中图像中的蓝色区域显示为白色而其他任何位置显示为黑色的图像.这将大大提高您选择框周围的对比度,并使其更容易从文本中挑选出来.您需要尝试使用正确的参数,以使其在您的情况下尽可能可靠.