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,