【opencv】17.提取RBG各种颜色c++代码

2024-06-16 21:08

本文主要是介绍【opencv】17.提取RBG各种颜色c++代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

关于HSV颜色空间的介绍可以参考这篇博客:OpenCV中HSV颜色模型及颜色分量范围。
在这里插入图片描述

提取上图各种颜色c++代码如下test.cpp,以提取蓝色、绿色、红色三种颜色为例:

#include <iostream>
#include <string>
#include <vector>#include "opencv2/highgui/highgui.hpp"
#include "opencv2/opencv.hpp"//g++ test.cpp `pkg-config opencv --libs --cflags` -std=c++11 -o testint main() {cv::Mat origin_bgr_img = cv::imread("pic.png");// 将BGR空间的图片转换到HSV空间cv::Mat hsv;// hsv为3通道,hsv.channels==3cv::cvtColor(origin_bgr_img, hsv, cv::COLOR_BGR2HSV);std::cout << "hsv.channels=" << hsv.channels() << std::endl;// 在HSV空间中定义蓝色cv::Scalar lower_blue = cv::Scalar(100, 50, 50);cv::Scalar upper_blue = cv::Scalar(124, 255, 255);// # 在HSV空间中定义绿色cv::Scalar lower_green = cv::Scalar(35, 50, 50);cv::Scalar upper_green = cv::Scalar(77, 255, 255);// # 在HSV空间中定义红色,红色的h值有两个范围[0,10]和[156,180]cv::Scalar lower_red_1 = cv::Scalar(0, 50, 50);cv::Scalar upper_red_1 = cv::Scalar(10, 255, 255);cv::Scalar lower_red_2 = cv::Scalar(156, 50, 50);cv::Scalar upper_red_2 = cv::Scalar(180, 255, 255);// 从HSV图像中截取出蓝色、绿色、红色,即获得相应的掩膜// cv::inRange()函数是设置阈值去除背景部分,得到想要的区域cv::Mat blue_mask, green_mask, red_mask, red_mask_1, red_mask_2;// 把hsv中的像素值在范围内的置255,不在范围内的置0,输出为掩模mask// blue_mask为单通道,blue_mask.channels==1cv::inRange(hsv, lower_blue, upper_blue, blue_mask);std::cout << "blue_mask.channels=" << blue_mask.channels() << std::endl;//   std::cout << blue_mask << std::endl;cv::inRange(hsv, lower_green, upper_green, green_mask);cv::inRange(hsv, lower_red_1, upper_red_1, red_mask_1);cv::inRange(hsv, lower_red_2, upper_red_2, red_mask_2);red_mask = red_mask_1 + red_mask_2;// 将原图像和mask(掩膜)进行按位与cv::Mat blue_res;// 三通道图像进行单通道掩模操作后,输出图像还是三通道。相当于对三通道都做了掩模。cv::bitwise_and(origin_bgr_img, origin_bgr_img, blue_res, blue_mask);cv::Mat green_res;cv::bitwise_and(origin_bgr_img, origin_bgr_img, green_res, green_mask);cv::Mat red_res;cv::bitwise_and(origin_bgr_img, origin_bgr_img, red_res, red_mask);cv::Mat background_img = cv::Mat::zeros(1000, 1900, CV_8UC3);// #最后得到要分离出的颜色图像cv::Mat res = blue_res + green_res + red_res;{int x = 100, y = 40;cv::Rect roi(x, y, origin_bgr_img.cols, origin_bgr_img.rows);cv::putText(background_img, "origin", cv::Point(x, y - 10),cv::FONT_HERSHEY_PLAIN, 1, CV_RGB(255, 255, 255), 1);//将background_img复制到img中roi指定的矩形位置origin_bgr_img.copyTo(background_img(roi));}{int x = 500, y = 40;cv::Rect roi(x, y, res.cols, res.rows);cv::putText(background_img, "hsv", cv::Point(x, y - 10),cv::FONT_HERSHEY_PLAIN, 1, CV_RGB(255, 255, 255), 1);hsv.copyTo(background_img(roi));}{int x = 900, y = 40;cv::Rect roi(x, y, res.cols, res.rows);cv::putText(background_img, "res", cv::Point(x, y - 10),cv::FONT_HERSHEY_PLAIN, 1, CV_RGB(255, 255, 255), 1);res.copyTo(background_img(roi));}{int x = 100, y = 500;cv::Rect roi(x, y, blue_res.cols, blue_res.rows);cv::putText(background_img, "blue", cv::Point(x, y - 10),cv::FONT_HERSHEY_PLAIN, 1, CV_RGB(255, 255, 255), 1);blue_res.copyTo(background_img(roi));}{int x = 500, y = 500;cv::Rect roi(x, y, green_res.cols, green_res.rows);cv::putText(background_img, "green", cv::Point(x, y - 10),cv::FONT_HERSHEY_PLAIN, 1, CV_RGB(255, 255, 255), 1);green_res.copyTo(background_img(roi));}{int x = 900, y = 500;cv::Rect roi(x, y, red_res.cols, red_res.rows);cv::putText(background_img, "red", cv::Point(x, y - 10),cv::FONT_HERSHEY_PLAIN, 1, CV_RGB(255, 255, 255), 1);red_res.copyTo(background_img(roi));}cv::imwrite("pppp.png", background_img);std::string win_name = "background_img";cv::namedWindow(win_name, cv::WINDOW_KEEPRATIO);cv::imshow(win_name, background_img);cv::waitKey(0);
}

