为什么 opencv cvtColor 会修改图像大小?

Why does the opencv cvtColor modify image sizes?

我希望这与颜色 space 及其属性有更多关系。我试图将 YUYV 转换为灰度图像。我使用了以下函数调用:

cv::cvtColor(imgOrig, imgGray, cv::COLOR_YUV2GRAY_420);

有了这个功能,我失去了一些图像的高度。我显然可以使用 resize 方法使原始图像足够大,这样转换就不会删除任何实际数据,但我想找到更合适的方法。

查看 opencv 源代码,以下是 cvtColor 方法的摘录:

case COLOR_YUV2GRAY_420:
        {
            if (dcn <= 0) dcn = 1;

            CV_Assert( dcn == 1 );
            CV_Assert( sz.width % 2 == 0 && sz.height % 3 == 0 && depth == CV_8U );

            Size dstSz(sz.width, sz.height * 2 / 3);
            _dst.create(dstSz, CV_MAKETYPE(depth, dcn));
            dst = _dst.getMat();
#ifdef HAVE_IPP
#if IPP_VERSION_X100 >= 201700
            if (CV_INSTRUMENT_FUN_IPP(ippiCopy_8u_C1R_L, src.data, (IppSizeL)src.step, dst.data, (IppSizeL)dst.step,
                                               ippiSizeL(dstSz.width, dstSz.height)) >= 0)
                break;
#endif
#endif
            src(Range(0, dstSz.height), Range::all()).copyTo(dst);
        }
        break;

你看到在第 8 行,目标图像的大小被设置为源图像大小的三分之二。

为什么会这样?进行颜色 space 转换的合适方法是什么?

说白了,YUV420就是这样工作的。来自 wikipedia, YUV uses 6 bytes to store 4 pixels. Those 4 pixels share U, V values while having their own Y values. The picture and the formula presented in the conversion from YUV420 to RGB888 section 解释得更好。他们也很好地解释了为什么 check

CV_Assert( sz.width % 2 == 0 && sz.height % 3 == 0 && depth == CV_8U ); 以及为什么 RGB 只是 YUV 的 2/3