OpenCV 4.x API 详解与C++实例-颜色空间变换

第五节 颜色空间变换

OpenCV提供了143种颜色空间相互转换的类型,比如RGB2BGR、BGR2GRAY等等。在本节中将介绍平时常用的几种颜色空间转换。

1、cv::cvtColor


将图像从一种颜色空间转换为另一种颜色空间。

void cv::cvtColor(InputArray src,OutputArray dst,int code,int dstCn = 0)

该函数将输入图像从一种颜色空间转换为另一种颜色空间。 在从RGB颜色空间转换的情况下,应明确指定通道的顺序(RGB或BGR)。 请注意,OpenCV中的默认颜色格式通常称为RGB,但实际上是BGR(字节是相反的)。 因此,标准(24位)彩色图像中的第一个字节将是8位蓝色分量,第二个字节将是绿色分量,第三个字节将是红色分量。 第四,第五和第六个字节将是第二个像素(蓝色,然后是绿色,然后是红色),依此类推。

R、G和B通道值的常规范围是:

  • 0 至 255 的CV_8U 图像
  • 0 至65535 的CV_16U 图像
  • 0 至 1 的CV_32F 图像

在线性变换的情况下,范围无关紧要。 但是,在进行非线性变换的情况下,应将输入的RGB图像规范化为适当的值范围以获得正确的结果,例如,对于RGB→L * u * v *变换。 例如,如果您有一个32位浮点图像直接从8位图像转换而没有任何缩放,则它将具有0…255的值范围,而不是该函数假定的0…1。 因此,在调用cvtColor之前,您首先需要按比例缩小图像:

img *= 1./255;
cvtColor(img, img, COLOR_BGR2Luv);

如果将cvtColor与8位图像一起使用,转换将丢失一些信息。 对于许多应用程序,这不会引起注意,但是建议在需要全范围颜色或在执行操作之前先转换图像然后转换回来的应用程序中使用32位图像。

如果转换添加了Alpha通道,则其值将设置为相应通道范围的最大值:CV_8U为255,CV_16U为65535,CV_32F为1。

参数如下:

参数名称 参数描述
src 输入图像:8位无符号,16位无符号(CV_16UC …)或单精度浮点。
dst 输出与src具有相同大小和深度的图像。
code 色彩空间转换代码 (请参考ColorConversionCodes).
dstCn 目标图像中的频道数; 如果参数为0,则通道数自动从src和代码得出。
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;

void setToPanel(cv::Mat & panel,const cv::Mat& region,int rowIndex,
                int colsIndex,const string& text){
    // 分割成网格
    int width = panel.cols / 4;
    int height = panel.rows / 2;

    // 计算每个网格的区域位置
    cv::Rect roiRect;
    roiRect.x = colsIndex * width;
    roiRect.y = rowIndex * height;
    roiRect.width = width;
    roiRect.height = height;

    // ROI提取
    cv::Mat roi(panel,roiRect);

    // 重新调整显示图像的大小与网格大小相同
    cv::Mat resized;
    cv::resize(region,roi,cv::Size(width,height));


    // 设置字体参数并显示
    int font_face = cv::FONT_HERSHEY_COMPLEX;
    double font_scale = 1;
    int thickness = 1;
    int baseline;
    cv::Size text_size = cv::getTextSize(text, font_face, font_scale, thickness, &baseline);
    cv::Point center(width / 2 - text_size.width / 2,height / 2 - text_size.height / 2);
    cv::putText(roi,text,center,font_face,font_scale,cv::Scalar(255,255,255),thickness);
}

int main()
{
    // 读取图像
    cv::Mat src = cv::imread("images/f1.jpg");
    if(src.empty()){
        cerr << "cannot read image.\n";
        return EXIT_FAILURE;
    }
    cv::Mat panel(cv::Size(1280,480),CV_8UC3);

    int colorspaces[] = {cv::COLOR_BGR2GRAY,cv::COLOR_BGR2YUV,cv::COLOR_BGR2HLS,
                        cv::COLOR_BGR2HSV,cv::COLOR_BGR2Lab,cv::COLOR_BGR2XYZ,
                        cv::COLOR_BGR2YCrCb,cv::COLOR_BGR2RGB};
    string names[] = {"gray","yuv","HLS","HSV","Lab","XYZ","YCrCb","RGB"};
    for(int i = 0;i<8;i++){
        cv::Mat dst;
        if(i == 0){
            cv::cvtColor(src,dst,cv::COLOR_BGR2GRAY);
            cv::cvtColor(dst,dst,cv::COLOR_GRAY2BGR);
        }else{
            cv::cvtColor(src,dst,colorspaces[i]);
        }
        if(i < 4){
            setToPanel(panel,dst,0,i,names[i]);
        }else{
            setToPanel(panel,dst,1,i-4,names[i]);
        }
    }


    cv::imshow("dst",panel);
    cv::waitKey();
    return 0;
}

在这里插入图片描述

2、cv::cvtColorTwoPlane


将图像从一种颜色空间转换为另一种颜色,其中源图像存储在两个平面中。

void cv::cvtColorTwoPlane(InputArray src1,InputArray src2,OutputArray dst,int code)

到目前为止,此函数仅支持YUV420到RGB的转换。

参数如下:

参数名称 参数描述
src1 Y平面的8位图片(CV_8U)
src2 包含交错的U / V平面的图像。
dst 输出图像
code 指定转换类型.

code的值如下:

  • COLOR_YUV2BGR_NV12
  • COLOR_YUV2RGB_NV12
  • COLOR_YUV2BGRA_NV12
  • COLOR_YUV2RGBA_NV12
  • COLOR_YUV2BGR_NV21
  • COLOR_YUV2RGB_NV21
  • COLOR_YUV2BGRA_NV21
  • COLOR_YUV2RGBA_NV21

3、cv::demosaicing


所有去马赛克处理的主函数

void cv::demosaicing(InputArray src,OutputArray dst,int code,int dstCn = 0)

参数如下:

参数名称 参数描述
src 输入图像:8位无符号或16位无符号。
dst 输出与src具有相同大小和深度的图像。
code 色彩空间转换代码(请参见下面的描述)。
dstCn 目标图像中的频道数; 如果参数为0,则通道数自动从src和代码得出。

该函数可以进行以下转换:

猜你喜欢

转载自blog.csdn.net/wujuxKkoolerter/article/details/112426583