簡體   English   中英

使用MPSImageConvolution內核和Metal計算着色器

[英]Using MPSImageConvolution kernel with Metal compute shaders

我正在使用位於此處的MetalVideoCapture示例https://github.com/FlexMonkey/MetalVideoCapture 我在我的版本中唯一改變的是使用內核值的MPSImageConvolution(而不是MPSImageGaussianBlur):

[-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 )。 這個例子的作者同樣像我一樣難倒,這讓我相信這是某種錯誤或在我的概念知識中的差距,為什么這甚至不能起作用。

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

    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)

西蒙

謝沃倫

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM