Я пытаюсь выполнить выравнивание гистограммы с помощью MPSImageHistogramEqualization на iOS, но в итоге выдает утверждение, которое я не понимаю. Вот мой код:

    // Calculate Histogram
    var histogramInfo = MPSImageHistogramInfo(
        numberOfHistogramEntries: 256,
        histogramForAlpha: false,
        minPixelValue: vector_float4(0,0,0,0),
        maxPixelValue: vector_float4(1,1,1,1))
    let calculation = MPSImageHistogram(device: self.mtlDevice, histogramInfo: &histogramInfo)
    let bufferLength = calculation.histogramSize(forSourceFormat: sourceTexture.pixelFormat)
    let histogramInfoBuffer = self.mtlDevice.makeBuffer(length: bufferLength, options: [.storageModePrivate])!
    calculation.encode(to: commandBuffer,
                       sourceTexture: sourceTexture,
                       histogram: histogramInfoBuffer,
                       histogramOffset: 0)
    let histogramEqualization = MPSImageHistogramEqualization(device: self.mtlDevice, histogramInfo: &histogramInfo)
    histogramEqualization.encodeTransform(to: commandBuffer, sourceTexture: sourceTexture, histogram: histogramInfoBuffer, histogramOffset: 0)

И вот итоговое утверждение, которое происходит в последней строке:

-[MTLDebugComputeCommandEncoder setBuffer:offset:atIndex:]:283: failed assertion `offset(4096) must be < [buffer length](4096).'

Есть предложения о том, что здесь может происходить?

0
Gadzair 15 Окт 2019 в 08:01

1 ответ

Лучший ответ

Похоже, это ошибка в специальном пути в MPSImageHistogramEqualization, и я рекомендую вам оставить отзыв в теме.

Когда numberOfHistogramEntries больше 256, ядро ​​изображения выделяет внутренний буфер, достаточно большой для хранения данных, с которыми ему нужно работать (для N = 512 это 8192 байта), плюс дополнительный бит пространства (32 байта ). Когда установлен внутренний флаг optimized256BinsUseCase, он выделяет ровно 4096 байт, опуская последний бит дополнительной памяти. Я подозреваю, что последующие операции полагаются на наличие большего пространства после начального блока данных и непреднамеренно устанавливают смещение буфера, превышающее длину внутреннего буфера.

Вы можете обойти это, используя другое количество интервалов гистограммы, например 512. Это тратит немного места и времени, но я предполагаю, что это даст те же результаты.

В качестве альтернативы вы можете избежать этого сбоя, отключив слой проверки Metal, но я настоятельно не рекомендую это, поскольку вы просто маскируете основную проблему, пока она не будет исправлена.

Примечание . Я выполнил обратное проектирование фреймворка MetalPerformanceShaders на macOS Catalina. Различные платформы и разные версии программного обеспечения, вероятно, имеют разные пути кода.

2
warrenm 15 Окт 2019 в 20:08