c语言数字图像处理(十):阈值处理
定义
全局阈值处理
假设某一副灰度图有如下的直方图,该图像由暗色背景下的较亮物体组成,从背景中提取这一物体时,将阈值T作为分割点,分割后的图像g(x, y)由下述公式给出,称为全局阈值处理


多阈值处理


本文仅完成全局阈值处理的算法实现
基本全局阈值处理方法
1. 为全局阈值T选择一个初始的估计值
2. 用T分割图像,产生两组像素:G1由大于T的像素组成,G2由小于T的像素组成
3. 对G1和G2的像素分别计算平均灰度值m1和m2
4. 计算新的阈值T = 1/2 * (m1 + m2)
5. 重复步骤2-4,直到连续迭代中的T值差小于一个预定义的参数ΔT
算法实现
void threshold(short** in_array, short** out_array, long height, long width, int delt_t)
{
double T = 0xff / 2.0;
double m1 = 0.0, m2 = 0.0;
int m1_num = , m2_num = ; while(dabs(T, 0.5*(m1 + m2)) > delt_t){
T = 0.5 * (m1 + m2);
m1 = 0.0;
m2 = 0.0;
m1_num = ;
m2_num = ; for (int i = ; i < height; i++){
for (int j = ; j < width; j++){
if (in_array[i][j] <= T){
m1 += in_array[i][j];
m1_num++;
}
else{
m2 += in_array[i][j];
m2_num++;
}
}
}
if (m1_num != )
m1 /= m1_num;
if (m2_num != )
m2 /= m2_num;
printf("%lf\n", T);
}
for (int i = ; i < height; i++){
for (int j = ; j < width; j++){
if (in_array[i][j] <= T)
out_array[i][j] = 0xff;
else
out_array[i][j] = 0x00;
}
}
}
测试结果


从实验结果看出,第二组阈值处理的效果并不好,因此考虑更优的算法实现
Otsu方法进行最佳全局阈值处理
阈值处理可视为一种统计决策理论问题,其目的是在把像素分配给两个或多个组的过程中引入的平均误差最小。这一问题有个闭合形式的解,称为贝叶斯决策规则。
Otsu方法在类间方差最大的情况下是最佳的
算法执行流程

代码实现
double dabs(double a, double b)
{
if (a < b)
return b-a;
else
return a-b;
} void calculate_histogram(long height, long width, short **image, unsigned long histogram[])
{
short k;
for(int i=; i < height; i++){
for(int j=; j < width; j++){
k = image[i][j];
histogram[k] = histogram[k] + ;
}
}
} void calculate_pi(long height, long width, unsigned long histogram[], double pi[])
{
for (int i = ; i < GRAY_LEVELS; ++i){
pi[i] = (double)histogram[i] / (double)(height * width);
}
} double p1(int k, double pi[])
{
double sum = 0.0; for (int i = ; i <= k; i++){
sum += pi[i];
} return sum;
} double m(int k, double pi[])
{
double sum = 0.0; for (int i = ; i <= k; i++){
sum += i * pi[i];
} return sum;
} double calculate_sigma(int k, double mg, double pi[])
{
double p1k = p1(k, pi);
double mk = m(k, pi); if (p1k < 1e- || ( - p1k) < 1e-)
return 0.0;
else
return pow(mg * p1k - mk, ) / (p1k * ( - p1k));
} void otsu(short** in_array, short** out_array, long height, long width)
{
unsigned long histogram[GRAY_LEVELS] = {};
double pi[GRAY_LEVELS] = {};
double sigma[GRAY_LEVELS] = {};
double mg;
short max_count = ;
short k = ;
double max_value = 0.0;
double k_star; calculate_histogram(height, width, in_array, histogram);
calculate_pi(height, width, histogram, pi);
mg = m(GRAY_LEVELS-, pi); for (int i = ; i < GRAY_LEVELS; i++)
sigma[i] = calculate_sigma(i, mg, pi); max_value = sigma[];
max_count = ;
k = ;
for (int i = ; i < GRAY_LEVELS; i++){
if (dabs(sigma[i], max_value) < 1e-){
k += i;
max_count++;
}
else if (sigma[i] > max_value){
max_value = sigma[i];
max_count = ;
k = i;
}
}
k_star = k / max_count; printf("%lf\n", k_star);
for (int i = ; i < height; i++){
for (int j = ; j < width; j++){
if (in_array[i][j] <= k_star)
out_array[i][j] = 0x00;
else
out_array[i][j] = 0xff;
}
}
}
结果

