Qt+OpenCV联合开发(十四)--图像感兴趣区域(ROI)的提取

 一、简述ROI及mask(掩模)技术

1、ROI(region of interest)——感兴趣区域

用途:这个区域是图像分析所关注的重点。圈定这个区域,以便进行进一步的处理。而且,使用ROI指定想读入的目标,可以减少处理时间,增加精度,给图像处理带来不小的便利。

2、利用mask(掩模)技术提取纯色背景图像ROI区域中的人和物,并将提取出来的人或物添加在其他图像上。

二、实现原理

先通过cvtColor函数,将原RGB彩色图像转换成hsv色彩风格,然后通过inRange()函数获得ROI区域的mask,接着利用bitwise_not()函数将mask图像取反,最后利用copyTo函数将取反后的图像拷贝到新的图像上。

三、函数原型

1、cvtColor函数

  • image为要进行色彩空间转换的原图
  • hsv为转换后的图片
  • COLOR_BGR2HSV为转换类型,即将原图RGB色彩空间转换为HSV色彩空间

注:HSV即Hue(色调),Saturation(饱和度)和Value(亮度)

2、inRange函数

作用:inRange函数可实现二值化功能,更关键的是可以同时针对多通道进行操作,使用起来非常方便

c++原型:

  • 参数一:输入要处理的图像,可以为单通道或多通道
  • 参数二:包含下边界的数组或标量
  • 参数三:包含上边界数组或标量
  • 参数四:输出图像,与输入图像src 尺寸相同且为CV_8U 类型

注意:该函数输出的dst是一幅二值化之后的图像

inRange函数通过设置不同的h、s、v的min和max阈值可以获取不同色彩的一个二值的mask图,下图为各颜色的阈值表:

Qt+OpenCV联合开发(十四)--图像感兴趣区域(ROI)的提取_第1张图片

inRange函数补充:

1、针对单通道图像
dst(I) = lowerb(I)0 ≤ src(I)0 < upperb(I)0
即,如果一幅灰度图像的某个像素的灰度值在指定的高、低阈值范围之内,则在dst图像中令该像素值为255,否则令其为0,这样就生成了一幅二值化的输出图像。

2、针对三通道图像
dst(I) = lowerb(I)0 ≤ src(I)0 < upperb(I)0 ∧ lowerb(I)1 ≤ src(I)1 < upperb(I)1 ∧lowerb(I)2 ≤ src(I)2 < upperb(I)2
即,每个通道的像素值都必须在规定的阈值范围内!

3、inRange函数类似threshold()函数【去掉噪,例如过滤很小或很大像素值的图像点】

3、copyTo函数

OpenCV中image.copyTo()有两种形式:

1、image.copyTo(image_roi),作用是把image的内容复制到imageROI;

2、image.copyTo(image_roi,mask),作用是把原图(image)和掩膜(mask)与运算后得到ROI区域(image_roi)。

Qt+OpenCV联合开发(十四)--图像感兴趣区域(ROI)的提取_第2张图片

mask就是位图,如果mask像素的值是非0的,我就拷贝它,否则不拷贝。(非零的位置就是原图中的那些需要拷贝的部分)
 

四、实现效果

1、二值化之后的图像mask

Qt+OpenCV联合开发(十四)--图像感兴趣区域(ROI)的提取_第3张图片

2、图像取反

Qt+OpenCV联合开发(十四)--图像感兴趣区域(ROI)的提取_第4张图片

3、将掩膜(提取到的ROI区域)拷贝到新图像上

Qt+OpenCV联合开发(十四)--图像感兴趣区域(ROI)的提取_第5张图片

五、代码

void test1::inRange_demo(Mat &image)
{
    Mat hsv;
    cvtColor(image,hsv,COLOR_BGR2HSV);//将原图RGB色彩空间转换为HSV色彩空间
    
    //提取mask
    Mat mask;

    inRange(hsv,Scalar(35,43,46),Scalar(77,255,255),mask);//二值化之后的图像mask
    imshow("mask1",mask);

    Mat blueBack = Mat::zeros(image.size(),image.type());
    blueBack = Scalar(211,35,35);
    bitwise_not(mask,mask);
    imshow("mask2",mask);


    //只有那些像素在mask上面不为0的像素点才会被提取到新图像上,也就是图像取反之后的白色部分(人物),为0的就不要了(黑色背景部分)
    image.copyTo(blueBack,mask);//将掩膜(提取到的ROI区域)拷贝到新图像blueBack上
    imshow("ROI eara",blueBack);


}

补充:

为什么取反色?

因为现在提取的背景是绿色,绿色是1,代表背景在这个遮罩上面是1 的像素的可变形,可以被拷贝,而人的区域是黑色,就不可以被拷贝,所以先给他取反,取反之后就可以拷贝人的部分(黑变白),然后把抠出来的人贴到另一张图上去。

为什么放绿幕?

为什么网红主播在播一个东西的时候,后面放一个绿幕,然后背景就可以任意切换,这是非常简单的,如果再加上融合技术就会达到一个很好的效果。 当然现在用深度学习做出来的就会有更好的像素融合,精度更高。在RGB色彩空间,我们很难准确去提取这些像素值,因为分布的颜色太广,所以放到HSV像素空间只有HS控制颜色,就很容易进行提取。所以当你看到一个单一颜色的时候,你第一反应应该是把他转到色彩辨识度的色彩空间里面去,比如HSV LAB HSI,处理完之后再返回RGB。

你可能感兴趣的:(Qt实战,opencv,C/C++,qt,opencv,开发语言)