文档章节

图像二值化(迭代法,C语言实现)

t
 tigerBin
发布于 2017/07/25 22:23
字数 389
阅读 27
收藏 0
点赞 0
评论 0

1. 随机确定一个初始阈值 k1 = 127(可以为随机值【0,255】)

2. 根据阈值k1把原始图像分为两部分(小于 k1 的像素部分,大于k1的背景部分),并分别求其均值avgPix, avgBac

3. 计算新的阈值 k2 = (avgPix + avgBac) / 2

4. 判断 k1 与 k2 是否相等,如果不等,则更新k1, 重新执行步骤2-3 直到 k1 == k2

5. 根据计算得到的阈值 k1 (或 k2) 对图像进行二值化


#include "JpegDecoder.h"
#include <stdio.h>
#include <opencv2/highgui.hpp>
#include <math.h>

using namespace JpegCodec;

static cv::Mat ConvertToMat(Matrix &mat)
{
	int channel = CV_8UC3;
	if (mat.channal == 1) channel = CV_8UC1;

	cv::Mat img(mat.rows, mat.cols, channel);  // create a new matrix

	for (int i = 0; i < mat.rows * mat.cols * mat.channal; i++)
	{
		img.data[i] = mat.data[i];
	}

	return img;
}


void ShowImage(Matrix &mat)
{
	cv::Mat img = ConvertToMat(mat);
	cv::imshow("Bitmap", img);
}


// 二值化
void Binary(Matrix &mat)
{
	int k1 = 127, k2 = 0;
	int cnt = mat.rows * mat.cols * mat.channal;

	// 计算阈值
	while (k1 != k2)
	{
		k2 = k1;
		int avgPix = 0;
		int avgBac = 0;
		int size = 0;
		for (int i = 0; i < cnt; i++)
		{
			if (mat.data[i] < k2)
			{
				avgPix += mat.data[i]; // 像素数据
				size++;
			}
			else 
				avgBac += mat.data[i]; // 背景数据
		}

		// 计算像素阈值 与 背景阈值
		avgPix /= size;
		avgBac /= (cnt - size);
		// 计算 k1
		k1 = (avgPix + avgBac) / 2;
	}

	// 二值化
	for (int i = 0; i < cnt; i++)
	{
		if (mat.data[i] < k1) mat.data[i] = 0;
		else mat.data[i] = 255;
	}
}


// 灰度化
void Gray(Matrix &dst, Matrix &src)
{
	dst.Create(src.rows, src.cols, 1);

	for (int i = 0; i < src.rows; i++)
	{
		for (int j = 0; j < src.cols; j++)
		{
			int idx = (i * src.rows + j) * 3;
			dst.data[idx / 3] = (src.data[idx] + src.data[idx + 1] + src.data[idx + 2]) / 3;
		}
	}
}


int main(int argc, char *arrv[])
{
	JpegDecoder decoder("01.jpg");
	Matrix mat, dst;
	decoder.Decoder(mat);

	Gray(dst, mat);
	Binary(dst);
	ShowImage(dst);

	cvWaitKey(0);
	return 0;
}

JpegDecoder: https://github.com/lzb-cc/JpegCodecs

 

运行示例

© 著作权归作者所有

共有 人打赏支持
t
粉丝 0
博文 61
码字总数 16992
作品 0
武汉
程序员
OpenCV学习(14) 细化算法(2)

前面一篇教程中,我们实现了Zhang的快速并行细化算法,从算法原理上,我们可以知道,算法是基于像素8邻域的形状来决定是否删除当前像素。还有很多与此算法相似的细化算法,只是判断的条件不一...

迈克老狼1 ⋅ 2013/09/15 ⋅ 0

Java基于opencv实现图像数字识别(二)—基本流程

Java基于opencv实现图像数字识别(二)—基本流程 做一个项目之前呢,我们应该有一个总体把握,或者是进度条;来一步步的督促着我们来完成这个项目,在我们正式开始前呢,我们先讨论下流程。 ...

奇迹迪 ⋅ 06/10 ⋅ 0

opencv查找mat的值

OpenCV如何扫描图像、利用查找表和计时 目的 我们将探索以下问题的答案: 如何遍历图像中的每一个像素? OpenCV的矩阵值是如何存储的? 如何测试我们所实现算法的性能? 查找表是什么?为什么...

代码学习者01 ⋅ 2014/03/18 ⋅ 0

手写数字识别系统之图像分割

背景 本文,主要介绍我之前在学校时候,研究的一些跟手写数字识别相关的技术心得,主要涉及:数字图像处理、特征提取、神经网络等等相关的一些技术。。 虽然很多用到的还是网上现有的比较成熟...

ruki ⋅ 2016/07/30 ⋅ 0

图像的灰度图 和 二值化的概念

原文地址 在图像处理中,用RGB三个分量(R:Red,G:Green,B:Blue),即红、绿、蓝三原色来表示真彩色,R分量,G分量,B分量的取值范围均为0~255,比如电脑屏幕上的一个红色的像素点的三个...

liuhongyi0104 ⋅ 03/23 ⋅ 0

大津法---OTSU算法