c语言数字图像处理(十):阈值处理的更多相关文章
- c语言数字图像处理(三):仿射变换
仿射变换及坐标变换公式 几何变换改进图像中像素间的空间关系.这些变换通常称为橡皮模变换,因为它们可看成是在一块橡皮模上印刷一幅图像,然后根据预定的一组规则拉伸该薄膜.在数字图像处理中,几何变换由两个基 ...
- c语言数字图像处理(九):边缘检测
背景知识 边缘像素是图像中灰度突变的像素,而边缘是连接边缘像素的集合.边缘检测是设计用来检测边缘像素的局部图像处理方法. 孤立点检测 使用<https://www.cnblogs.com/Gol ...
- c语言数字图像处理(五):空间滤波
空间滤波原理 使用大小为m*n的滤波器对大小为M*N的图像进行线性空间滤波,将滤波器模板乘以图像中对应灰度值,相加得模板中心灰度值 a = (m-1)/2, b = (n-1)/2 若f(x+s, y ...
- c语言数字图像处理(二):图片放大与缩小-双线性内插法
图像内插 假设一幅大小为500 * 500的图像扩大1.5倍到750 * 750,创建一个750 * 750 的网格,使其与原图像间隔相同,然后缩小至原图大小,在原图中寻找最接近的像素(或周围的像素) ...
- c语言数字图像处理(一):bmp图片格式及灰度图片转换
本篇文章首先介绍了bmp图片格式,主要参考wiki上的内容,包括bmp文件的存储方式,对于一些常见的bmp文件格式都给了例子,并且对8位 16位RGB555 16位RGB565格式的bmp文件进行了简 ...
- c语言数字图像处理(八):噪声模型及均值滤波器
图像退化/复原过程模型 高斯噪声 PDF(概率密度函数) 生成高斯随机数序列 算法可参考<http://www.doc.ic.ac.uk/~wl/papers/07/csur07dt.pdf&g ...
- c语言数字图像处理(七):频率域滤波
代码运行了两个小时才出的结果,懒得测试了,这一部分先鸽了,等对DFT算法进行优化后再更
- c语言数字图像处理(六):二维离散傅里叶变换
基础知识 复数表示 C = R + jI 极坐标:C = |C|(cosθ + jsinθ) 欧拉公式:C = |C|ejθ 有关更多的时域与复频域的知识可以学习复变函数与积分变换,本篇文章只给出DF ...
- c语言数字图像处理(四):灰度变换
灰度变换 灰度变换函数 s = T(r) 其中r为输入图像在(x, y)点处的灰度值,s为输出图像在(x, y)点处的灰度值 灰度变换的作用 上图所示的两幅T(s)函数的图像曲线,第一幅图可以增强 ...
随机推荐
- 【C#】#102 发送邮件
项目需求:定时的发送邮件,于是学习了如何发送邮件 下面有一个简单的例子.能够实现简单的发送邮件,加上附件可以添加一个属性[Attachment],然后配置上附件的路径 Demo下载 代码总共只有一下这 ...
- Alpha 冲刺报告(7/10)
Alpha 冲刺报告(7/10) 队名:洛基小队 峻雄(组长) 已完成:参考已有资源设计角色属性 明日计划:完善并编码 剩余任务:角色的属性脚本 困难:编码进展缓慢 -------------- 非易 ...
- ES6中map和set用法
ES6中map和set用法 --转载自廖雪峰的官方网站 一.map Map是一组键值对的结构,具有极快的查找速度. 举个例子,假设要根据同学的名字查找对应的成绩,如果用Array实现,需要两个Arra ...
- tomcat6 集群配置
1. 概要 web容器在做集群配置时,有3点需要注意: 1.1. 负载均衡配置: 1.2. session共享: 1.3. 若做的是单机集群(多个tomcat安装在同一台机器上),需要注意端口冲突问题 ...
- JVM内存区域划分Eden Space、Survivor Space、Tenured Gen,Perm Gen解释 (生动形象)
[转自]:https://blog.csdn.net/sd4015700/article/details/50109939 jvm区域总体分两类,heap区和非heap区.heap区又分:Eden S ...
- vue async/await同步 案例
1.async/await场景 这是一个用同步的思维来解决异步问题的方案,当前端接口调用需要等到接口返回值以后渲染页面时. 2.名词解释 >async async的用法,它作为一个关键字放到函数 ...
- Dictionary<string, object>
Dictionary<string, object> dcic = JsonHelper.DataRowFromJSON(resultdepth); foreach (var depthk ...
- arcgis api for javascript本地部署加载地图
最近开始学习arcgis api for javascript,发现一头雾水,决定记录下自己的学习过程. 一.下载arcgis api for js 4.2的library和jdk,具体安装包可以去官 ...
- Python学习之路 (一)开发环境搭建
前言 python3应该是Python的趋势所在,当然目前争议也比较大,这篇随笔的主要目的是记录在centos6.7下搭建python3环境的过程 以及碰到的问题和解决过程. 另外,如果本机安装了py ...
- C语言程序设计I—第十二周教学
第十二周教学总结(19/11-25/11) 教学内容 第4章 循环结构 4.5 循环结构程序设计 课前准备 在蓝墨云班课发布资源: PTA:2018秋第十二周作业4.5 分享码:B7FA52A13B6 ...