2016-05-09 70 views
1

我正在使用位於這裏的MetalVideoCapture示例https://github.com/FlexMonkey/MetalVideoCapture。我在版本改變的唯一的事情是使用MPSImageConvolution(而不是MPSImageGaussianBlur)與核心價值觀:在Metal計算着色器中使用MPSImageConvolution內核

[-2.0, -1.0, 0.0, 
-1.0, 1.0, 1.0, 
    0.0, 1.0, 2.0] 

使用值高於沒有改變任何可見的輸出方式。但一個邊緣增強內核例如

[0.0, -1.0, 0.0, 
0.0, 1.0, 0.0, 
0.0, 0.0, 0.0] 

工作,只介紹你的列主要順序;即使這是MPSImageConvolution所期望的,它也不能按行優先順序工作。我真的被這個難住了。我不知道是否有明顯的原因,卷積內核無法在計算管道中工作(僅在渲染管道中),但我無法在線上找到任何信息。

我還修改了代碼庫,將內核應用於靜態圖像而不是實時視頻源;然而,這產生了相同的結果。

我還想指出,我在示例項目的留言板上發佈了相同的問題(https://github.com/FlexMonkey/MetalVideoCapture/issues/1#issuecomment-217609500)。這個例子的作者同樣和我一樣難過,這導致我相信這是我的概念知識中的某種缺陷或差距,甚至認爲這甚至不能工作。

回答

2

我有一個解決方法,這是爲了避免使用就地紋理。試試這個:創建一個單獨的目標質地:

let descriptor = MTLTextureDescriptor.texture2DDescriptorWithPixelFormat(
     drawable.texture.pixelFormat, 
     width: drawable.texture.width, 
     height: drawable.texture.height, 
     mipmapped: false) 

    let destination: MTLTexture = device!.newTextureWithDescriptor(descriptor) 

YCbCrColorConversion着色器瞄準目標:

commandEncoder.setTexture(destination, atIndex: 2) // out texture 

...然後使用使用目的地替代encodeToCommandBuffer

encodeToCommandBuffer(commandBuffer, sourceTexture: destination, destinationTexture: drawable.texture) 

這東西可以刪除:

//  let inPlaceTexture = UnsafeMutablePointer<MTLTexture?>.alloc(1) 
//  inPlaceTexture.initialize(drawable.texture) 

Simon

感謝Warren

+0

這似乎是個伎倆。謝謝! – SeismicSquall

0

一般來說,除非將卷積濾波器實現爲多通濾波器,否則不會有適當的卷積濾波器。由於您正在查看相鄰像素,因此在一個像素中寫出結果會改變旁邊像素的輸入,從而導致錯誤。像這樣的小卷積一般實現爲MPS中的單通濾波器。您應該使用就地MPS編碼方法,以便框架根據需要更換目標紋理。另一種節省內存的方法是使用MPSTemporaryImages(iOS 10及更高版本)。

MPSImageConvolution應該檢測使用模式失敗並斷言。確保在Xcode中打開了金屬調試圖層。如果仍然沒有斷言,檢測問題的失敗是值得的。 http://bugreporter.apple.com