OPENCV——cvtColor和putText

一、cvtColor的用处和API讲解

1.1 cvtColor 的作用

cvtColor是OPENCV里面颜色转换的转换函数,它的功能非常强大。能够实现RGB图像转换成灰度图、灰度图转换成RGB图像、RGB转换成HSV等等。下面我们来看看

​​​​​​​1.2 cvtColor的 API

复制代码
CV_EXPORTS_W void cvtColor( InputArray src,
                           OutputArray dst, 
                                  int code, 
                            int dstCn = 0 );

第一个参数:输入的图像数据

第二个参数:输出的图像数据

第三个参数:颜色转换的标识符,下面是转换的图表。图像转化可以分为11个大类,分别是RGB->BGR RGB->5X5 RGB->GRAY RGB->CIEXYZ RGB->YyCrcb(YUV) RGB->HSV RGB->HLS RGB->CIELab RGB->CIELuv RGB->Bayer YUV420->RGB

第四个参数:目标图像通道数,默认为0

​​​​​​​1.3 用代码实现cvtColor的颜色转换功能

这次代码主要是转换几个常见的格式,如RGB->YUV, YUV->RGB。具体的代码思路如下:

这个代码里面我们分别读取两种图片,一种是RGB图片、另外一种是YUV灰度图像、分别用cvtColor把RGB图像转换成YUV图像、把YUV灰度图像转换成RGB图像、最后用imwrite保存两种图片。

复制代码
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main()
{
    Mat car_image = imread("car.png");
    if(car_image.empty())
    {
        printf("Can not load car_image...\n");
        return -1;
    }

    Mat yuv_process_car_image;
    cvtColor(car_image, yuv_process_car_image, COLOR_RGB2YUV);
    imwrite("yuv_process_image.jpg", yuv_process_car_image);

    Mat yuv_car_image = imread("yuv_car.png");
    if(yuv_car_image.empty())
    {
        printf("Can not load yuv_car_image...\n");
        return -1;
    }

    Mat rgb_process_car_image;
    cvtColor(yuv_car_image, rgb_process_car_image, COLOR_YUV2RGB);
    imwrite("rgb_process_image.jpg", rgb_process_car_image);

    return 0;
}
  1. ​​​​​​​调用 imread 读取 RGB 彩色图像

    Mat car_image = imread("car.png");
    if(car_image.empty())
    {
    printf("Can not load car_image...\n");
    return -1;
    }

读取RGB彩色通道的图像,这张图片是一张车辆的图片

​​​​​​​2. RGB 图像转换为 YUV 图像

复制代码
Mat yuv_process_car_image;
cvtColor(car_image, yuv_process_car_image, COLOR_RGB2YUV);

调用cvtColor把三通道的RGB图像转换为YUV的灰度图像,这里使用的是COLOR_RGB2YUV。

​​​​​​​3. 调用 imread 读取 YUV 灰度图像

复制代码
Mat yuv_car_image = imread("yuv_car.png");
if(yuv_car_image.empty())
{
    printf("Can not load yuv_car_image...\n");
    return -1;
}

读取YUV的灰度图像,这张图片是一张灰度的汽车图像

​​​​​​​4. YUV 图像转换为 RGB 图像

复制代码
Mat rgb_process_car_image;
cvtColor(yuv_car_image, rgb_process_car_image, COLOR_YUV2RGB);

调用cvtColor把单通道的图像转换成RGB图像,调用的选项使用的是COLOR_YUV2RGB

​​​​​​​5. 把处理过后的两种图像保存

复制代码
imwrite("yuv_process_image.jpg", yuv_process_car_image);
imwrite("rgb_process_image.jpg", rgb_process_car_image);

使用imwrite保存两种图像

最终的效果:

左边是处理后的YUV图像,右边是RGB图像

二、putText的用处和API讲解

2.1. putText 的用法和作用

putText是OPENCV中常见的功能,他主要的功能是在Mat矩阵里面显示显示文字,像下图

从上图可以看出来putText是通过坐标(X,Y)在矩阵显示文字

2.2. putText API

