12RGB肤色区域检测器

 1. 在室内条件下,利用一些手和脸来建立RGB直方图;2. 利用函数cvCalcBackProject()找到肤色区域;3. 利用本书第五章图像处理相关函数来清除噪声,并利用函数cvFloodFill()找到图像中肤色最大区域。

具体代码如下:

#include <cv.h>
#include <highgui.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>using namespace std;CvPoint Current_Point;              //值为255点当前点 全局变量才可通过普通成员引用变更其值bool find_point(IplImage *img, char val);int main(int argc, char* argv[])
{IplImage* src1, *src2, *Imask, *rgb1, *rgb2, *Ithreshold, *Itemp, *Iclose, *Idst;   //源图像 HSVint threshold_type = CV_THRESH_BINARY;      //阈值类型CvPoint Last_Point;                         //值为255点的上一点//  CvPoint Current_Point;                  //值为255点当前点  为局部变量时,只能通过指针引用变更其值int Last_Area = 0;                          //上一个区域面积       int Current_Area = 0;                       //当前区域面积CvConnectedComp comp;                       //被填充区域统计属性Last_Point = cvPoint(0, 0);         //初始化上一点Current_Point = cvPoint(0, 0);      //初始化当前点if (!(src1 = cvLoadImage("D:\\Template\\OpenCV\\Template56_RGB_BackProjection\\Debug\\handdd.jpg")))return -1;if (!(src2 = cvLoadImage("D:\\Template\\OpenCV\\Template56_RGB_BackProjection\\Debug\\handd.jpg")))return -2;//此处调入图像掩码应为单通道if (!(Imask = cvLoadImage("D:\\Template\\OpenCV\\Template56_RGB_BackProjection\\Debug\\Imask.jpg", CV_LOAD_IMAGE_GRAYSCALE)))return -3;//cvXorS(Imask, cvScalar(255), Imask);      //掩码图像按位异或,求反生成新的掩码处理背景色//cvSet(src1, cvScalarAll(0), Imask);       //背景变黑只提取肤色rgb1 = cvCreateImage(cvGetSize(src1), src1->depth, src1->nChannels);rgb2 = cvCreateImage(cvGetSize(src2), src2->depth, src2->nChannels);cvCvtColor(src1, rgb1, CV_BGR2RGB); //源图像->HSV格式图像cvCvtColor(src2, rgb2, CV_BGR2RGB); //源图像->HSV格式图像//反向投影图像IplImage *back_projection = cvCreateImage(cvGetSize(src2), IPL_DEPTH_8U, 1);//阈值化 开运算图像Ithreshold=cvCreateImage(cvGetSize(src2), IPL_DEPTH_8U, 1);Itemp = cvCreateImage(cvGetSize(src2), IPL_DEPTH_8U, 1);Iclose = cvCreateImage(cvGetSize(src2), IPL_DEPTH_8U, 1);//最终目标区域图像Idst = cvCreateImage(cvGetSize(src2), IPL_DEPTH_8U, 1);//RGBIplImage *r_plane_1 = cvCreateImage(cvSize(rgb1->width, rgb1->height), IPL_DEPTH_8U, 1);IplImage *g_plane_1 = cvCreateImage(cvSize(rgb1->width, rgb1->height), IPL_DEPTH_8U, 1);IplImage *b_plane_1 = cvCreateImage(cvSize(rgb1->width, rgb1->height), IPL_DEPTH_8U, 1);IplImage *r_plane_2 = cvCreateImage(cvSize(rgb2->width, rgb2->height), IPL_DEPTH_8U, 1);IplImage *g_plane_2 = cvCreateImage(cvSize(rgb2->width, rgb2->height), IPL_DEPTH_8U, 1);IplImage *b_plane_2 = cvCreateImage(cvSize(rgb2->width, rgb2->height), IPL_DEPTH_8U, 1);IplImage *planes1[] = { r_plane_1, g_plane_1, b_plane_1 };                      //色相饱和度数组IplImage *planes2[] = { r_plane_2, g_plane_2, b_plane_2 };                      //色相饱和度数组cvCvtPixToPlane(rgb1, r_plane_1, g_plane_1, b_plane_1, NULL);       //图像分割cvCvtPixToPlane(rgb2, r_plane_2, g_plane_2, b_plane_2, NULL);       //图像分割//cvSplit(hsv, h_plane, s_plane, v_plane, NULL);int r_bins = 32, g_bins = 32, b_bins = 32;//建立直方图CvHistogram *hist_model,*hist_test;int hist_size[] = { r_bins, g_bins, b_bins };       //对应维数包含bins个数的数组float r_ranges[] = { 0, 255 };                      //R通道划分范围 float g_ranges[] = { 0, 255 };                      //G通道划分范围float b_ranges[] = { 0, 255 };                      //R通道划分范围 float* ranges[] = { r_ranges, g_ranges, b_ranges }; //划分范围数对,均匀bin,range只要最大最小边界hist_model = cvCreateHist(3, hist_size, CV_HIST_ARRAY, ranges, 1);hist_test = cvCreateHist(3, hist_size, CV_HIST_ARRAY, ranges, 1);//创建直方图 (维数,对应维数bins个数,密集矩阵方式存储,划分范围数对,均匀直方图)cvCalcHist(planes1, hist_model, 0, Imask);  //计算直方图(图像,直方图结构,不累加,掩码)cvCalcHist(planes2, hist_test, 0, 0);       //计算直方图(图像,直方图结构,不累加,掩码)//cvNormalizeHist(hist_model, 1.0);         //直方图归一化//cvNormalizeHist(hist_test, 1.0);          //直方图归一化cvCalcBackProject(planes2, back_projection, hist_model);        //像素点的反射投影//cvErode(back_projection, back_projection, NULL);              //腐蚀cvDilate(back_projection, back_projection, NULL);               //膨胀cvThreshold(back_projection, Ithreshold, 100, 255, threshold_type); //二值阈值化//闭运算,去除小暗区域,亮区域联结 NULL:3*3参考点为中心的核cvMorphologyEx(Ithreshold, Iclose, Itemp, NULL, CV_MOP_CLOSE, 1);cvNamedWindow("Mask", 1);cvNamedWindow("Model", 1);cvNamedWindow("Test", 1);cvNamedWindow("BACK_Projection", 1);cvNamedWindow("Threshhold", 1);cvNamedWindow("Iclose", 1);cvShowImage("Mask", Imask);cvShowImage("Model", src1);cvShowImage("Test", src2);cvShowImage("BACK_Projection", back_projection);cvShowImage("Threshhold", Ithreshold);cvShowImage("Iclose", Iclose);//漫水填充 获得手掌目标区域  效果不明显 图中没有太多噪声 闭运算后已达到要求cvNamedWindow("Destination", 1);cvCopy(Iclose, Idst);             //复制生成手掌目标图像do{if (find_point(Idst, 255))    //找像素值为255的像素点{cout << " X: " << Current_Point.x << " Y: " << Current_Point.y << endl;cvFloodFill(Idst, Current_Point, cvScalar(100), cvScalar(0), cvScalar(0),&comp, 8 | CV_FLOODFILL_FIXED_RANGE);           //对值为255的点进行漫水填充,值100Current_Area = comp.area;                           //当前区域面积if (Last_Area<Current_Area)                         //当前区域大于上一区域,上一区域清0{if (Last_Area>0)cvFloodFill(Idst, Last_Point, cvScalar(0), cvScalar(0), cvScalar(0),&comp, 8 | CV_FLOODFILL_FIXED_RANGE);   //上一区域赋值0cvShowImage("Destination", Idst);cvWaitKey(500);Last_Area = Current_Area;                               //当前区域赋值给上一区域Last_Point = Current_Point;                             //当前点赋值给上一点//memcpy(&Last_Point, &Current_Point, sizeof(CvPoint)); //错误,此方法复制无法正常使用掩码}else                                                //当前区域小于等于上一区域,当前区域清0{if (Current_Area>0)cvFloodFill(Idst, Current_Point, cvScalar(0), cvScalar(0), cvScalar(0),&comp, 8 | CV_FLOODFILL_FIXED_RANGE);   //当前区域赋值0cvShowImage("Destination", Idst);cvWaitKey(500);}}else                                                    //最后剩余的最大区域赋值255{cvFloodFill(Idst, Last_Point, cvScalar(255), cvScalar(0), cvScalar(0), &comp, 8 | CV_FLOODFILL_FIXED_RANGE);cvShowImage("Destination", Idst);cvWaitKey(500);//上一区域赋值0break;}} while (true);cvWaitKey(0);//system("pause");cvReleaseHist(&hist_model);cvReleaseHist(&hist_test);cvReleaseImage(&Imask);cvReleaseImage(&src1);cvReleaseImage(&src2);cvReleaseImage(&rgb1);cvReleaseImage(&rgb2);cvReleaseImage(&Ithreshold);cvReleaseImage(&Itemp);cvReleaseImage(&Iclose);cvReleaseImage(&Idst);cvReleaseImage(&r_plane_1);cvReleaseImage(&g_plane_1);cvReleaseImage(&b_plane_1);cvReleaseImage(&r_plane_2);cvReleaseImage(&g_plane_2);cvReleaseImage(&b_plane_2);cvReleaseImage(&back_projection);cvDestroyAllWindows();
}/******************遍历图像,指针算法********************/
//bool find_point(IplImage *img, char val,CvPoint* P_point)
bool find_point(IplImage *img, char val)
{char* ptr = NULL;//uchar* ptr = NULL;                    /**********    错,CvMat中为uchar* IplImage中为char*     ********/if (img->nChannels == 1){ptr = img->imageData;//ptr = (uchar*)img->imageData;/**********    错,CvMat中为uchar* IplImage中为char*     ********/if (ptr != NULL){for (int i = 0; i < img->height; i++)       //矩阵指针行寻址{ptr = (img->imageData + i*(img->widthStep));   //i 行 j 列//ptr = (uchar*)img->imageData + i*img->widthStep;   //index1 行 index2 列    /**********    错,mat中为uchar* IplImage中为char*     ********/for (int j = 0; j < img->width; j++)    //矩阵指针列寻址{//if (ptr[j] == 255)            /********错误  ptr对应的值为char型********/if (ptr[j] == val)              //判断某点像素是否为255{//P_point->x = j;               //列 ****Notice x为列坐标,若为行坐标会出现问题//P_point->y = i;               //行Current_Point.x = j;            /********局部变量此方式 无法实现赋值********/Current_Point.y = i;//cout << " j: " << j << " i: " << i << endl;//cout << " X: " << P_point->x << " Y: " << P_point->y << endl;//cout << " j: " <<j<< " i: " << i << endl;//cout << " X: " << Current_Point.x << " Y: " << Current_Point.y << endl;return true;}}}}}return false;
}

