OpenCV彩色图像分割

OpenCV计算机视觉开发实践:基于Qt C++ - 商品搜索 - 京东

灰度图像大多通过算子寻找边缘和区域生长融合来分割图像。彩色图像增加了色彩信息,可以通过不同的色彩值来分割图像,常用彩色空间HSV/HIS、RGB、LAB等都可以用于分割。本节使用inRange函数来实现阈值化,跟前面的阈值化方法一样,只不过在实现时用阈值范围来替代固定阈值。inRange函数提供了一种物体检测的手段,用基于像素值范围的方法,在HSV色彩空间检测物体,从而达到分割的效果。

9-12所示是HSV圆柱体,表示HSV的颜色空间。HSV(Hue、Saturation、Value的首字母,分别表示颜色的色相、饱和度、强度)色彩空间是一种类似于RGB的颜色表示方式。Hue通道是颜色类型,在需要根据颜色来分割物体的应用中非常有效。Saturation的变化从不饱和到完全饱和,对应图9-12所示的灰色过度到阴影(没有白色成分)。Value描述了颜色的强度或者说亮度。

图9-12

HSV是一种比较直观的颜色模型,所以在许多图像编辑工具中应用比较广泛,这个模型中颜色的参数分别是:色调(H, Hue)、饱和度(S, Saturation)、明度(V, Value)。色调H用角度度量,取值范围为0°~360°,从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。它们的补色是:黄色为60°,青色为180°,品红为300°;饱和度S表示颜色接近光谱色的程度。一种颜色,可以看成是某种光谱色与白色混合的结果。其中光谱色所占的比例愈大,颜色接近光谱色的程度就愈高,颜色的饱和度也就愈高。饱和度高,颜色则深而艳。光谱色的白光成分为0,饱和度达到最高。通常取值范围为0%~100%,值越大,颜色越饱和。明度V表示颜色明亮的程度。对于光源色,明度值与发光体的光亮度有关;对于物体色,此值和物体的透射比或反射比有关。通常取值范围为0%(黑)到100%(白)。HSV颜色空间模型(圆锥模型)如图9-13所示。

图9-13

由于RGB色彩空间是由三个通道来编码颜色,所以难以根据颜色来分割物体,而HSV中只有Hue一个通道表示颜色。此时可以用函数cvtColor将BGR转换到HSV色彩空间,然后用函数inRange根据HSV设置的范围检测目标。该函数声明如下:

复制代码
void  inRange (InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst);

其中src表示输入图像;lowerb 表示H、S、V的最小值;upperb表示H、S、V的最大值;dst表示输出图像,要和输入图像有相同的尺寸且为CV_8U类。

OpenCV中的inRange()函数可实现二值化功能(这点类似threshold函数),更关键的是可以同时针对多通道进行操作。通俗来讲,这个函数就是判断src中每一个像素是否在[lowerb,upperb]之间,注意集合的开闭。如果结果为是,那么在dst相应像素位置填上255,反之则是0。一般我们把dst当作一个mask来用。对于单通道图像,如果一幅灰度图像的某个像素的灰度值在指定的高、低阈值范围之内,则在dst图像中令该像素值为255,否则令其为0,这样就生成了一幅二值化的输出图像。对于三通道图像,每个通道的像素值都必须在规定的阈值范围内。下面我们看一个用函数inRange进行颜色分割的例子。

【例9.5】直接用HSV体系进行颜色分割

(1)新建一个控制台工程,工程名是test。

(2)打开main.cpp,输入代码如下:

复制代码
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <opencv2/imgproc/types_c.h>
#include <iostream>
using namespace std;
using namespace cv;

