使用加速技术缩放Ycbcr(420f)时出现的图像伪影问题

3

我找不到任何关于如何调整Ycbcr双平面的文档或示例,这应该是苹果公司在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个回答

7

您可以在UV缓冲区中使用vImageScale_CbCr8,但仅适用于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
@fathy:你知道如何将缩放后的结果合并回一个新的像素缓冲区吗? - decades
@decades 你找到如何合并比例结果的方法了吗? - Tometoyou

2

我从苹果的工作人员那里得到了答案:因为UV平面是交错的,所以vImageScale_Planar8无法对其进行操作。唯一的解决方案是将其拆分为两个独立的平面。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接