结果图片:

12RGB肤色区域检测器相关推荐

  1. 11肤色“场景检测器”

    11肤色"场景检测器" 1. 从室内.室外阴影和室外阳光下得到的第一类直方图作为模型,用其中每一个分别跟第二类图进行B距离测试,检验肤色匹配效果: 2. 利用(1)中设计的&quo ...

  2. Python人体肤色区域提取

    单张图片处理 import cv2 import matplotlib.pyplot as plt# 肤色检测之一: YCrCb之Cr分量 + OTSU二值化 imname = './hand/0.j ...

  3. 基于色度或其他彩色属性设计一个简单的肤色检测器

    要求:肤色检测 基于色度或其它彩色属性设计一个简单的肤色检测器. 用手机自拍一张人脸图像. 剪切照片或另外用画笔工具拾取那些可能是肤色的像素(人脸部位). 对这些肤色像素计算彩色分布,如彩色直方图.( ...

  4. 基于肤色空间建模+连通域处理的人脸检测算法的MATLAB仿真

    目录 1.算法仿真效果 2.MATLAB核心程序 3.算法涉及理论知识概要 4.完整MATLAB 1.算法仿真效果 matlab2022a仿真结果如下: 2.MATLAB核心程序 .......... ...

  5. opencv学习笔记(二):基于肤色的人手检测

    opencv学习笔记(二):基于肤色的人手检测 原文:http://blog.csdn.net/wzmsltw/article/details/50849810 先写了人手的检测程序,下一步基于检测程 ...

  6. 肤色检测算法 - 基于二次多项式混合模型的肤色检测

    1.二次多项式混合模型 二次多项式混合模型首先有SORIANO提出,此后CHIANG对此进行了改进.改进后的模型由两个R-G平面的二次多项式和一个圆方程构成: 在以上三个方程的基础上,肤色区域可以通过 ...

  7. 吃瓜笔记 | 旷视研究院:被遮挡人脸区域检测的技术细节(PPT+视频)

    主讲人:袁野 | 旷视研究院研究员 屈鑫 编辑整理 量子位 出品 | 公众号 QbitAI 12月27日晚,量子位·吃瓜社联合Face++论文解读系列第四期开讲,本期中旷视(Megvii)研究院解读了 ...

  8. opencv图像处理学习(六十八)——肤色检测

    参考链接:https://blog.csdn.net/qq_22527639/article/details/81501565. 1.肤色检测   肤色检测技术利用了计算机对人体皮肤像素的分析过程,随 ...

  9. 基于肤色高斯概率模型的人脸检测

    肤色高斯概率模型,主要将颜色空间从RGB转换为YCrCb,计算肤色的相似度,确定根据概率阈值筛选出肤色区域.但高斯概率模型中肤色均值及协方差矩阵需要提前确定,并且肤色均值对检测结果影响非常大,需要根据 ...

最新文章

  1. HTML的标签描述6
  2. (转)android UI进阶之用ViewPager实现欢迎引导页面
  3. PMCAFF|百度客户端产品:高效开发客户端产品的正确姿势
  4. 容器必须设置宽度吗_UI设计必须要具备的前端知识
  5. 一元流量显示服务器繁忙,流量充不进去老退款
  6. 如何开展灰盒测试[1]:灰盒测试优缺点分析
  7. Linux 指令篇:文档编辑--col
  8. powershell目录带空格_powershell - 如何在命令行的路径中运行带有空格的powershell脚本? - SO中文参考 - www.soinside.com...
  9. 下拉式菜单在GridView编辑时联动选择
  10. 本周日直播丨Oracle 多租户容器数据库体系结构
  11. 磁珠 符号_磁珠的主要功能是什么
  12. ext4文件系统制作 - make_ext4fs 参数介绍【转】
  13. 2022年R2移动式压力容器充装操作证考试题库及答案
  14. jieba / hanlp / ltp / standforCorenlp 分词器对比
  15. 字幕基础:字幕介绍、字幕种类及常见格式
  16. STM32通过SD卡IAP
  17. Git介绍、安装、环境配置及常用的Git命令
  18. 监控服务器时间无法修改怎么办,监控服务器目录修改时间
  19. Zotero修改英文文献的“等”为“et al”
  20. COUNTIF函数:

热门文章

  1. 牛客竞赛每日俩题 - Day1
  2. 通俗易懂说java设计模式-代理模式
  3. Django管理后台
  4. 快速、简洁且高效的博客框架hexo
  5. SecureCRT 8.5.4.1943 CRT中文版
  6. java double类型保留三位小数
  7. golang延时_Go 定时器/延时触发器
  8. 好用的任务管理工具有哪些?可以管理日常任务的便签
  9. 2021致自己一段话真实的话
  10. 这29家谷歌SEO公司超赚钱,涉及800亿美元