【Emgu.CV教程】第19篇 、色彩处理之InRange()函数进行颜色筛选

news/2024/7/21 7:42:36 标签: opencv, 计算机视觉, c#, 图像处理

        这篇文章又是偏实战的,读者们拿好小板凳,坐端正了仔细听讲啊。上一篇讲到了不同的颜色空间,为什么会有几十个不同的颜色空间来表示一张图片呢。

        以这张  红叶.jpg 举例,要想提取图片中的树叶,第一眼看到的是什么。

        树叶是红的,而最常用的BGR颜色空间正好代表蓝、绿、红,只需要将 红叶.jpg 进行通道分离,在红色通道内,越亮(越接近255)的必然是红色。 先看一下分离后红色通道是什么样的???

        看到上面结果了吗,基本上白色的部分,就是代表原图中红色区域了,那我再对这个红色通道用一个二值化函数 ,把超过200的部分全部变成白色,其余部分变成黑色,那结果就是下图这样的:

        很明显,在这个二值化图形中,白色区域就是原图中的红色树叶。这不是很简单的就挑出来红色部分了吗??步骤是:

  • 分离BGR颜色空间;
  • 得到红色通道;
  • 二值化红色通道;
  • 得到最终结果。

       这个图是没问题,咱们换一张, 可口可乐.jpg,如下图:

       这个图是以白色为背景,红色为前景的图片。在BGR颜色空间下,它的红色通道是这样的:

       看到了吗,在红色通道中,白色背景比真正红色的还要白。因为白色就是Blue=255、Green=255、Red=255,合并而来。因此在蓝、绿、红三个通道中,都是255。简单的理解,BGR颜色空间下,白色会干扰目标颜色的选择。这就没办法再用二值化函数提取了。此时,就需要进行颜色空间转换了,比如转换成HSV颜色空间,三个通道如下图所示:

        但是接下来怎么提取红色区域呢,InRange()函数闪亮登场。函数定义如下:

public static void InRange(
    IInputArray src,  // 输入图像
    IInputArray lower, // 颜色下限 
    IInputArray upper, // 颜色上限
    IOutputArray dst // 输出图像
)

        它的输出图像是一个二值化图像,可以看成是个掩码图,当输入图像的值在下限和上限之间,掩码图值为255,其余的为0。Emgu.CV中,对HSV的各通道取值范围是:

        这时候我们可以选红色下限是(0,43,46),红色上限是(10,255,255),再应用InRange(),全部代码如下:

Mat hsvMat = new Mat();
Mat maskMat = new Mat();
Mat tempMat = srcMat.Clone();
CvInvoke.CvtColor(tempMat, hsvMat, Emgu.CV.CvEnum.ColorConversion.Bgr2Hsv);
Mat[] channels = hsvMat.Split();
CvInvoke.Imshow("HSV H channel, " + channels[0].Size.ToString(), channels[0]);
CvInvoke.Imshow("HSV S channel, " + channels[1].Size.ToString(), channels[1]);
CvInvoke.Imshow("HSV V channel, " + channels[2].Size.ToString(), channels[2]);

// 定义红色的上下限
double hMin = 0, sMin = 43, vMin = 46;
double hMax = 10, sMax = 255, vMax = 255;
ScalarArray hsvMin = new ScalarArray(new MCvScalar(hMin, sMin, vMin));
ScalarArray hsvMax = new ScalarArray(new MCvScalar(hMax, sMax, vMax));
CvInvoke.InRange(hsvMat, hsvMin, hsvMax, maskMat); // 输出为符合要求的掩码图
CvInvoke.Imshow("Red mask, " + maskMat.Size.ToString(), maskMat);

// 提取红色区域并拷贝到黑底的图片上
Mat black = Mat.Ones(srcMat.Rows, srcMat.Cols, DepthType.Cv8U, 3);
tempMat.CopyTo(black, maskMat);
CvInvoke.Imshow("Final image only red, " + black.Size.ToString(), black);

        利用InRange()函数得到的maskMat掩码图和利用maskMat进行掩码拷贝得到的最终图片,如下: 

        InRange()函数要多做试验,小提示:这几篇都是介绍色彩处理的,选择图片时,一定要选颜色丰富的,才能突出效果。 

        代码不变,换成这张彩图试一试:

        结果如下:

原创不易,请勿抄袭。共同进步,相互学习。 


http://www.niftyadmin.cn/n/5292071.html

相关文章

R语言【BIEN】——BIEN_occurrence_family 可从 BIEN 数据库中提取指定科(或多个科)的所有记录。

Package BIEN version 1.2.6 Parameters BIEN_occurrence_family(family,cultivated FALSE,new.world NULL,observation.type FALSE,all.taxonomy FALSE,native.status FALSE,natives.only TRUE,political.boundaries FALSE,collection.info FALSE,... ) 参数【famil…

如何借助边缘网关打造智慧配电房安全方案

配电房是电力系统的重要组成部分,通常设置有各种高压配电装置和箱柜,是企业安全管理的重点。传统的人工巡检和监控总是难以避免疏漏,导致风险隐患的产生和扩大。 随着物联网、边缘计算、设备联动控制等技术的普及应用,佰马针对配电…

最新腾讯云轻量应用服务器优惠价格表

腾讯云轻量应用服务器优惠价格表,12月最新报价,腾讯云轻量2核2G3M带宽62元一年、2核2G4M轻量服务器118元一年,540元三年、2核4G5M带宽218元一年,756元三年、4核8G12M轻量服务器646元15个月,CVM云服务器S5实例2核2G配置…

【理论】STM32定时器时间计算公式 +【实践】TIM中断1s计时一次

前言:定时器TIM的详细知识点见我的博文:11.TIM定时中断-CSDN博客 STM32定时器时间计算公式 公式解释: ARR(TIM_Period):自动重装载值,是定时器溢出前的计数值 PSC(TIM_Prescaler&…

Activiti工作流框架学习笔记(二)之springboot2.0整合工作流Activiti6.0

文/朱季谦 以前在工作当中做过不少与工作流Activiti有关的工作,当时都是spring集成activiti5.22的项目,现在回过头去看,其实版本已经稍微老了,因此,基于先前的工作经验,决定用较新版本的技术来重新梳理下以…

跨模态检索论文阅读:Plug-and-Play Regulators for Image-Text Matching用于图像文本匹配的即插即用调节器

Plug-and-Play Regulators for Image-Text Matching用于图像文本匹配的即插即用调节器 利用细粒度的对应关系和视觉语义比对在图像-文本匹配中显示出巨大的潜力。通常,最近的方法首先使用跨模态注意力单元来捕捉潜在的区域-单词交互,然后整合所有比对以获…

[react]react-router-dom 与 redux 版本升级

[react]react-router-dom 与 redux 版本升级 环境脚手架的升级react-router-dom 升级关于路由相关文件的写法--react-router-dom 5.0.1入口渲染文件App.js路由框架src/views/root/index.js路由守卫 src/views/routerguide/index.jsx路由文件src/views/page.js 关于路由相关文件…

数据库开发之子查询案例的详细解析

1.5 案例 基于之前设计的多表案例的表结构,我们来完成今天的多表查询案例需求。 准备环境 将资料中准备好的多表查询的数据准备的SQL脚本导入数据库中。 分类表:category 菜品表:dish 套餐表:setmeal 套餐菜品关系表&#x…