复制代码
void putText(
    InputOutputArray img,
    const String& text,
    Point org,
    int fontFace,
    double fontScale,
    Scalar color,
    int thickness = 1,
    int lineType = LINE_8,
    bool bottomLeftOrigin = false
);
  1. img --- 目标画布
  • 类型:输入输出图像,一般直接传你的原始彩色图
  • 特点:就地修改 ,文字直接画在原图上;不想破坏原图就先 clone() 备份一份
  1. text --- 要绘制的文字内容
  • 类型:字符串 String
  • ⚠️ 核心限制:原生只支持英文、数字、ASCII 符号,不支持中文,直接写中文会显示成问号或乱码。嵌入式场景下调试标注用英文 + 数字完全足够。
  1. org --- 文字锚点坐标(最容易踩坑的参数)
  • 类型:Point(x, y)
  • 重点:默认情况下,这个坐标是文字的左下角位置 ,不是左上角!
    • x:文字左端距离图像左边缘的像素数
    • y:文字底端距离图像上边缘的像素数
  • 常见坑:把 y 设得太小(比如 y=10),文字整体会超出图像顶部,显示不全;一般要根据字体大小预留足够的高度。
  1. fontFace --- 字体样式
  • 内置几种固定字体,不能自定义字体文件,常用的有 3 种:

    枚举值 效果 适用场景
    FONT_HERSHEY_SIMPLEX 正常大小无衬线字体,笔画清晰 最常用,推荐首选,通用性强,绘制速度快
    FONT_HERSHEY_PLAIN 小号细体字体 空间小、需要密集标注的场景
    `FONT_HERSHEY_SIMPLEX FONT_HERSHEY_BOLD` 加粗版 需要突出显示的标注
  1. fontScale --- 字体缩放系数
  • 字体大小的倍数,乘以字体默认尺寸得到最终大小
  • 常用值:0.5(小号)、0.75(中号)、1.0(标准大小)
  • 数值越大字越大,绘制耗时也越长
  1. color --- 文字颜色
  • rectangleline 完全一致,Scalar(B, G, R) 格式
  • 比如红色标注:Scalar(0, 0, 255)
  1. thickness --- 文字笔画粗细
  • 默认值 1,单位像素;数值越大笔画越粗
  • 小字体配合细笔画,大字体配合粗笔画,显示更清晰
  1. lineType --- 线条类型
  • 默认 LINE_8(8 连通线),绘制速度最快,嵌入式场景推荐默认
  • LINE_AA 抗锯齿,文字边缘更平滑,但计算量更大,对性能敏感的场景不建议开
  1. bottomLeftOrigin --- 坐标原点开关
  • 默认 falseorg 是文字的左下角,日常开发永远用默认即可
  • 设为 true 时,org 变成文字左上角,极少用到

2.3. 用代码实现putText的功能

本章节代码主要是实现单张图片显示文字

复制代码
#include <opencv2/core.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main()
{
    Mat car_image = imread("car.png");
    if(car_image.empty())
    {
        printf("Can not load car_image....\n");
        return -1;
    }

    string str = "hello world";
    Point bg;
    bg.x = 0;
    bg.y = 400;
    int fontface = cv::FONT_HERSHEY_PLAIN;
    double fontScale = 4.0;
    int thickness = 4;
    putText(car_image, str, bg, fontface, fontScale, Scalar(0,0,255), thickness, LINE_8);
    imwrite("putText.jpg", car_image);
    
    return 0;
}

1. 读取车辆图片

复制代码
Mat car_image = imread("car.png");
if(car_image.empty())
{
    printf("Can not load car_image....\n");
    return -1;
}

使用imread读取需要处理的图片

2. 调用putText的API进行文字显示

复制代码
    string str = "hello world";
    Point bg;
    bg.x = 0;
    bg.y = 400;
    int fontface = cv::FONT_HERSHEY_PLAIN;
    double fontScale = 4.0;
    int thickness = 4;
    putText(car_image, str, bg, fontface, fontScale, Scalar(0,0,255), thickness, LINE_8);

上面是代码是利用putText对Mat矩阵进行文字显示,显示的字符是HelloWorld ,这里的位置我们选择是Point(0,400)这个位置,字体选择FONT_HERSHEY_PLAIN ,字体大小是4.0,颜色为红色(Scalar(0,0,255) ), 绘制线的粗细程度是4,然后线的类型是LINE_8.

3. 最后用imwrite来保存图片,最终的显示效果是

复制代码
    imwrite("putText.jpg", car_image);