otsu自适应阈值分割的算法描述和opencv实现,及其在肤色检测中的应用
更新时间:2024-02-02 20:14:02 阅读量: 教育文库 文档下载
- otsu算法推荐度:
- 相关推荐
otsu算法选择使类间方差最大的灰度值为阈值,具有很好的效果 算法具体描述见otsu论文,或冈萨雷斯著名的数字图像处理那本书 这里给出程序流程:
1、计算直方图并归一化histogram 2、计算图像灰度均值avgValue.
3、计算直方图的零阶w[i]和一级矩u[i]
4、计算并找到最大的类间方差(between-class variance)
variance[i]=(avgValue*w[i]-u[i])*(avgValue*w[i]-u[i])/(w[i]*(1-w[i])) 对应此最大方差的灰度值即为要找的阈值 5、用找到的阈值二值化图像
我在代码中做了一些优化,所以算法描述的某些地方跟程序并不一致 otsu代码,先找阈值,继而二值化 // implementation of otsu algorithm // author: onezeros(@yahoo.cn)
// reference: Rafael C. Gonzalez. Digital Image Processing Using MATLAB void cvThresholdOtsu(IplImage* src, IplImage* dst) {
int height=src->height; int width=src->width;
//histogram
float histogram[256]= {0}; for(int i=0; i unsigned char* p=(unsigned char*)src->imageData+src->widthStep*i; for(int j=0; j histogram[*p++]++; } } //normalize histogram int size=height*width; for(int i=0; i<256; i++) { histogram[i]=histogram[i]/size; } //average pixel value float avgValue=0; for(int i=0; i<256; i++) { avgValue+=i*histogram[i]; } int threshold; float maxVariance=0; float w=0,u=0; for(int i=0; i<256; i++) { w+=histogram[i]; u+=i*histogram[i]; float t=avgValue*w-u; float variance=t*t/(w*(1-w)); if(variance>maxVariance) { maxVariance=variance; threshold=i; } } cvThreshold(src,dst,threshold,255,CV_THRESH_BINARY); } // implementation of otsu algorithm // author: onezeros(@yahoo.cn) // reference: Rafael C. Gonzalez. Digital Image Processing Using MATLAB void cvThresholdOtsu(IplImage* src, IplImage* dst) { int height=src->height; int width=src->width; //histogram float histogram[256]= {0}; for(int i=0; i unsigned char* p=(unsigned char*)src->imageData+src->widthStep*i; for(int j=0; j histogram[*p++]++; } } //normalize histogram int size=height*width; for(int i=0; i<256; i++) { histogram[i]=histogram[i]/size; } //average pixel value float avgValue=0; for(int i=0; i<256; i++) { avgValue+=i*histogram[i]; } int threshold; float maxVariance=0; float w=0,u=0; for(int i=0; i<256; i++) { w+=histogram[i]; u+=i*histogram[i]; float t=avgValue*w-u; float variance=t*t/(w*(1-w)); if(variance>maxVariance) { maxVariance=variance; threshold=i; } } cvThreshold(src,dst,threshold,255,CV_THRESH_BINARY); } 更多情况下我们并不需要对每一帧都是用otsu寻找阈值,于是可以先找到阈值,然后用找到的阈值处理后面的图像。下面这个函数重载了上面的,返回值就是阈值。只做了一点改变 // implementation of otsu algorithm // author: onezeros(@yahoo.cn) // reference: Rafael C. Gonzalez. Digital Image Processing Using MATLAB int cvThresholdOtsu(IplImage* src) { int height=src->height; int width=src->width; //histogram float histogram[256]= {0}; for(int i=0; i unsigned char* p=(unsigned char*)src->imageData+src->widthStep*i; for(int j=0; j histogram[*p++]++; } } //normalize histogram int size=height*width; for(int i=0; i<256; i++) { histogram[i]=histogram[i]/size; } //average pixel value float avgValue=0; for(int i=0; i<256; i++) { avgValue+=i*histogram[i]; } int threshold; float maxVariance=0; float w=0,u=0; for(int i=0; i<256; i++) { w+=histogram[i]; u+=i*histogram[i]; float t=avgValue*w-u; float variance=t*t/(w*(1-w)); if(variance>maxVariance) { maxVariance=variance; threshold=i; } } return threshold; } // implementation of otsu algorithm // author: onezeros(@yahoo.cn) // reference: Rafael C. Gonzalez. Digital Image Processing Using MATLAB int cvThresholdOtsu(IplImage* src) { int height=src->height; int width=src->width; //histogram float histogram[256]= {0}; for(int i=0; i unsigned char* p=(unsigned char*)src->imageData+src->widthStep*i; for(int j=0; j histogram[*p++]++; } } //normalize histogram int size=height*width; for(int i=0; i<256; i++) { histogram[i]=histogram[i]/size; } //average pixel value float avgValue=0; for(int i=0; i<256; i++) { avgValue+=i*histogram[i]; } int threshold; float maxVariance=0; float w=0,u=0; for(int i=0; i<256; i++) { w+=histogram[i]; u+=i*histogram[i]; float t=avgValue*w-u; float variance=t*t/(w*(1-w)); if(variance>maxVariance) { maxVariance=variance; threshold=i; } } return threshold; } 我在手的自动检测中使用这个方法,效果很好。 下面是使用上述两个函数的简单的主程序,可以试运行一下,如果处理视频,要保证第一帧时,手要在图像中。 #include #pragma comment(lib,\#pragma comment(lib,\#pragma comment(lib,\ #include int main(int argc, char** argv) { #ifdef VIDEO //video process CvCapture* capture=cvCreateCameraCapture(-1); if (!capture) { cout<<\ exit(0); } int threshold=-1; IplImage* img; while (img=cvQueryFrame(capture)) { cvShowImage(\ cvCvtColor(img,img,CV_RGB2YCrCb); IplImage* imgCb=cvCreateImage(cvGetSize(img),8,1); cvSplit(img,NULL,NULL,imgCb,NULL); if (threshold<0) { threshold=cvThresholdOtsu(imgCb); } //cvThresholdOtsu(imgCb,imgCb); cvThreshold(imgCb,imgCb,threshold,255,CV_THRESH_BINARY); cvErode(imgCb,imgCb); cvDilate(imgCb,imgCb); cvShowImage(\ cvReleaseImage(&imgCb); if (cvWaitKey(3)==27) //esc { break; } } cvReleaseCapture(&capture); #else //single image process const char* filename=(argc>=2?argv[1]:\ IplImage* img=cvLoadImage(filename,CV_LOAD_IMAGE_GRAYSCALE); cvThresholdOtsu(img,img); cvShowImage( \ char buf[256]; sprintf_s(buf,256,\ cvSaveImage(buf,img); cvErode(img,img); cvDilate(img,img); cvShowImage( \ sprintf_s(buf,256,\ cvSaveImage(buf,img); cvWaitKey(0); #endif return 0; } #include #pragma comment(lib,\#pragma comment(lib,\#pragma comment(lib,\#include using namespace std; int main(int argc, char** argv) { #ifdef VIDEO //video process CvCapture* capture=cvCreateCameraCapture(-1); if (!capture) { cout<<\ exit(0); } int threshold=-1; IplImage* img; while (img=cvQueryFrame(capture)) { cvShowImage(\ cvCvtColor(img,img,CV_RGB2YCrCb); IplImage* imgCb=cvCreateImage(cvGetSize(img),8,1); cvSplit(img,NULL,NULL,imgCb,NULL); if (threshold<0) { threshold=cvThresholdOtsu(imgCb); } //cvThresholdOtsu(imgCb,imgCb); cvThreshold(imgCb,imgCb,threshold,255,CV_THRESH_BINARY); cvErode(imgCb,imgCb); cvDilate(imgCb,imgCb); cvShowImage(\ cvReleaseImage(&imgCb); if (cvWaitKey(3)==27) //esc { break; } } cvReleaseCapture(&capture); #else //single image process const char* filename=(argc>=2?argv[1]:\ IplImage* img=cvLoadImage(filename,CV_LOAD_IMAGE_GRAYSCALE); cvThresholdOtsu(img,img); cvShowImage( \ char buf[256]; sprintf_s(buf,256,\ cvSaveImage(buf,img); cvErode(img,img); cvDilate(img,img); cvShowImage( \ sprintf_s(buf,256,\ cvSaveImage(buf,img); cvWaitKey(0); #endif return 0; }
正在阅读:
otsu自适应阈值分割的算法描述和opencv实现,及其在肤色检测中的应用02-02
公司管理人员非利用职务便利窃取公司财物可构成盗窃罪04-11
碎石桩施工技术交底108-11
镁合金连铸连轧工艺与设备设计02-04
2017年浙江省会计继续教育(东奥)10-03
年末工作总结,一年的收获03-13
铁路工程试验检测方案11-27
浅谈多媒体技术在体育教学中的作用06-07
证券模拟炒股实训报告1500字04-08
- exercise2
- 铅锌矿详查地质设计 - 图文
- 厨余垃圾、餐厨垃圾堆肥系统设计方案
- 陈明珠开题报告
- 化工原理精选例题
- 政府形象宣传册营销案例
- 小学一至三年级语文阅读专项练习题
- 2014.民诉 期末考试 复习题
- 巅峰智业 - 做好顶层设计对建设城市的重要意义
- (三起)冀教版三年级英语上册Unit4 Lesson24练习题及答案
- 2017年实心轮胎现状及发展趋势分析(目录)
- 基于GIS的农用地定级技术研究定稿
- 2017-2022年中国医疗保健市场调查与市场前景预测报告(目录) - 图文
- 作业
- OFDM技术仿真(MATLAB代码) - 图文
- Android工程师笔试题及答案
- 生命密码联合密码
- 空间地上权若干法律问题探究
- 江苏学业水平测试《机械基础》模拟试题
- 选课走班实施方案
- 阈值
- 肤色
- 算法
- 分割
- 适应
- 描述
- 检测
- 及其
- 实现
- 应用
- opencv
- otsu
- 光电工程(项目)安全预评价报告编制规定(水电规安办121号)
- 江西美术出版社五年级下册美术教案
- 2014-2015高中物理新课标选修3-1:单元测评(1)
- 某公司人力资源结构分析报告
- 2016注册咨询工程师继续教育PPP政策解析及制度建设试卷及答案119分
- 清华学长考研谈
- 针对发掘普通高中学生英语学习潜力的研究阶段性总结4(2012.09-2013.02)
- 2018年执业药师继续教育考试试题及答案
- 最新整理商业地产租金定价策略与测算方法
- 商英词汇
- 关于总包服务费、总包配合费、总包管理费
- 普兰店市涉河违法行为专项整治实施方案
- 计组实验4控制器实验
- 审计署办公厅关于印发《常见公文批示用语》的通知
- 办公室公文批示规范用语规则
- 牛津译林版2017-2018学年九年级(上)期末英语试卷及答案解析
- 宋德福:我走了,共青团- 武汉理工大学华夏学院
- 空气废气中苯并芘采样与检测方法
- “齐景公谓子贡曰”阅读答案附翻译
- 2016安全月试题