使用Accelerate缩放Ycbcr(420f)时的伪像

时间:2015-09-25 23:56:03

标签: ios accelerate-framework

我找不到任何关于如何调整Ycbcr biplanar大小的文档或示例,据说这是你应该在iOS上使用的主要格式。我试着像这样调整两架飞机的大小:

    // resize luma
    vImage_Buffer originalYBuffer = { CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0), CVPixelBufferGetHeightOfPlane(pixelBuffer, 0), CVPixelBufferGetWidthOfPlane(pixelBuffer, 0), CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 0) };
    vImage_Buffer resizedYBuffer;
    vImageBuffer_Init(&resizedYBuffer, IMAGE_HEIGHT, IMAGE_WIDTH, 8 * sizeof(Pixel_8), kvImageNoFlags);
    error = vImageScale_Planar8(&originalYBuffer, &resizedYBuffer, NULL, kvImageNoFlags);
    assert(!error);
    cv::Mat grey(IMAGE_HEIGHT, IMAGE_WIDTH, CV_8UC1, resizedYBuffer.data);

    // resize chroma
    vImage_Buffer originalUVBuffer = { CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1), CVPixelBufferGetHeightOfPlane(pixelBuffer, 1), CVPixelBufferGetWidthOfPlane(pixelBuffer, 1), CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 1) };
    vImage_Buffer resizedUVBuffer;
    vImageBuffer_Init(&resizedUVBuffer, IMAGE_HEIGHT / 2, IMAGE_WIDTH / 2, 8 * sizeof(Pixel_16U), kvImageNoFlags);
    error = vImageScale_Planar8(&originalUVBuffer, &resizedUVBuffer, NULL, kvImageNoFlags);
    assert(!error);

但颜色完全被淹没了。亮度通道本身就可以工作,所以这是色度问题。这种格式应该使用2个字节用于色度,虽然不完全确定。如果我使用vImageScale_Planar8,我会将屏幕的一半设为绿色,否则如果我使用vImageScale_Planar16U,我会在整个图像上出现蓝/黄噪声。

2 个答案:

答案 0 :(得分:5)

你可以使用vImageScale_CbCr8作为UV缓冲区,但它只是iOS 10+:

// resize luma
    vImage_Buffer originalYBuffer = { CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0), CVPixelBufferGetHeightOfPlane(pixelBuffer, 0), CVPixelBufferGetWidthOfPlane(pixelBuffer, 0), CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 0) };
    vImage_Buffer resizedYBuffer;
    vImageBuffer_Init(&resizedYBuffer, IMAGE_HEIGHT, IMAGE_WIDTH, 8 * sizeof(Pixel_8), kvImageNoFlags);
    error = vImageScale_Planar(&originalYBuffer, &resizedYBuffer, NULL, kvImageNoFlags);
    assert(!error);
    cv::Mat grey(IMAGE_HEIGHT, IMAGE_WIDTH, CV_8UC1, resizedYBuffer.data);

    // resize chroma
    vImage_Buffer originalUVBuffer = { CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1), CVPixelBufferGetHeightOfPlane(pixelBuffer, 1), CVPixelBufferGetWidthOfPlane(pixelBuffer, 1), CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 1) };
    vImage_Buffer resizedUVBuffer;
    vImageBuffer_Init(&resizedUVBuffer, IMAGE_HEIGHT / 2, IMAGE_WIDTH / 2, 8 * sizeof(Pixel_16U), kvImageNoFlags);
    error = vImageScale_CbCr8(&originalUVBuffer, &resizedUVBuffer, NULL, kvImageNoFlags);
    assert(!error);

答案 1 :(得分:2)

得到了苹果公司的工作人员:vImageScale_Planar8无法在UV平面上操作,因为它是交错的。唯一的解决方案是分成两个独立的平面。