OpenCV色彩空间应用之ROI提取
1.引言
在RGB色彩空间中,颜色由红、绿、蓝三个通道描述,但这种描述方式对于颜色提取并不直观,尤其在光照变化较大的情况下容易受到影响。HSV色彩空间则将颜色分为三个分量:
- Hue(色相): 表示颜色的基本属性,比如红色、蓝色、绿色等,范围一般是0~179(在OpenCV中)。
- Saturation(饱和度): 表示颜色的纯度,饱和度高的颜色看起来更鲜艳。
- Value(明度): 表示颜色的亮度,高明度的颜色显得更亮。
由于HSV色彩空间能够更好地分离颜色信息和亮度信息,因此在进行颜色过滤和目标检测时具有很大优势。
基于这种方式的应用之一就是主播直播时都是绿幕背景,然后有软件自动生成各种特效。
2.使用HSV提取ROI的原理
提取ROI的基本流程通常包括以下几个步骤:
- 图像预处理: 加载原始图像,并进行适当的预处理(如高斯模糊)以减少噪声。
- 颜色空间转换: 将BGR图像转换为HSV色彩空间,使得颜色信息与亮度分离。
- 颜色阈值设定: 根据待提取目标的颜色特点,设置HSV的阈值范围(低阈值和高阈值)。
- 二值化处理: 利用**
inRange()
**函数生成掩膜(mask),使得在指定阈值内的像素被保留。 - ROI提取: 使用掩膜对原始图像进行按位与操作,从而提取出感兴趣区域。
这种方法在提取颜色明显与背景区分的目标时效果尤为显著,如提取特定颜色的物体、车牌识别等。
3.提取函数inRange
void cv::inRange(InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst);
各参数说明如下:
src
:输入图像,可以是单通道或多通道图像。lowerb
:每个通道的下边界数组或标量。upperb
:每个通道的上边界数组或标量。dst
:输出图像,与输入图像尺寸相同且为单通道二值图像(CV_8U 类型)。
3.1HSV取值表
这个是网友提供的,没有标准的,每个人对颜色的感受不一样,包括不同显示设备对颜色显示也是有差异的,大部分都是经验值通过实验计算的范围
H: 0— 180
S: 0— 255
V: 0— 255
此处把部分红色归为紫色范围:
4、参考代码与效果
#include "stdio.h"
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
int main()
{
cv::Mat srcImage=cv::imread("eagle.png");
//HSV颜色转换
Mat hsvImage;
cvtColor(srcImage, hsvImage, COLOR_BGR2HSV);
//提取指定范围数据
Mat mask;
inRange(hsvImage, Scalar(35, 43, 46), Scalar(77, 255, 255), mask);
//像素逻辑操作 获取ROI掩膜
bitwise_not(mask, mask);
//重新生成新的图片
Mat dstImage=Mat::zeros(hsvImage.rows, hsvImage.cols, hsvImage.type());
dstImage = Scalar(200, 60, 60);
srcImage.copyTo(dstImage, mask);
imshow("src", srcImage);
imshow("mask", mask);
imshow("dst", dstImage);
waitKey();
cv::destroyAllWindows();
return 0;
}
- 加载图像并转换到 HSV 色彩空间。
- 使用
inRange
函数对图像进行阈值处理,生成特定颜色区域的掩膜。 - 反转掩膜,使得需要提取的区域对应白色(非零)。
- 创建背景图像并赋初值,通过掩膜将原图中的目标区域复制到背景图上。
- 显示各个结果图像。
如下图把绿色替换为蓝色。这种方法可以快速实现复杂为物体提取