利用 OpenCV 转换图片颜色格式

首先说一下遇到的需求,想要做个展示camera的demo,输出的图像有 YUV 格式的 和 16位深度图。显示画面用opengl渲染到glSurfaceView上,得先把图像都转换成 RGB 格式,然后才能作为贴图渲染。

这种处理用 OpenCV 就能轻易实现了,对刚接触的人来说,只是要注意颜色格式等等的设置。

下面是把 yuv 转换成 rgb 的步骤:

cv::Mat rawMat = cv::Mat((height + (height >> 1)), width, CV_8UC1, rgbRawData);
cv::Mat rgbMat = cv::Mat(height,width,CV_8UC3);
cv::cvtColor(rawMat, rgbMat, CV_YUV2RGB_NV12);

这里 CV_8UC1, CV_8UC3 是指定颜色存储格式。

CV_8UC1 表示颜色通道是1,每个颜色用8位数据,高度指定为1.5倍,是因为 yuv420 格式有 H*W 个Y数据,另外还有一半存UV数据。

CV_8UC3 更好理解些,每个像素有3通道,分别是R,G,B,每个颜色用8位数据表示,宽高也就是图像真实的宽高。

最后执行颜色转换的时候,这里对应指定了 CV_YUV2RGB_NV12,其他格式还有很多。

处理深度图像的步骤:

dptMat = cv::Mat(depthH, depthW, CV_16UC1, depthRawData);
dptMat.convertTo(dptMat, CV_8U, 255.0 / 3840);
cv::applyColorMap(dptMat, dptMat, cv::COLORMAP_RAINBOW);

首先构建原始的cvMat,因为是16位单通道的,对应指定格式为 CV_16UC1。

因为16位数据无法进行颜色映射,先转为普通的8位数据,使用的函数是:

    /** @brief Converts an array to another data type with optional scaling.

    The method converts source pixel values to the target data type. saturate_cast\<\> is applied at
    the end to avoid possible overflows:

    \f[m(x,y) = saturate \_ cast( \alpha (*this)(x,y) +  \beta )\f]
    @param m output matrix; if it does not have a proper size or type before the operation, it is
    reallocated.
    @param rtype desired output matrix type or, rather, the depth since the number of channels are the
    same as the input has; if rtype is negative, the output matrix will have the same type as the input.
    @param alpha optional scale factor.
    @param beta optional delta added to the scaled values.
     */
    void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const;

这里 scale 值的设置并不一定,可以调整。

映射颜色的时候,有多种预定义的模式可选,参考如下:

利用 OpenCV 转换图片颜色格式_第1张图片

你可能感兴趣的:(opencv)