在图像处理中,色彩空间转换是非常重要的步骤,尤其是在图像提取、颜色识别和分析时。通过 OpenCV 提供的 函数,可以方便地在不同的色彩空间之间进行转换。常见的转换包括 BGR 到 HSV、BGR 到灰度等。而
cvtColor() 函数可以帮助我们提取图像中的特定颜色区域,常用于颜色过滤和图像分割。
inRange()
本文将详细讲解如何使用 OpenCV 进行色彩空间转换,并利用 提取图像中的特定颜色区域。
inRange()
1. 基本概念
1.1 BGR 到 HSV
是 OpenCV 默认的图像格式,表示蓝色、绿色和红色三种颜色通道。而
BGR 是基于色调、饱和度和亮度的颜色模型。与
HSV 模型不同,
BGR 更加直观地表示颜色,通常在颜色提取和过滤中使用。通过
HSV 函数,可以方便地将 BGR 图像转换为 HSV 图像。
cvtColor()
cvtColor(image, hsv, COLOR_BGR2HSV);
1.2
inRange() 函数
inRange()
是一个非常有用的函数,用于根据给定的颜色范围提取图像中的指定颜色区域。它会生成一个二值掩膜,掩膜中满足条件的像素为白色(255),不满足条件的像素为黑色(0)。通常结合其他操作(如
inRange() 或
bitwise_and())使用,从图像中提取特定区域。
copyTo()
inRange(hsv, Scalar(36, 43, 46), Scalar(77, 255, 255), mask);
这里, 和
Scalar(36, 43, 46) 是指定的颜色范围,分别表示 HSV 中色调、饱和度和明度的上下限。
Scalar(77, 255, 255)
2. 示例代码:提取图像中的绿色区域
下面是一个完整的示例,演示如何将 BGR 图像转换为 HSV 图像,并使用 提取绿色区域:
inRange()
void QuickDemo::inrange_demo(Mat& image) {
// Step 1: 将 BGR 图像转换为 HSV 图像
Mat hsv;
cvtColor(image, hsv, COLOR_BGR2HSV); // BGR 转换为 HSV
// Step 2: 使用 inRange 提取绿色区域
Mat mask;
// 绿色的 HSV 范围可以根据需要调整,这里选择色调范围在36到77之间
inRange(hsv, Scalar(36, 43, 46), Scalar(77, 255, 255), mask);
imshow("mask", mask); // 显示提取出来的绿色区域的掩膜
// Step 3: 创建背景图像,用红色填充
Mat redback = Mat::zeros(image.size(), image.type());
redback = Scalar(40, 40, 200); // 红色背景
// Step 4: 反转掩膜
bitwise_not(mask, mask); // 反转掩膜,使绿色区域变为0,其他区域变为255
imshow("反转掩膜", mask); // 显示反转后的掩膜
// Step 5: 使用掩膜提取绿色区域并放到背景图上
image.copyTo(redback, mask); // 将绿色区域提取出来,放到红色背景上
imshow("roi区域提取", redback); // 显示提取后的区域
}
代码解释:
BGR 到 HSV 转换:
cvtColor(image, hsv, COLOR_BGR2HSV);
我们首先使用 函数将 BGR 图像转换为 HSV 图像,因为 HSV 空间对于颜色的分离和提取更加直观。
cvtColor()
提取绿色区域:
inRange()
inRange(hsv, Scalar(36, 43, 46), Scalar(77, 255, 255), mask);
函数用来生成掩膜,范围内的绿色区域会变为白色(255),其他区域为黑色(0)。这个掩膜是后续提取操作的基础。
inRange()
反转掩膜:
bitwise_not(mask, mask);
反转掩膜的作用是将绿色区域变为黑色,其他区域变为白色。反转后的掩膜可以用来提取除了绿色区域之外的其他部分。
掩膜提取绿色区域:
image.copyTo(redback, mask);
函数将原图像中的绿色区域(根据掩膜)复制到
copyTo() 图像中。这样,绿色区域会显示在红色背景上,其他区域会被背景填充。
redback
3. 演示(抠出白色区域替换为红色)
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
void inrange_demo(Mat& image) {
// 将图像从BGR转换为HSV
Mat hsv;
cvtColor(image, hsv, COLOR_BGR2HSV);
// 创建一个掩膜,提取白色背景区域(HSV范围内白色背景)
Mat mask;
inRange(hsv, Scalar(0, 0, 200), Scalar(180, 60, 255), mask); // 过滤掉白色背景部分
// 显示掩膜图像,白色部分是背景
imshow("mask", mask);
// 创建一个与输入图像相同大小的背景图像,这里我们用一个新的颜色来替换背景
Mat redback = Mat::zeros(image.size(), image.type());
redback = Scalar(40, 40, 200); // 红色背景,替换掉原图中的白色背景
// 使用bitwise_not反转掩膜,得到前景部分
bitwise_not(mask, mask);
imshow("inverted mask", mask);
// 将原图复制到红色背景上(前景提取并粘贴到新的背景上)
image.copyTo(redback, mask);
// 显示前景提取后的图像
imshow("roi区域提取", redback);
}
int main() {
// 加载图像
Mat image = imread("C:UserszzzzzmPictureslxxx.png");
if (image.empty()) {
cout << "无法加载图像!" << endl;
return -1;
}
// 显示原始图像
imshow("Original Image", image);
// 调用inrange_demo进行背景替换
inrange_demo(image);
waitKey(0);
destroyAllWindows();
return 0;
}

参考资料:
OpenCV 文档
OpenCV 官方教程





![[C++探索之旅] 第一部分第十一课:小练习,猜单词 - 鹿快](https://img.lukuai.com/blogimg/20251015/da217e2245754101b3d2ef80869e9de2.jpg)










暂无评论内容