opencv学习笔记14-opencv肤色提取(HSV色彩空间)

一、函数:

a.cvtColor函数:
(1)函数原型:
CV_EXPORTS_W void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0 );
(2)函数功能:
  • cvtColor 函数用于将输入图像从一种颜色空间转换到另一种颜色空间。
(3)颜色空间和通道顺序:
  • 转换涉及到 RGB 颜色空间时,需要明确指定通道的顺序(RGB 或 BGR)。OpenCV 默认的颜色格式通常被称为 RGB,但实际上是 BGR(字节顺序相反)。
 (4)颜色通道值范围:
  • 对于不同的数据类型,颜色通道的值范围不同:
    • 对于 CV_8U 图像:0 到 255。
    • 对于 CV_16U 图像:0 到 65535。
    • 对于 CV_32F 图像:0 到 1。
(5)线性与非线性转换:
  • 在线性转换中,颜色通道值的范围不重要。但在非线性转换中,如 RGB 到 Luv*,输入 RGB 图像需要归一化到适当的值范围以获得正确的结果。
 (6)归一化示例
  • 如果你有一个直接从 8 位图像转换而来的 32 位浮点图像,而没有进行任何缩放,那么它将具有 0..255 的值范围,而不是函数假定的 0..1。因此,在调用 cvtColor 之前,你需要先将图像缩放下来:
img *= 1./255;
cvtColor(img, img, COLOR_BGR2Luv);
 (7)8位图像转换的注意事项:
  • 使用 cvtColor 与 8 位图像进行转换可能会有一些信息丢失。对于需要全色域或在操作前转换图像然后转换回原色的应用程序,建议使用 32 位图像。
 (8)添加 Alpha 通道:
  • 如果转换过程中添加了 Alpha 通道,其值将设置为相应通道范围的最大值:对于 CV_8U 是 255,对于 CV_16U 是 65535,对于 CV_32F 是 1。
(9)参数说明:
  • src:输入图像,可以是 8 位无符号、16 位无符号(CV_16UC...)或单精度浮点类型。
  • dst:输出图像,大小和深度与 src 相同。
  • code:颜色空间转换代码(见 ColorConversionCodes)。
  • dstCn:目标图像中的通道数;如果参数为 0,则从 src 和 code 自动推导通道数。
(10)函数用途:
  • cvtColor 是图像处理中常用的函数,用于在不同的颜色空间之间转换图像,以便进行进一步的处理或分析。
 b.inRange 函数
(1)函数原型:
CV_EXPORTS_W void inRange(InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst);
(2)函数功能
  • inRange 函数用于检查输入数组 src 中的每个元素是否位于由 lowerb 和 upperb 指定的范围内。
(3)范围检查方式:
  • 对于单通道输入数组的每个元素,如果元素值在 lowerb 和 upperb 之间(包括边界值),则输出数组 dst 对应位置的元素将被设置为 255。
  • 对于双通道或多通道数组,所有通道的元素都需要在对应的边界范围内,输出数组 dst 的对应位置才会被设置为 255。
(4)数学表达式
  • 对于单通道数组,条件可以表示为: 
  • 对于双通道数组,条件可以表示为: 

        

 (5)边界参数:
  • 如果 lowerb 和/或 upperb 是标量,则在上述公式中的索引 (I) 应省略。
 (6)参数:
  • src:第一个输入数组,可以是单通道或多通道。
  • lowerb:包容性下界数组或标量。
  • upperb:包容性上界数组或标量。
  • dst:输出数组,大小与 src 相同,类型为 CV_8U(8位无符号整型)。
(7)输出结果:
  • 输出数组 dst 将包含与 src 相同的尺寸,并且每个元素将根据是否满足范围条件被设置为 255 或 0。

二、代码示例: 

#include <opencv2/core/utils/logger.hpp> 
#include <opencv2/opencv.hpp>           
#include <opencv2/videoio.hpp>          
#include <opencv2/objdetect.hpp>        
#include <opencv2/highgui/highgui_c.h>  
#include <iostream>                     

using namespace cv;                    
using namespace std;                 

// 主函数,实现肤色提取
int main() {
    utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT); // 设置日志级别为不输出任何日志信息
    VideoCapture cap(0); // 使用VideoCapture打开0号摄像头(通常为默认摄像头)
    double scale = 0.5; // 定义缩放比例

    // 定义HSV色彩空间中的肤色范围参数
    double hue_min = 0;    // 肤色的最小色调值
    double hue_max = 20;    // 肤色的最大色调值
    double saturability_min = 43;   // 肤色的最小饱和度值
    double saturability_max = 255;  // 肤色的最大饱和度值
    double Value_min = 55;   // 肤色的最小亮度值
    double Value_max = 255;  // 肤色的最大亮度值

    cout << "参数信息:" << endl; // 输出参数信息
    cout << "width:" << cap.get(CAP_PROP_FRAME_WIDTH) << endl; // 输出视频流中帧的宽度
    cout << "height:" << cap.get(CAP_PROP_FRAME_HEIGHT) << endl; // 输出视频流中帧的高度

    // 循环处理视频的每一帧
    while (1) {
        // 定义图像容器
        Mat frame; // 原始帧
        Mat hsvMat; // HSV色彩空间的帧
        Mat image; // 用于存放检测结果的图像

        cap >> frame; // 从摄像头读取当前帧

        // 修改图片尺寸大小
        Size ResImgSiz = Size(frame.cols * scale, frame.rows * scale); // 定义缩放后的图像尺寸
        Mat rFrame = Mat(ResImgSiz, frame.type()); // 创建缩放后的图像容器
        resize(frame, rFrame, ResImgSiz, INTER_LINEAR); // 执行缩放操作

        // 将BGR色彩空间的图像转换为HSV色彩空间
        cvtColor(rFrame, hsvMat, COLOR_BGR2HSV);

        // 对image进行初始化
        frame.copyTo(image); // 复制原始帧到image

        // 利用inRange函数对图片进行HSV筛选,提取肤色
        inRange(hsvMat, Scalar(hue_min, saturability_min, Value_min), Scalar(hue_max, saturability_max, Value_max), image);

        // 显示结果
        imshow("肤色提取", image); // 显示筛选后的图像
        imshow("摄像头", rFrame); // 显示原始图像

        // 每帧之间等待30毫秒,如果用户按下'q'键,则退出循环
        if (waitKey(30) == 'q') {
            break;
        }
    }
    destroyAllWindows();
    return 0;

}

三、运行结果:

 

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值