2016-03-20 13 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 
} 

この関数は常に[]を返すので、それは明らかに働いていません。

興味深い詳細 - 私はGPUImageの例からFilterShowcaseSwiftプロジェクトをコンパイルしました。フィルターは黒い背景の紙のように非常に鮮明なコーナーを見つけることができません。

+1

明確なコーナーが見つからないことに関して、Harrisコーナー検出器はスケール不変ではないため、画像が高解像度であるほど、より鮮明なコーナーが検索されます。 'blurRadiusInPixels'、' sensitivity'、 'threshold'は、指定された解像度で微調整してより多くのコーナーを引き出すことができますが、検出器に入る画像の解像度を下げて実験して、大規模なコーナー。現在の実装では、最大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

技術的には、コーナーが検出されたかどうかに関わらず、処理されたフレームの後に呼び出されます。 GPUImagePictureの-processImageメソッドは、バックグラウンドディスパッチキューの処理ジョブを起動します。このジョブは、この関数が終了する前に完了していない可能性が非常に高いです。つまり、この関数でローカルに定義されたGPUImagePictureは、処理が完了する前に割り当てが解除されるため、注意しないとクラッシュする可能性があります。私はこの操作の同期バージョンを一度持っていましたが、なぜそれを削除したのか覚えていません。デッドロック、多分? –

+0

@BradLarsonの説明をお寄せいただきありがとうございます!私はあなたが提供した情報を更新しました。 :] – Jack

関連する問題