C++ OpenCV怎么使用InRange对HSV颜色进行分割

发布时间:2021-07-16 10:47:10 作者:chen
来源:亿速云 阅读:1262
# C++ OpenCV怎么使用InRange对HSV颜色进行分割

## 一、HSV颜色空间简介

HSV(Hue-Saturation-Value)是一种更符合人类视觉感知的颜色模型,与RGB相比更适合颜色分割任务:

- **H(色相)**:表示颜色类型,范围0-180(OpenCV中压缩为0-180)
- **S(饱和度)**:颜色纯度,范围0-255
- **V(明度)**:颜色亮度,范围0-255

```cpp
// RGB转HSV示例
Mat bgrImage, hsvImage;
cvtColor(bgrImage, hsvImage, COLOR_BGR2HSV);

二、inRange函数原理

inRange()是OpenCV中进行颜色分割的核心函数:

void inRange(InputArray src, InputArray lowerb, 
             InputArray upperb, OutputArray dst);

三、完整实现步骤

1. 环境准备

#include <opencv2/opencv.hpp>
using namespace cv;

2. 基础实现代码

int main() {
    // 读取图像
    Mat image = imread("test.jpg");
    if(image.empty()) return -1;
    
    // 转换到HSV空间
    Mat hsvImage;
    cvtColor(image, hsvImage, COLOR_BGR2HSV);
    
    // 设置颜色范围(示例:提取红色)
    Scalar lower_red(0, 70, 50);
    Scalar upper_red(10, 255, 255);
    
    // 颜色分割
    Mat mask;
    inRange(hsvImage, lower_red, upper_red, mask);
    
    // 显示结果
    imshow("Original", image);
    imshow("Mask", mask);
    waitKey(0);
    return 0;
}

3. 多区间颜色处理

对于跨越HSV色相0值(如红色)的颜色:

// 处理红色(需要两个区间)
Mat mask1, mask2;
inRange(hsvImage, Scalar(0, 70, 50), Scalar(10, 255, 255), mask1);
inRange(hsvImage, Scalar(170, 70, 50), Scalar(180, 255, 255), mask2);
Mat mask = mask1 | mask2;

四、参数调节技巧

1. 动态调节工具

建议创建轨迹条实时调试:

// 创建调节窗口
namedWindow("Trackbars");
createTrackbar("Hue Min", "Trackbars", &h_min, 179);
// ...其他通道类似

// 在循环中实时更新
while(true) {
    Scalar lower(h_min, s_min, v_min);
    Scalar upper(h_max, s_max, v_max);
    inRange(hsvImage, lower, upper, mask);
    imshow("Mask", mask);
    if(waitKey(1) == 27) break;
}

2. 典型颜色HSV范围参考

颜色 H范围 S范围 V范围
红色 0-10, 160-180 100-255 50-255
绿色 35-85 50-255 50-255
蓝色 90-120 70-255 50-255
黄色 20-35 100-255 100-255

五、后处理优化

1. 形态学操作

// 去除噪声
Mat kernel = getStructuringElement(MORPH_RECT, Size(5,5));
morphologyEx(mask, mask, MORPH_OPEN, kernel);

// 填充空洞
morphologyEx(mask, mask, MORPH_CLOSE, kernel);

2. 轮廓处理

vector<vector<Point>> contours;
findContours(mask, contours, RETR_EXTERNAL, CHN_APPROX_SIMPLE);

for(size_t i=0; i<contours.size(); i++) {
    if(contourArea(contours[i]) > 500) { // 过滤小区域
        drawContours(image, contours, i, Scalar(0,255,0), 2);
    }
}

六、实际应用案例

1. 交通标志识别

// 识别红色禁止标志
Scalar lower_red(0, 100, 100);
Scalar upper_red(10, 255, 255);
inRange(hsvImage, lower_red, upper_red, mask);

2. 皮肤检测

// 皮肤颜色范围
Scalar lower_skin(0, 48, 80);
Scalar upper_skin(20, 255, 255);
inRange(hsvImage, lower_skin, upper_skin, mask);

七、常见问题解决

  1. 颜色检测不全:检查是否跨越HSV的0值,需要合并多个区间
  2. 背景干扰:适当提高饱和度(S)和明度(V)的下限
  3. 光照影响:在输入图像前先进行直方图均衡化
  4. 性能优化:对视频处理时可先降低分辨率

八、完整示例代码

GitHub代码仓库链接

通过合理设置HSV范围和结合后处理,inRange可以高效实现复杂场景下的颜色分割任务。建议在实际项目中配合其他视觉算法共同使用。 “`

推荐阅读:
  1. C++使用OpenCV实现证件照蓝底换成白底功能(或其他颜色如红色)详解
  2. 怎么在C++中使用opencv把蓝底照片转化为白底照片

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

c++ opencv inrange

上一篇:什么是C#拆箱和C#装箱

下一篇:Web开发中客户端跳转与服务器端跳转有什么区别

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》