OpenCV颜色转换和皮肤检测
本笔记重点记录OpenCV中的颜色转换和利用色彩空间的特性进行皮肤检测
颜色转换
实现原理
之所以要引入色调/饱和度/亮度的色彩空间概念,是因为人们喜欢凭直觉分辨各种颜色,而它与这种方式吻合。实际上,人类更喜欢用色彩、彩度、亮度等直观的属性来描述颜色,而大多 数直觉色彩空间正是基于这三个属性。
- 色调(hue)表示主色,我们使用的颜色名称(例如绿色、 黄色和红色)就对应了不同的色调值;
- 饱和度(saturation)表示颜色的鲜艳程度,柔和的颜色饱 和度较低,而彩虹的颜色饱和度就很高
- 亮度(brightness)是一个主观的属性,表示某种 颜色的光亮程度。
其他直觉色彩空间使用颜色明度(value)或颜色亮度(lightness)的概念描述 有关颜色的强度。
利用这些颜色概念,能尽可能地模拟人类对颜色的直观感知。因此,它们没有标准的定义。 根据文献资料,色调、饱和度和亮度都有多种不同的定义和计算公式。OpenCV 建议的两种直觉 色彩空间的实现是 HSV 和 HLS 色彩空间,它们的转换公式略有不同,但是结果非常相似。
亮度成分可能是最容易解释的。在 OpenCV 对 HSV 的实现中,它被定义为三个 BGR 成分中 的最大值,以非常简化的方式实现了亮度的概念。为了让定义更符合人类视觉系统,应该使用均 匀感知的色彩空间 Lab和 Luv的 L 通道。举个例子,L 通道已经考虑到了,在强度相同的 情况下,人们会觉得绿色比蓝色等颜色的亮度更高。
OpenCV 用一个公式来计算饱和度,该公式基于 BGR 组件的最小值和最大值:
其原理是:灰度颜色包含的 R、G、B 的成分是相等的,相当于一种极不饱和的颜色,因此 它的饱和度是 0(饱和度是一个 0~1.0 的值)。对于 8 位图像,饱和度被调节成一个 0~255 的值, 并且作为灰度图像显示的时候,较亮区域对应的颜色具有较高的饱和度。
利用opencv把RGB图片像HSV颜色空间转变(CV_BGR2HSV)的时候,
H通道的值范围为: 0-180
S: 0-255
V:0-255
实现代码
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <vector>
int main()
{
// 读入图像
cv::Mat image= cv::imread("boldt.jpg");
if (!image.data)
return 0;
// 原始图像
cv::namedWindow("Original image");
cv::imshow("Original image",image);
// 转换成HSV色彩空间
cv::Mat hsv;
cv::cvtColor(image, hsv, CV_BGR2HSV);
// 把三个通道分割进三幅图像中
std::vector<cv::Mat> channels;
cv::split(hsv,channels);
// channels[0] 色调
// channels[1] 饱和度
// channels[2] 亮度
// 亮度
cv::namedWindow("Value");
cv::imshow("Value",channels[2]);
// display 饱和度
cv::namedWindow("Saturation");
cv::imshow("Saturation",channels[1]);
// display 色调
cv::namedWindow("Hue");
cv::imshow("Hue",channels[0]);
cv::waitKey();
}
实现效果
皮肤检测
8 位版本的色调在 0~180,饱和度在 0~255
实现原理
在对特定物体做初步检测时,颜色信息非常有用。例如辅助驾驶程序中的路标检测功能,就要凭借标准路标的颜色快速识别可能是路标的信息。另一个例子是肤色检测,检测到的皮肤区域 可作为图像中有人存在的标志。手势识别就经常使用肤色检测确定手的位置。
肤色检测领域的大量研究已经表明,来自不同人种的人群的皮肤颜色,可以在色调、饱和度、色彩空间中很好地归类。
实现代码
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <vector>
void detectHScolor(const cv::Mat& image, // input image
double minHue, double maxHue, // Hue interval
double minSat, double maxSat, // saturation interval
cv::Mat& mask) { // output mask
// convert into HSV space
cv::Mat hsv;
cv::cvtColor(image, hsv, CV_BGR2HSV);
// split the 3 channels into 3 images
std::vector<cv::Mat> channels;
cv::split(hsv, channels);
// channels[0] is the Hue
// channels[1] is the Saturation
// channels[2] is the Value
// Hue masking
cv::Mat mask1; // below maxHue
cv::threshold(channels[0], mask1, maxHue, 255, cv::THRESH_BINARY_INV);
cv::Mat mask2; // over minHue
cv::threshold(channels[0], mask2, minHue, 255, cv::THRESH_BINARY);
cv::Mat hueMask; // hue mask
if (minHue < maxHue)
hueMask = mask1 & mask2;
else // if interval crosses the zero-degree axis
hueMask = mask1 | mask2;
// Saturation masking
// below maxSat
cv::threshold(channels[1], mask1, maxSat, 255, cv::THRESH_BINARY_INV);
// over minSat
cv::threshold(channels[1], mask2, minSat, 255, cv::THRESH_BINARY);
cv::Mat satMask; // saturation mask
satMask = mask1 & mask2;
// combined mask
mask = hueMask&satMask;
}
int main()
{
// 读入图像
cv::Mat image= cv::imread("girl.jpg");
if (!image.data)
return 0;
// show original image
cv::namedWindow("Original image");
cv::imshow("Original image",image);
// detect skin tone
cv::Mat mask;
detectHScolor(image,
160, 10, // hue from 320 degrees to 20 degrees
25, 166, // saturation from ~0.1 to 0.65
mask);
// show masked image
cv::Mat detected(image.size(), CV_8UC3, cv::Scalar(0, 0, 0));
image.copyTo(detected, mask);
cv::imshow("Detection result",detected);
cv::waitKey();
}
实现效果
可改进的地方
在检测时没有考虑颜色的亮度。在实际应用中,排除较高亮度的颜色可以降低把明亮的淡红色误认为皮肤的可能性。所以要想对皮肤颜色进行可靠和准确的检测, 还需要更加精确的分析。对不同的图像进行检测,也很难保证效果都好,因为摄影时影响彩色再 现的因素有很多,如白平衡和光照条件等。
OpenCV颜色转换和皮肤检测的更多相关文章
- OpenCV探索之路(二十七):皮肤检测技术
好久没写博客了,因为最近都忙着赶项目和打比赛==| 好吧,今天我打算写一篇关于使用opencv做皮肤检测的技术总结.那首先列一些现在主流的皮肤检测的方法都有哪些: RGB color space Yc ...
- OpenCv皮肤检测-HSV分离
HSV皮肤检测 // 进行肤色检测 void SkinDetect(IplImage* src, IplImage* dst) { // 创建图像头 IplImage* hsv = cvCreateI ...
- 使用opencv进行简单的手势检测[by Python]
代码参考于:https://github.com/rainyear/lolita/issues/8 简单的手势识别,基本思路是基于皮肤检测,皮肤的颜色在HSV颜色空间下与周围环境的区分度更高,从RGB ...
- OpenCV 学习笔记 07 目标检测与识别
目标检测与识别是计算机视觉中最常见的挑战之一.属于高级主题. 本章节将扩展目标检测的概念,首先探讨人脸识别技术,然后将该技术应用到显示生活中的各种目标检测. 1 目标检测与识别技术 为了与OpenCV ...
- OpenCV实战:人脸关键点检测(FaceMark)
Summary:利用OpenCV中的LBF算法进行人脸关键点检测(Facial Landmark Detection) Author: Amusi Date: 2018-03-20 ...
- cvSmooth函数 和 OpenCV自带的人脸检测
记录cvSmooth函数的用法和 OpenCV自带的人脸检测. (1)cvSmooth函数 void cvSmooth( const CvArr* src, CvArr* dst,int smooth ...
- iOS中RGB颜色转换
iOS中RGB常用的色值,同时可将对颜色的设置定义成宏,方便开发应用,如: // RGB颜色转换(16进制->10进制) #define UIColorFromRGB(rgbValue) [UI ...
- UIColor各种颜色转换
1.Hex值颜色转换 #import <UIKit/UIKit.h> @interface UIColor (Extension) // 根据无符号的32位整数转换为对应的RGB颜色 + ...
- js颜色转换
很久之前面试遇到过一个题.写个颜色转换的方法. function RGB2Color(r,g,b) { return '#' + byte2Hex(r) + byte2Hex(g) + byte2He ...
随机推荐
- 【001】JS解析,反解析XML的一些问题
JS解析,反解析 XML 的一些问题 2016-03-25 15:38:28 星期五 文章底部下面有提供把 字符串 变成 XML 对象的方法. 该方法,在 Chrome48 ,FireFox ,IE1 ...
- debug的粗略使用(求大神们补充、指教,小渣马上改)
debug的使用 往往我们在写代码的时候会发现那种很隐秘的bug,一直找找不多,甚至开始怀疑人生.目光扫描和人脑编译又耗时又耗精力又很容易中途乱了脑子,一切得重新来,所以我写了一篇博客来模拟一下检查b ...
- JavaScript中操作有些DOM时关于文本节点和元素节点的问题。
初学JavaScript时候,经常遇到需要操作的内容因为文本节点而使操作更麻烦或者不能达到效果. 例: <ul id="ull"> <li>111&l ...
- P2245 星际导航
题目描述 sideman 做好了回到 Gliese星球的硬件准备,但是 sideman 的导航系统还没有完全设计好.为了方便起见,我们可以认为宇宙是一张有 N 个顶点和 M 条边的带权无向图,顶点表示 ...
- OpenCV——RGB和HSV颜色空间
RGB颜色空间 在RGB中,一幅图像有三个独立的图像平面或通道组成:红,绿,蓝(以及第四个通道透明度). RGB颜色表 资料:网络 ◇ 编制:王践舜 RGB(255,23,140)是光的三原色,也 ...
- PAT乙级1019
1019 数字黑洞 (20 分) 给定任一个各位数字不完全相同的 4 位正整数,如果我们先把 4 个数字按非递增排序,再按非递减排序,然后用第 1 个数字减第 2 个数字,将得到一个新的数字.一直 ...
- 学习笔记——OS——引论
学习笔记--OS--引论 操作系统的定义 操作系统是一组管理计算机硬件资源的软件集合: 用户和计算机硬件之间的接口 控制和管理硬件资源 实现对计算机资源的抽象 计算机系统硬件 冯诺依曼体系结构和哈佛结 ...
- hisi3559的usb无线网卡驱动(rtl8192cu)(一条龙服务:内核编译、驱动编译、iw等工具编译)
usb无线网卡驱动(rtl8192cu) 内核编译.驱动编译.iw等工具编译 (哈哈,如果有其他问题,麻烦留言:) 环境 板卡:hi3559av100(arm64) 交叉编译链:aarch64-hi ...
- C语言学习记录_2019.02.07
C99开始,可以用变量来定义数组的大小:例如,利用键盘输入的变量来定义数组大小: 赋值号左边的值叫做左值: 关于数组:编译器和运行环境不会检查数组下标是否越界,无论读还是写. 越界数组可能造成的问题提 ...
- 2017-2018-2 《网络对抗技术》20155322 Exp7 网络欺诈防范
[-= 博客目录 =-] 1-实践目标 1.1-实践介绍 1.2-实践内容 1.3-实践要求 2-实践过程 2.1-简单应用SET工具建立冒名网站 2.2-ettercap DNS spoof 2.3 ...