[英]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.