使用 GPUImage 和 GPUImageHoughTransformLineDetector 检测突出显示的文本边界框

Posted

技术标签:

【中文标题】使用 GPUImage 和 GPUImageHoughTransformLineDetector 检测突出显示的文本边界框【英文标题】:Using GPUImage and GPUImageHoughTransformLineDetector to detect highlighted text bounding box 【发布时间】:2015-02-15 08:20:19 【问题描述】:

我正在使用 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 行,每次我运行它,结果输出如下所示:

我不清楚为什么更改阈值没有任何作用,但我确信我误解了一些东西。有人对如何最好地做到这一点有任何想法吗?

【问题讨论】:

【参考方案1】:

我刚刚对框架中的 Hough 变换线检测器进行了一些改进,这将有助于解决此问题,但您需要对图像进行一些额外的预处理才能仅挑选出那个蓝色框。

让我解释一下这个操作是如何工作的。首先,它检测图像中的边缘。对于确定为边缘的每个像素(现在,我为此使用 Canny 边缘检测器),提取该像素的坐标。然后使用这些坐标中的每一个在平行坐标空间中绘制一对线(基于 Dubská 等人在"Real-Time Detection of Lines using Parallel Coordinates and OpenGL" 中描述的过程,)。

线相交的平行坐标空间中的像素将增加强度。平行坐标空间中强度最大的点表示现实世界场景中存在一条线。

但是,只有强度局部最大值的像素表示真实线条。挑战在于确定局部最大值以抑制来自繁忙场景的噪声。这就是我在这次行动中没有完全解决的问题。在上图中,大量线是由于在平行坐标空间中高于检测阈值的点混乱,但由于不是局部最大值而没有被正确删除。

不过,我确实做了一些改进,因此我现在从操作中获得了更清晰的输出(我只是在屏幕上的实时视频源中快速完成了此操作):

我修复了局部非最大抑制滤波器中的一个错误,并将其工作区域从 3x3 扩展到 5x5。它仍然留下了一堆导致噪音的非最大值点,但它要好得多。

您会注意到这仍然不能满足您的要求。它在文本中拾取线条,但不是你的盒子。这是因为白色背景上的黑色文本在边缘检测阶段会产生非常强烈、非常锐利的边缘,而白色背景上的浅蓝色选择框需要极低的阈值才能在任何边缘检测过程中被拾取。

如果您总是要挑选蓝色选择框,我建议您运行预处理操作以唯一标识场景中的蓝色对象。一种简单的方法是定义一个自定义过滤器,该过滤器从每个像素的蓝色中减去红色分量,铺平负值并将计算结果作为红色、绿色和蓝色通道的输出。您甚至可能希望将结果乘以 2.0-3.0 以加强这种差异。

结果应该是图像中的蓝色区域显示为白色,其他地方显示为黑色。这将大大改善您的选择框周围的对比度,并使其更容易从文本中挑选出来。您需要尝试使用正确的参数,以使其在您的情况下尽可能可靠。

【讨论】:

好的,这非常有帮助。使用您对预过滤器的想法,然后我自己通过边缘检测过滤它,模糊半径为 5px,我能够得到这张感觉如此接近的图像:dl.dropboxusercontent.com/spa/zsb1h2lxmgrll8w/zz-6b7tc.png(这张图片中有 12 行)。我知道 LineFilter 已经对其进行了一次边缘检测,但为了确定,我想做一个预检测。我不确定它怎么可能没有检测到那张照片中的水平线。在那张照片中,我的 lineDetectionThreshold 是 0.3。 (我用的是master) @IanOwnbey - 我用于过滤掉一些噪声值的启发式算法中可能存在错误。查看 GPUImageHoughTransformLineDetector.m 的 -extractLineParametersFromImageAtFrameTime: 方法,其中我有“案例测试”cmets。我的逻辑可能在那里有缺陷。看看删除那些 if 条件(仅使用 else 情况)是否会使这更好。如果是这样,我可以删除该启发式。 好的,非常感谢,我只需要一个正确的方向:) 这是我这样做时的输出dl.dropboxusercontent.com/spa/zsb1h2lxmgrll8w/yqaot2q2.png,这似乎稍微好一点,但仍然是错误的。我将阅读您链接的论文,看看我是否真的可以让自己变得有用。 @IanOwnbey - 如果您将图像的非边缘检测版本输入霍夫变换线检测器会发生什么?线检测器的第一步是进行边缘检测,如果您已经将边缘送入其中,则可能会搞砸。如果您需要调整第一阶段的参数以匹配此处的边缘检测,您可以在该文件中的 Canny 边缘检测过滤器上执行此操作。您可以调整源以使参数与您在上面所做的一致(在某些时候,我应该将这些作为 Hough 操作的属性公开)。

以上是关于使用 GPUImage 和 GPUImageHoughTransformLineDetector 检测突出显示的文本边界框的主要内容,如果未能解决你的问题,请参考以下文章

使用 GPUImage 和 GPUImageHoughTransformLineDetector 检测突出显示的文本边界框

GPUImage的简单使用

GPUImage的简单使用

GPUImage过滤视频

图像处理库GPUImage简单使用

GPUImage框架导入到项目中的方法(转载)