CImg提供了丰富的色彩空间转换功能,允许在不同的颜色空间(RGB,sRGB,YUV,HSL,HSV,YCbCr,CMY,CMYK,XYZ
)之间的转换,使用非常简单以下是将一个RGB
图像转为YUV
的示例。
#include <CImg.h>
using namespace cimg_library;
/**
* 加载JPEG图像文件并转为YUV色彩空间
* @param jpeg_file
* @return
*/
CImg<unsigned char> load_jpeg_yuv(const char* jpeg_file)
{
// 因为RGB 转 YUV 是浮点运算,所以这里定义float类型的CImg对象
CImg<float> yuv;
// 加载一个JPEG文件到内存,
// NOTE:必须有libjpeg支持
yuv.load_jpeg(jpeg_file);
// RGB转为YUV
yuv.RGBtoYUV();
// RGB转YUV后,每个像素值都是归一化的浮点数(0.0~1.0)
// 所以需要将浮点数转为0~255之间的值,在这里 *= 操作符将所有图像矩阵中所有像素值乘以255。
yuv *= 255;
// 基于float类型的CImg对象,重新构造一个unsigned char类型的CImg对象
return CImg<unsigned char>(yuv,false);
}
上面的代码如果简写,只要一行就完成.
CImg<unsigned char> load_jpeg_yuv(const char* jpeg_file)
{
return CImg<unsigned char>(CImg<float>().load_jpeg(jpeg_file).RGBtoYUV()*255,false);
}
如果你想实现其他色彩空间的转稍稍看一下CImg.h源码就明白了。
如果想从YUV图像中分别获取,Y,U,V分量的数据该怎么办呢?
如下代码以std::string
对象返回Y分量(灰度图像)数据
#include <string>
std::string get_gray_matrix (const char* jpeg_file)
{
CImg<unsigned char> yuv = load_jpeg_yuv(jpeg_file);
// CImg的图像数据是按通道存储的,所以获取不同通道的数据只需要data函数算出通道起始地址就可以了。
// 返回 Y分量(灰度图像矩阵)
// U分量为data(0,0,0,1),V分量为data(0,0,0,2)
unsigned char* y = yuv.data(0,0,0,0);
return std::string((char*)y, yuv._width * yuv._height);
}
NOTE:
CImg
设计的目标是一个方便简单的图像处理工具,性能并不是追求的目标,
上面的色彩空间转换虽然简单,但在代码运行效率上并不可取,
所以需要考虑代码性能的应用场景,使用CImg
就不太合适了。