【问题标题】:How to get corners using GPUImageHarrisCornerDetectionFilter如何使用 GPUImageHarrisCornerDetectionFilter 获取角点
【发布时间】:2016-03-20 15:24:53
【问题描述】:

我正在尝试使用GPUImageHarrisCornerDetectionFilter 从静止图像中获取角点。

我查看了项目中的示例代码,查看了文档,还查看了这篇文章,内容大致相同: GPUImage Harris Corner Detection on an existing UIImage gives a black screen output

但我无法让它工作 - 我很难理解它应该如何处理静止图像。

我现在拥有的是:

func harrisCorners() -> [CGPoint] {
    var points = [CGPoint]()

    let stillImageSource: GPUImagePicture = GPUImagePicture(image: self.image)
    let filter = GPUImageHarrisCornerDetectionFilter()

    filter.cornersDetectedBlock = { (cornerArray:UnsafeMutablePointer<GLfloat>, cornersDetected:UInt, frameTime:CMTime) in
        for index in 0..<Int(cornersDetected) {
            points.append(CGPoint(x:CGFloat(cornerArray[index * 2]), y:CGFloat(cornerArray[(index * 2) + 1])))
        }
    }

    filter.forceProcessingAtSize(self.image.size)
    stillImageSource.addTarget(filter)
    stillImageSource.processImage()

    return points
}

这个函数总是返回[],所以它显然不起作用。

一个有趣的细节 - 我从 GPUImage 示例编译了 FilterShowcaseSwift 项目,但过滤器无法找到非常清晰的角落,就像在黑色背景上的一张纸上一样。

【问题讨论】:

  • 由于无法找到清晰的角点,Harris角点检测器不是尺度不变的,因此图像分辨率越高,它会寻找的角点越清晰。 blurRadiusInPixelssensitivitythreshold 可以在给定的分辨率下进行调整,以拉出更多或更少的角落,但您也可以尝试降低进入检测器的图像的分辨率,让它们拾取更大的图像——缩放角。当前的实现也被限制为最多 256 个角,因此如果在图像的左上角检测到所有这些角,则不会报告更多。

标签: ios swift2 gpuimage


【解决方案1】:
filter.cornersDetectedBlock = { (cornerArray:UnsafeMutablePointer<GLfloat>, cornersDetected:UInt, frameTime:CMTime) in
    for index in 0..<Int(cornersDetected) {
        points.append(CGPoint(x:CGFloat(cornerArray[index * 2]), y:CGFloat(cornerArray[(index * 2) + 1])))
    }
}

您在此处的这段代码设置了一个在每一帧都被调用的块。

这是一个异步过程,因此当您的函数返回时,它从未被调用过,并且您的数组应该始终为空。它应该在帧完成处理后调用。

要验证这一点,请在该块内设置一个断点并查看它是否被调用。

来自 cmets 中 Brad Larson(GPUImage 的创建者)的警告:

您在此处创建的 GPUImage stillImageSource 将在此函数退出后被释放,在这种情况下可能会导致崩溃。

【讨论】:

  • 是的,这是真的。我实际上尝试在某个点从 for 循环内部打印点,但是过滤器无法检测到我正在使用的测试图像中的角点,所以我错过了。
  • 从技术上讲,无论是否检测到角,都会在任何处理过的帧之后调用。没错,GPUImagePicture 的 -processImage 方法会在后台调度队列上触发处理作业,该作业很可能在此函数退出之前不会完成。这也意味着在这个函数中本地定义的 GPUImagePicture 将在处理完成之前被释放,如果你不小心可能会导致崩溃。我曾经有过这个操作的同步版本,但不记得我为什么删除它。也许是死锁?
  • 感谢@BradLarson 的澄清!我已经更新了您提供的一些信息。 :]
猜你喜欢
  • 2014-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-23
  • 1970-01-01
  • 2020-01-19
  • 2012-09-03
  • 1970-01-01
相关资源
最近更新 更多