1

gray8 形式のフレームを grayf32 および gbrpf32 形式に変換しようとしています。以下のコードは、grayf32 では機能しますが、gbrpf32 では機能しません。以下のコードで何が間違っていますか?

AVFrame* gray = av_frame_alloc();
gray->format = AV_PIX_FMT_GRAY8;
gray->width = 4;
gray->height = 1;
gray->color_range = AVCOL_RANGE_JPEG;
av_frame_get_buffer(gray, 0);

uint8_t grayVals[4] = { 0, 85, 170, 255 };
memcpy(gray->data[0], grayVals, 4);

AVFrame* floatGray = av_frame_alloc();
floatGray->format = AV_PIX_FMT_GRAYF32;
floatGray->width = gray->width;
floatGray->height = gray->height;
floatGray->color_range = AVCOL_RANGE_JPEG;
av_frame_get_buffer(floatGray, 0);

SwsContext* sws_ctx = sws_getContext(
    gray->width, gray->height, AV_PIX_FMT_GRAY8,
    floatGray->width, floatGray->height, AV_PIX_FMT_GRAYF32,
    SWS_BILINEAR,
    NULL, NULL, NULL);
av_opt_set_int(sws_ctx, "src_range", 1, 0);
av_opt_set_int(sws_ctx, "dst_range", 1, 0);

int ret = sws_scale(sws_ctx, (const uint8_t* const*)gray->data,
    gray->linesize, 0, gray->height, floatGray->data,
    floatGray->linesize);
if (ret < 0)
    printf("error (1): %d\n", ret);

sws_freeContext(sws_ctx);


AVFrame* floatRGB = av_frame_alloc();
floatRGB->format = AV_PIX_FMT_GBRPF32;
floatRGB->width = gray->width;
floatRGB->height = gray->height;
floatRGB->color_range = AVCOL_RANGE_JPEG;
av_frame_get_buffer(floatRGB, 0);

sws_ctx = sws_getContext(
    gray->width, gray->height, AV_PIX_FMT_GRAY8,
    floatRGB->width, floatRGB->height, AV_PIX_FMT_GBRPF32,
    SWS_BILINEAR,
    NULL, NULL, NULL);
av_opt_set_int(sws_ctx, "src_range", 1, 0);
av_opt_set_int(sws_ctx, "dst_range", 1, 0);

ret = sws_scale(sws_ctx, (const uint8_t* const*)gray->data,
    gray->linesize, 0, gray->height, floatRGB->data,
    floatRGB->linesize);
if (ret < 0)
    printf("error (1): %d\n", ret);
sws_freeContext(sws_ctx);

uint8_t* input = gray->data[0];
float* out = (float*)floatGray->data[0];
float* outG = (float*)floatRGB->data[0];
float* outB = (float*)floatRGB->data[1];
float* outR = (float*)floatRGB->data[2];

printf("input: \n");
for (int i = 0; i < 4; ++i)
    printf("%d, ", input[i]);
printf("\ngray floats: \n");
for (int i = 0; i < 4; ++i)
    printf("%.5f, ", out[i]);
printf("\nRGB floats (G): \n");
for (int i = 0; i < 4; ++i)
    printf("%.5f, ", outG[i]);
printf("\nRGB floats (B): \n");
for (int i = 0; i < 4; ++i)
    printf("%.5f, ", outB[i]);
printf("\nRGB floats (R): \n");
for (int i = 0; i < 4; ++i)
    printf("%.5f, ", outR[i]);

これは私が得る出力です:

input:
0, 85, 170, 255,
gray floats:
0.00000, 0.33333, 0.66667, 1.00000,
RGB floats (G):
0.52912, 0.86114, 1.00000, 1.00000,
RGB floats (B):
0.00000, 0.00000, 0.00000, 0.11012,
RGB floats (R):
0.00000, 0.00000, 0.00000, 0.29512,

RGB フロートのすべてのチャネルに対して 0.00000、0.33333、0.66667、1.00000 を期待していましたが、明らかにそうではありません。FWIW、入力として gray8 の代わりに rgb24 を使用する場合 (つまり、rgb24->gray32f および rgb24->gbrpf32)、両方でほとんど正しく動作しますが、grayf32 形式の場合は間違った色範囲が使用されているようです (にもかかわらず)設定されている)、gbrpf32 の丸め誤差があります (コードは示されていません):

gray floats:
0.06250, 0.34766, 0.63282, 0.91798,
RGB floats (G):
0.00000, 0.33205, 0.66410, 0.99615,
RGB floats (B):
0.00000, 0.33205, 0.66410, 0.99615,
RGB floats (R):
0.00000, 0.33205, 0.66410, 0.99615,
4

0 に答える 0