【OpenCV + VS】从纯色的背景中扣出前景然后对背景颜色进行转换

        在图像处理中,色彩空间转换是非常重要的步骤,尤其是在图像提取、颜色识别和分析时。通过 OpenCV 提供的
cvtColor()
函数,可以方便地在不同的色彩空间之间进行转换。常见的转换包括 BGR 到 HSV、BGR 到灰度等。而
inRange()
函数可以帮助我们提取图像中的特定颜色区域,常用于颜色过滤和图像分割。

        本文将详细讲解如何使用 OpenCV 进行色彩空间转换,并利用
inRange()
提取图像中的特定颜色区域。


1. 基本概念

1.1 BGR 到 HSV


BGR
是 OpenCV 默认的图像格式,表示蓝色、绿色和红色三种颜色通道。而
HSV
是基于色调、饱和度和亮度的颜色模型。与
BGR
模型不同,
HSV
更加直观地表示颜色,通常在颜色提取和过滤中使用。通过
cvtColor()
函数,可以方便地将 BGR 图像转换为 HSV 图像。


cvtColor(image, hsv, COLOR_BGR2HSV);
1.2
inRange()
函数


inRange()
是一个非常有用的函数,用于根据给定的颜色范围提取图像中的指定颜色区域。它会生成一个二值掩膜,掩膜中满足条件的像素为白色(255),不满足条件的像素为黑色(0)。通常结合其他操作(如
bitwise_and()

copyTo()
)使用,从图像中提取特定区域。


inRange(hsv, Scalar(36, 43, 46), Scalar(77, 255, 255), mask);

这里,
Scalar(36, 43, 46)

Scalar(77, 255, 255)
是指定的颜色范围,分别表示 HSV 中色调、饱和度和明度的上下限。


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);

我们首先使用
cvtColor()
函数将 BGR 图像转换为 HSV 图像,因为 HSV 空间对于颜色的分离和提取更加直观。


inRange()
提取绿色区域:


inRange(hsv, Scalar(36, 43, 46), Scalar(77, 255, 255), mask);


inRange()
函数用来生成掩膜,范围内的绿色区域会变为白色(255),其他区域为黑色(0)。这个掩膜是后续提取操作的基础。

反转掩膜:


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 官方教程

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
欧洲杯买比利时球队保险吗的头像 - 鹿快
评论 抢沙发

请登录后发表评论

    暂无评论内容