我正在使用GPUImageHoughTransformLineDetector尝试检测图像中突出显示的文本:
我使用以下代码尝试检测边界蓝框线:
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行,结果输出如下:
我不清楚为什么改变门槛没有做任何事情,但我确信我误解了一些事情。任何人对如何做到这一点都有任何想法?
答案 0 :(得分:6)
我刚刚在框架中对Hough变换线检测器进行了一些改进,这将对此有所帮助,但是您需要对图像进行一些额外的预处理才能选出蓝色框。
让我解释一下这个操作是如何运作的。首先,它检测图像中的边缘。对于确定为边缘的每个像素(现在,我正在使用Canny边缘检测器),提取该像素的坐标。然后使用这些坐标中的每一个在平行坐标空间中绘制一对线(基于Dubská在"Real-Time Detection of Lines using Parallel Coordinates and OpenGL"中描述的过程,等。)。
线条相交的平行坐标空间中的像素强度会增加。平行坐标空间中最大强度的点表示现实世界场景中存在一条线。
但是,只有强度为局部最大值的像素才表示实线。挑战在于确定局部最大值以抑制来自繁忙场景的噪声。这就是我在这次行动中没有完全解决的问题。在上面的图像中,大量的线条是由于在平行坐标空间中一堆点高于检测阈值,但由于不是局部最大值而没有被正确删除。
我确实做了一些改进,所以我现在从操作中获得更清晰的输出(我刚从屏幕的实时视频输入中快速做到了这一点):
我修复了本地非最大抑制过滤器中的错误,并将其工作区域从3x3扩展到5x5。它仍然留下一堆非最大点,这些点会导致噪音,但它会好得多。
你会注意到这仍然不是你想要的。它在文本中拾取线条,但不是你的盒子。这是因为白色背景上的黑色文字在边缘检测阶段会产生非常强烈,非常锐利的边缘,但是白色背景上的浅蓝色选择框需要极低的阈值才能在任何边缘检测过程中被拾取。
如果您总是要挑选一个蓝色选择框,我建议您运行预处理操作以唯一地识别场景中的蓝色对象。一种简单的方法是定义一个自定义滤镜,为每个像素从蓝色中减去红色分量,将负值置于地板上,并将该计算的结果作为红色,绿色和蓝色通道的输出。您甚至可能希望将结果乘以2.0-3.0以加强这种差异。
结果应该是图像中图像中的蓝色区域显示为白色而其他任何位置显示为黑色的图像。这将大大提高您选择框周围的对比度,并使其更容易从文本中挑选出来。您需要尝试使用正确的参数,以使其在您的情况下尽可能可靠。