执行编译命令:

g++ test.cpp `pkg-config opencv --libs --cflags` -std=c++11  -o test

上面程序运行结果如下图:
在这里插入图片描述

值得说明的是:

  • hsv为3通道;
  • 掩模mask为单通道;
  • 提取颜色使用HSV方法,只是通过hsv获得掩模mask,得到的掩模mask是用来和BGR图像做掩模操作;
  • 三通道图像进行单通道掩模mask操作后,输出图像还是三通道,相当于对三通道都做了掩模mask。

cv::inRange()的用法:

void inRange(InputArray src, InputArray lowerb, InputArray upperb,OutputArray dst);
src:输入图像,CV2常用Mat类型;lowerb:下限,scalar类型的像素值,单通道scalar取一个值就行,彩图3通道scalar三个值;upperb:上限,类型与lowerb同理;dst:输出图像,尺寸与src一致,类型是CV_8U,但没有指定通道数。

对于多通道的输入,输出结果是各个通道的结果相,当各通道结果都在上下限之内时,输出为255,否则为0。因此也有人将输出理解为掩码模板!


cv::bitwise_and()按位与操作,此外还有bitwise_orbitwise_xorbitwise_not这四个按位操作函数:

void bitwise_and(InputArray src1, InputArray src2,OutputArray dst, InputArray mask=noArray());//dst = src1 & src2void bitwise_or(InputArray src1, InputArray src2,OutputArray dst, InputArray mask=noArray());//dst = src1 | src2void bitwise_xor(InputArray src1, InputArray src2,OutputArray dst, InputArray mask=noArray());//dst = src1 ^ src2void bitwise_not(InputArray src, OutputArray dst,InputArray mask=noArray());//dst = ~src

bitwise_and是对二进制数据进行“与”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“与”操作,1&1=11&0=00&1=00&0=0;

bitwise_or是对二进制数据进行“或”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“或”操作,1|1=11|0=00|1=00|0=0;

bitwise_xor是对二进制数据进行“异或”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“异或”操作,1^1=0,1^0=1,0^1=1,0^0=0;

bitwise_not是对二进制数据进行“非”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“非”操作,~1=0~0=1;

这篇关于【opencv】17.提取RBG各种颜色c++代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1067551

相关文章

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

C/C++错误信息处理的常见方法及函数

《C/C++错误信息处理的常见方法及函数》C/C++是两种广泛使用的编程语言,特别是在系统编程、嵌入式开发以及高性能计算领域,:本文主要介绍C/C++错误信息处理的常见方法及函数,文中通过代码介绍... 目录前言1. errno 和 perror()示例:2. strerror()示例:3. perror(

C++变换迭代器使用方法小结

《C++变换迭代器使用方法小结》本文主要介绍了C++变换迭代器使用方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、源码2、代码解析代码解析:transform_iterator1. transform_iterat

详解C++中类的大小决定因数

《详解C++中类的大小决定因数》类的大小受多个因素影响,主要包括成员变量、对齐方式、继承关系、虚函数表等,下面就来介绍一下,具有一定的参考价值,感兴趣的可以了解一下... 目录1. 非静态数据成员示例:2. 数据对齐(Padding)示例:3. 虚函数(vtable 指针)示例:4. 继承普通继承虚继承5.

C++中std::distance使用方法示例

《C++中std::distance使用方法示例》std::distance是C++标准库中的一个函数,用于计算两个迭代器之间的距离,本文主要介绍了C++中std::distance使用方法示例,具... 目录语法使用方式解释示例输出:其他说明:总结std::distance&n编程bsp;是 C++ 标准

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

使用C#代码在PDF文档中添加、删除和替换图片

《使用C#代码在PDF文档中添加、删除和替换图片》在当今数字化文档处理场景中,动态操作PDF文档中的图像已成为企业级应用开发的核心需求之一,本文将介绍如何在.NET平台使用C#代码在PDF文档中添加、... 目录引言用C#添加图片到PDF文档用C#删除PDF文档中的图片用C#替换PDF文档中的图片引言在当

详解C#如何提取PDF文档中的图片

《详解C#如何提取PDF文档中的图片》提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使用,下面我们就来看看如何使用C#通过代码从PDF文档中提取图片吧... 当 PDF 文件中包含有价值的图片,如艺术画作、设计素材、报告图表等,提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使

C#使用SQLite进行大数据量高效处理的代码示例

《C#使用SQLite进行大数据量高效处理的代码示例》在软件开发中,高效处理大数据量是一个常见且具有挑战性的任务,SQLite因其零配置、嵌入式、跨平台的特性,成为许多开发者的首选数据库,本文将深入探... 目录前言准备工作数据实体核心技术批量插入:从乌龟到猎豹的蜕变分页查询:加载百万数据异步处理:拒绝界面

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放