OpenCV的二值化操作中,有一种“大津阈值处理”的方法,使用函数cvThreshold(image,image2,0,255,CVTHRESH_OTSU) 实现,该函数就会使用大律法OTSU得到的全局自适应阈值来进行二值化图片,而参...

moki_oschina ⋅ 2016/11/24 ⋅ 0

最新的人脸识别特征点定位方法--人脸识别关键点技术颜鉴提供

1.2 人脸特征点定位方法综述 目前为止,国内外学者们已经提出了人脸特征点定位的方法[3],依据定位所需要的基本信息的类型,人脸特征点定位的方法可以大致分为以下六类:(1)灰度信息的方法;...

colorreco ⋅ 2016/09/07 ⋅ 0

【OpenCV3.3】检测图像中的身份证区域

假设现有一些含身份证前景以及不确定背景的图像,想通过计算机将身份证区域检测出来,实现诸如用户拍照定位提示、背景分离等业务,用OpenCV该如何做呢?如果输入图像前景和背景同时具有一定区...

wjf1997 ⋅ 2017/08/16 ⋅ 0

灰度化、二值化、膨胀算法、腐蚀算法以及开运算和闭运算

一、RGB RGB色彩模式使用RGB模型为图像中每一个像素的RGB分量分配一个0~255范围内的强度值。RGB图像只使用三种颜色,R(red)、G(green)、B(blue),就可以使它们按照不同的比例混合,在屏幕上呈...

li_wen01 ⋅ 2017/06/05 ⋅ 0

人脸识别中的Procruster analysis应用

本文中,我们通过Procrustes analysis来处理特征点,Procrustes analysis算法可以参考:http://en.wikipedia.org/wiki/Procrustesanalysis 在数学上,Procruster analysis就是寻找一个标准形...

迈克老狼1 ⋅ 2014/04/12 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

R计算IV

参考文章 #读取文件 rawdata = read.csv("/path/to/csv/file",header=T) colnames(rawdata)[18] <- "y" //重命名因变量y #数据分区 训练集测试集 trainIdx <- sample(nrow(rawdata), round(......

火力全開 ⋅ 18分钟前 ⋅ 0

SQL老司机,在SQL中计算 array & map & json数据

摘要: 场景 通常,我们处理数据,一列数据类型要么是字符串,要么是数字,这些都是primitive类型的数据。 场景 通常,我们处理数据,一列数据类型要么是字符串,要么是数字,这些都是primi...

阿里云云栖社区 ⋅ 18分钟前 ⋅ 0

SQL老司机,在SQL中计算 array & map & json数据

摘要: 场景 通常,我们处理数据,一列数据类型要么是字符串,要么是数字,这些都是primitive类型的数据。 场景 通常,我们处理数据,一列数据类型要么是字符串,要么是数字,这些都是primi...

猫耳m ⋅ 29分钟前 ⋅ 0

关于ireport自定义变量类型为list的时候

自己摸石头过河,我真的应该去趟市中心图书馆,借本真正靠谱的教材 网上的东西,只有0.01%是有用的,还有0.99%是垃圾,剩下的99%是垃圾的复制品。。 哎!~ 问题是这样的,报表带sql,从db中获...

炑炑milina ⋅ 29分钟前 ⋅ 0

Spring mvc ContextLoaderListener 原理解析

对于熟悉Spring MVC功能,首先应从web.xml 开始,在web.xml 文件中我们需要配置一个监听器 ContextLoaderListener,如下。 <!-- 加载spring上下文信息,最主要的功能是解析applicationContex...

轨迹_ ⋅ 30分钟前 ⋅ 0

阿里云发布企业数字化及上云外包平台服务:阿里云众包平台

摘要: 阿里云正式发布旗下众包平台业务(网址:https://zhongbao.aliyun.com/),支持包括:网站定制开发,APP、电商系统等软件开发,商标、商品LOGO、VI、产品包装设计、营销推广、大数据人...

阿里云官方博客 ⋅ 32分钟前 ⋅ 0

Redis安装异常解决办法

官网地址:http://redis.io/ 官网下载地址:http://redis.io/download 1. 下载Redis源码(tar.gz),并上传到Linux 2. 解压缩包:tar zxvf redis-2.8.17.tar.gz 3. 进入解压缩后的文件夹:c...

slagga ⋅ 36分钟前 ⋅ 0

006. 深入JVM学习—年轻代

1. 年轻代图片 年轻代(Young)属于JVM堆内存空间的一个组成部分 所有使用关键字new新实例化的对象一定会在伊甸园区进行保存,而对于存活区保存的一定是已经在伊甸园区存在一段时间并且经过了...

影狼 ⋅ 37分钟前 ⋅ 0

如何成为一个合格的程序员

偶尔的,我会被人问道:如何成为一名优秀的程序员,更或者,如何成为一名程序员。每次人们问起,我都力图给出不同的答案。因此,我的答案是各种各样的。下面就是我认为的成为一名优秀的程序员...

柳猫 ⋅ 38分钟前 ⋅ 0

cups error_log日志暴增

日志内容 File \"/usr/lib/cups/notifier/dbus\" has insecure permissions 解决(未验证适用范围) sudo service cups stopsudo rm /etc/cups/subscriptions.conf*sudo rm -r /var/cac......

一介码夫_Hum ⋅ 42分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部