2015-04-15 5 views
3

Промежуточный шаг моего текущего проекта требует преобразования opvv cv :: Mat в MTLTexture, контейнер текстуры Металла. Мне нужно сохранить Floats в Mat как Floats в текстуре; мой проект не может позволить себе потерю точности.Преобразование cv :: Mat в MTLTexture

Это моя попытка такого преобразования.

- (id<MTLTexture>)texForMat:(cv::Mat)image context:(MBEContext *)context 
{ 

    id<MTLTexture> texture; 
    int width = image.cols; 
    int height = image.rows; 
    Float32 *rawData = (Float32 *)calloc(height * width * 4,sizeof(float)); 
    int bytesPerPixel = 4; 
    int bytesPerRow = bytesPerPixel * width; 
    float r, g, b,a; 


    for(int i = 0; i < height; i++) 
    { 
    Float32* imageData = (Float32*)(image.data + image.step * i); 
    for(int j = 0; j < width; j++) 
    { 
     r = (Float32)(imageData[4 * j]); 
     g = (Float32)(imageData[4 * j + 1]); 
     b = (Float32)(imageData[4 * j + 2]); 
     a = (Float32)(imageData[4 * j + 3]); 

     rawData[image.step * (i) + (4 * j)] = r; 
     rawData[image.step * (i) + (4 * j + 1)] = g; 
     rawData[image.step * (i) + (4 * j + 2)] = b; 
     rawData[image.step * (i) + (4 * j + 3)] = a; 
    } 
    } 


    MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA16Float 
                           width:width 
                           height:height 
                          mipmapped:NO]; 
    texture = [context.device newTextureWithDescriptor:textureDescriptor]; 
    MTLRegion region = MTLRegionMake2D(0, 0, width, height); 
    [texture replaceRegion:region mipmapLevel:0 withBytes:rawData bytesPerRow:bytesPerRow]; 

    free(rawData); 
    return texture; 
} 

Но он, похоже, не работает. Он каждый раз считывает нули из Mat и выдает EXC_BAD_ACCESS. Мне нужна MTLTexture в MTLPixelFormatRGBA16Float, чтобы сохранить точность.

Благодарим за рассмотрение этой проблемы.

+2

Почему голос? – CaladanBrood

+0

Я считаю, что 'image.step' находится в байтах. Также я думаю, что OpenCV обычно использует BGR, а не RGB, поэтому проверьте порядок вашего канала. И вы, кажется, не выделяете 'rawData' с шагом (обязательно)' image.step', но вы используете это для его решения. – chappjc

ответ

3

Одна из проблем заключается в том, что вы загружаете rawData с помощью Float32s, но ваша текстура RGBA16Float, поэтому данные будут повреждены (16Float - это половина размера Float32). Это не должно привести к вашему сбою, но это проблема, с которой вам придется иметь дело.

Также как «chappjc» отметил, что вы используете «image.step» при записи своих данных, но этот буфер должен быть смежным и никогда не иметь такого шага, который не просто (ширина * bytesPerPixel).

+0

Конечно, обе точки действительны, но поскольку у меня была точно такая же проблема, я просто подтвержу - вторая причина - это то, что вызывает крах. При повторении через 'rawData' - например. 'rawData [image.step * (i) + (4 * j)] = r;' скорее должен быть 'rawData [bytesPerRow * i + (4 * j)] = r;' –

Смежные вопросы