//输入图像
Mat img;
//灰度值归一化
Mat bgr;
//HSV图像
Mat hsv;
//色相
int hmin = 0;
int hmin_Max = 360;
int hmax = 180;
int hmax_Max = 180;
//饱和度
int smin = 0;
int smin_Max = 255;
int smax = 255;
int smax_Max = 255;
//亮度
int vmin = 106;
int vmin_Max = 255;
int vmax = 255;
int vmax_Max = 255;
//显示原图的窗口
string windowName = "src";
//输出图像的显示窗口
string dstName = "dst";
//输出图像
Mat dst;
void callBack(int, void*)//回调函数
{
	dst = Mat::zeros(img.size(), img.type());	//输出图像分配内存
	Mat mask; //掩码
	inRange(hsv, Scalar(hmin, smin, vmin), Scalar(hmax, smax, vmax), mask);
	//掩模到原图的转换
	for (int r = 0; r < bgr.rows; r++)
		for (int c = 0; c < bgr.cols; c++)
			if (mask.at<uchar>(r, c) == 255)
				dst.at<Vec3b>(r, c) = bgr.at<Vec3b>(r, c);
	//输出图像
	imshow(dstName, dst);
	//保存图像
	//dst.convertTo(dst, CV_8UC3, 255.0, 0);
	imwrite("HSV_inRange.jpg", dst);
}
int main(int argc, char** argv)
{
	//输入图像
	img = imread("myclr.jpg");
	if (!img.data || img.channels() != 3)
		return -1;
	imshow(windowName, img);
	bgr = img.clone();
	//颜色空间转换
	cvtColor(bgr, hsv, CV_BGR2HSV);
	//定义输出图像的显示窗口
	namedWindow(dstName, WINDOW_GUI_EXPANDED);
	//调节色相 H
	createTrackbar("hmin", dstName, &hmin, hmin_Max, callBack);
	createTrackbar("hmax", dstName, &hmax, hmax_Max, callBack);
	//调节饱和度 S
	createTrackbar("smin", dstName, &smin, smin_Max, callBack);
	createTrackbar("smax", dstName, &smax, smax_Max, callBack);
	//调节亮度 V
	createTrackbar("vmin", dstName, &vmin, vmin_Max, callBack);
	createTrackbar("vmax", dstName, &vmax, vmax_Max, callBack);
	callBack(0, 0);
	waitKey(0);
	return 0;
}

代码中,我们首先载入图像,然后利用函数cvtColor进行颜色空间转换,转换为HSV颜色空间。接着我们为调节色相H、饱和度 S和亮度V分别创建了滑块,这样可以通过调节不同的颜色、饱和度、亮度区间来定义信息。最后调用了自定义函数callBack,callBack函数中调用inRange进行颜色分割。

(3)保存工程并运行,运行结果如图9-14所示。

图9-14

相关推荐
九年义务漏网鲨鱼1 小时前
【大模型学习 | MINIGPT-4原理】
人工智能·深度学习·学习·语言模型·多模态
元宇宙时间2 小时前
Playfun即将开启大型Web3线上活动,打造沉浸式GameFi体验生态
人工智能·去中心化·区块链
开发者工具分享2 小时前
文本音频违规识别工具排行榜(12选)
人工智能·音视频
产品经理独孤虾2 小时前
人工智能大模型如何助力电商产品经理打造高效的商品工业属性画像
人工智能·机器学习·ai·大模型·产品经理·商品画像·商品工业属性
老任与码2 小时前
Spring AI Alibaba(1)——基本使用
java·人工智能·后端·springaialibaba
蹦蹦跳跳真可爱5892 小时前
Python----OpenCV(图像増强——高通滤波(索贝尔算子、沙尔算子、拉普拉斯算子),图像浮雕与特效处理)
人工智能·python·opencv·计算机视觉
雷羿 LexChien3 小时前
从 Prompt 管理到人格稳定:探索 Cursor AI 编辑器如何赋能 Prompt 工程与人格风格设计(上)
人工智能·python·llm·编辑器·prompt
两棵雪松3 小时前
如何通过向量化技术比较两段文本是否相似?
人工智能
heart000_13 小时前
128K 长文本处理实战:腾讯混元 + 云函数 SCF 构建 PDF 摘要生成器
人工智能·自然语言处理·pdf
敲键盘的小夜猫3 小时前
LLM复杂记忆存储-多会话隔离案例实战
人工智能·python·langchain