2016-03-20 1 views
20

Я пытаюсь получить угловые точки из неподвижного изображения, используя GPUImageHarrisCornerDetectionFilter.Как получить углы с помощью 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 
} 

Эта функция всегда возвращает [] так что, очевидно, не работает.

Интересная деталь. Я собрал проект FilterShowcaseSwift из примеров GPUImage, и фильтр не смог найти очень четкие углы, как на листе бумаги на черном фоне.

+1

Что касается отсутствия обнаружения ясных углов, то угловой детектор Харриса не является инвариантом по шкале, поэтому более высокое разрешение изображения, тем резче угол, который он будет искать. «BlurRadiusInPixels», «чувствительность» и «порог» могут быть настроены с заданным разрешением, чтобы вытащить больше или меньше углов, но вы также можете поэкспериментировать с уменьшением разрешения изображений, поступающих в детектор, масштабные углы. Текущая реализация также ограничена максимум 256 углами, поэтому, если все они обнаружены в левом верхнем углу изображения, больше не будет сообщено. –

ответ

4
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]))) 
    } 
} 

Этот код, который у вас здесь, содержит блок, который вызывается каждый кадр.

Это асинхронный процесс, поэтому, когда ваша функция возвращается, которая еще не была вызвана, а ваш массив должен всегда быть пустым. Он должен вызываться после завершения обработки кадра.

Чтобы проверить это, установите контрольную точку внутри этого блока и посмотрите, вызвана ли она.

Предупреждение от Брэда Ларсона (создатель GPUImage) в комментариях:

GPUImage создать здесь stillImageSource будут высвобождены после этой функции выходов и может привести к аварии в этом случае.

+0

Да, это правда. Я фактически попытался напечатать точки из цикла for в одной точке, однако фильтр не смог обнаружить углы в тестовом изображении, которое я использовал, поэтому я пропустил это. – henrikstroem

+1

Технически это называется после любого обработанного кадра, независимо от того, были ли обнаружены углы. Вы правы в том, что метод -processImage GPUImagePicture запускает задание на обработку в очереди отправки фона, которая, скорее всего, не будет завершена до выхода этой функции. Это также означает, что GPUImagePicture, определенная локально в этой функции, будет освобождена до завершения обработки, что может привести к сбоям, если вы не будете осторожны. У меня была синхронная версия этой операции один раз, но не помню, почему я ее удалил. Может быть, тупики? –

+0

Спасибо за то, что бросил с некоторым разъяснением @BradLarson! Я обновил информацию, которую вы предоставили. :] – Jack

Смежные вопросы