Ostu(大津法)二值化图像简介
来源:互联网 发布:学数据库有前途吗 编辑:程序博客网 时间:2024/06/16 04:27
一、前言
Ostu方法又名最大类间差方法,通过统计整个图像的直方图特性来实现全局阈值T的自动选取,其算法步骤为:
1) 先计算图像的直方图,即将图像所有的像素点按照0~255共256个bin,统计落在每个bin的像素点数量
2) 归一化直方图,也即将每个bin中像素点数量除以总的像素点
3) i表示分类的阈值,也即一个灰度级,从0开始迭代
4) 通过归一化的直方图,统计0~i 灰度级的像素(假设像素值在此范围的像素叫做前景像素) 所占整幅图像的比例w0,并统计前景像素的平均灰度u0;统计i~255灰度级的像素(假设像素值在此范围的像素叫做背景像素) 所占整幅图像的比例w1,并统计背景像素的平均灰度u1;
5) 计算前景像素和背景像素的方差 g = w0*w1*(u0-u1) (u0-u1)
6) i++;转到4),直到i为256时结束迭代
7)将最大g相应的i值作为图像的全局阈值
二、实现代码
Ostu算法实现函数为下面中的int getOstu(const Mat& in),其实在opencv中已经在threshold中实现了,下面代码也比较了两者的结果
#include "opencv2/core/core.hpp"#include "opencv2/highgui/highgui.hpp"#include "opencv2/imgproc/imgproc.hpp"using namespace cv;#include <iostream>int getOstu(const Mat & in);int main(){Mat img = imread("id_card.jpg" ,0);Mat img_high_Light = imread("id_card2.jpg" ,0);Mat dst , dst_HL;if(img.empty() | img_high_Light.empty()){std::cout<<"Error!!";return -1;}std::cout<<"The return value of getOstu is: "<<getOstu(img);std::cout<<"\n"<<"The return value of opencv threshold is: "<<threshold(img , dst ,0,255,CV_THRESH_OTSU);//opencv已实现的大津法imshow("光照均匀的原图像" ,img);imshow("图像光照均匀的处理结果" , dst);threshold(img_high_Light , dst_HL ,0,255,CV_THRESH_OTSU);imshow("光照不均匀的原图像" ,img_high_Light );imshow("图像光照不均匀的处理结果", dst_HL);waitKey(0);return 0;}int getOstu(const Mat & in){int rows = in.rows;int cols = in.cols;long size = rows * cols;float histogram[256] = {0}; for( int i = 0; i < rows; ++i) { //获取第 i行首像素指针 const uchar * p = in.ptr<uchar>(i); //对第i 行的每个像素(byte)操作 for( int j = 0; j < cols; ++j ) {histogram[int(*p++)]++; }}int threshold; long sum0 = 0, sum1 = 0; //存储前景的灰度总和及背景灰度总和 long cnt0 = 0, cnt1 = 0; //前景的总个数及背景的总个数 double w0 = 0, w1 = 0; //前景及背景所占整幅图像的比例 double u0 = 0, u1 = 0; //前景及背景的平均灰度 double variance = 0; //最大类间方差 double maxVariance = 0; for(int i = 1; i < 256; i++) //一次遍历每个像素 { sum0 = 0; sum1 = 0; cnt0 = 0; cnt1 = 0; w0 = 0; w1 = 0; for(int j = 0; j < i; j++) { cnt0 += histogram[j]; sum0 += j * histogram[j]; } u0 = (double)sum0 / cnt0; w0 = (double)cnt0 / size; for(int j = i ; j <= 255; j++) { cnt1 += histogram[j]; sum1 += j * histogram[j]; } u1 = (double)sum1 / cnt1; w1 = 1 - w0; // (double)cnt1 / size; variance = w0 * w1 * (u0 - u1) * (u0 - u1); if(variance > maxVariance) { maxVariance = variance; threshold = i; } } return threshold; }三、运行结果
调用函数getOstu和调用threshold所得到的图像全局阈值如下,可看出两者的结果非常接近,如下所示:
当所处理图像光照均匀时,这时的分割效果较好,如下所示
当处理的图像存在高照不均匀时,则ostu处理效果不是很好
0 0
- Ostu(大津法)二值化图像简介
- 图像分割(大律法 OSTU法)
- 图像Ostu二值化原理及matlab实现代码
- Win8 Metro(C#)数字图像处理--2.55OSTU法图像二值化
- Opencv图像识别从零到精通(15)-----阈值分割、固定阈值Threshold、自适应阈值分割adaptiveThreshold、OSTU大津法
- 图像基本变换---图像二值化(包含OSTU/迭代法/统计法/双峰法/P分位法/最大熵法)
- 图像基本变换---图像二值化(包含OSTU/迭代法/统计法/双峰法/P分位法/最大熵法)
- 图像基本变换---图像二值化(包含OSTU/迭代法/统计法/双峰法/P分位法/最大熵法)
- (1)OSTU二值化
- ostu
- OSTU
- 基于直方图的图像全局二值化算法原理、实现--OSTU大律法
- 最大类间方差法、大津法(ostu)
- ostu大津法 自动阈值分割
- 自动得到二值化阀值 ostu大津法
- 数字图像处理之OSTU二值化
- 使用opencv进行Ostu二值化
- OSTU (大津算法)
- hibernate_刚开始犯的错!
- Hexo个人博客搭建问题之 './build/Release/DTraceProviderBindings'] code: 'MODULE_NOT_FOUND'
- android activity之间传递ArrayList<HashMap<String,Object>>
- 实时系统动态内存算法分析dsa(二)——TLSF代码分析
- mac mysql error You must reset your password using ALTER USER statement before executing this statem
- Ostu(大津法)二值化图像简介
- 图解Wireshark安装
- python phantomjs+ selenium2 抓取动态js网页(版本python2.7+)
- Intent 和 Intent 过滤器
- 9.进程间通信---信号量集
- PowerPoint2007不能撤消所做的更改
- python dict与json转换
- 123
- Android studio