图像阈值分割---迭代算法

图像阈值分割---迭代算法

1.处理流程:

       1.为全局阈值选择一个初始估计值T(图像的平均灰度)。
       2.用T分割图像。产生两组像素:G1有灰度值大于T的像素组成,G2有小于等于T像素组成。
       3.计算G1和G2像素的平均灰度值m1和m2;
       4.计算一个新的阈值:T = (m1 + m2) / 2;
       5.重复步骤2和4,直到连续迭代中的T值间的差小于一个预定义参数为止。

       适合图像直方图有明显波谷

2.源代码

/******************************************************************************* 
函数名称  : IterativeAlgorithm 
函数描述  : 图像算法:图像阈值分割---迭代算法(适合图像直方图有明显波谷)
输入参数  : IplImage *pImage---------------------------图像指针(灰度图)
                   int nMaxIter----------------------------------最大迭代次数
				   int& iDiffRec---------------------------------使用给定阀值确定的亮区与暗区平均灰度差异值
输出参数  : N/A
返 回 值    : int iThrehold---------------------------------迭代得到的阈值
作     者     : N/A    2013-01-22
处理流程:1.为全局阈值选择一个初始估计值T(图像的平均灰度)。
          2.用T分割图像。产生两组像素:G1有灰度值大于T的像素组成,G2有小于等于T像素组成。
          3.计算G1和G2像素的平均灰度值m1和m2;
	  4.计算一个新的阈值:T = (m1 + m2) / 2;
          5.重复步骤2和4,直到连续迭代中的T值间的差小于一个预定义参数为止。
*******************************************************************************/ 
int CThreasholdProcess::DetectThreshold(const IplImage *img, int nMaxIter, int& iDiffRec)
{
		//图像信息
		int iHeight = img->height;
		int iWidth = img->width;
		int iStep = img->widthStep/sizeof(uchar);
		uchar *pData = (uchar*)img->imageData;

		iDiffRec =0;
		int F[256]={ 0 }; //直方图数组
		int iTotalGray=0;//灰度值和
		int iTotalPixel =0;//像素数和
		byte bt;//某点的像素值

		uchar iThrehold = 0; //阀值
		uchar iNewThrehold = 0; //新阀值
		uchar iMaxGrayValue=0,iMinGrayValue=255;//原图像中的最大灰度值和最小灰度值
		uchar iMeanGrayValue1,iMeanGrayValue2;

		//获取(i,j)的值,存于直方图数组F
		for(int i=0;i<iWidth;i++)
		{
			for(int j=0;j<iHeight;j++)
			{
				bt = pData[i*iStep+j];
				if(bt<iMinGrayValue)
					iMinGrayValue = bt;
				if(bt>iMaxGrayValue)
					iMaxGrayValue = bt;
				F[bt]++;
			}
		}

		iThrehold =0;
		iNewThrehold = (iMinGrayValue+iMaxGrayValue)/2;//初始阀值(图像的平均灰度)
		iDiffRec = iMaxGrayValue - iMinGrayValue;

		for(int a=0;(abs(iThrehold-iNewThrehold)>0.5)&&a<nMaxIter;a++)//迭代中止条件
		{
			iThrehold = iNewThrehold;
			//小于当前阀值部分的平均灰度值
			for(int i=iMinGrayValue;i<iThrehold;i++)
			{
				iTotalGray += F[i]*i;//F[]存储图像信息
				iTotalPixel += F[i];
			}

			iMeanGrayValue1 = (uchar)(iTotalGray/iTotalPixel);
			//大于当前阀值部分的平均灰度值
			iTotalPixel =0;
			iTotalGray =0;
			for(int j=iThrehold+1;j<iMaxGrayValue;j++)
			{
				iTotalGray += F[j]*j;//F[]存储图像信息
				iTotalPixel += F[j];    
			}

			iMeanGrayValue2 = (uchar)(iTotalGray/iTotalPixel);

			iNewThrehold = (iMeanGrayValue2+iMeanGrayValue1)/2;        //新阀值
			iDiffRec = abs(iMeanGrayValue2 - iMeanGrayValue1);
		}

		return iThrehold;
}

3.演示;

演示结果见http://blog.csdn.net/ily6418031hwm/article/details/8525695 的演示结果


  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
运用K-means算法进行图像分割, K-means算法是很典型的基于距离的聚类算法,采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大。该算法认为簇是由距离靠近的对象组成的,因此把得到紧凑且独立的簇作为最终目标。 k个初始类聚类中心点的选取对聚类结果具有较大的 公式 公式 影响,因为在该算法第一步中是随机的选取任意k个对象作为初始聚类的中心,初始地代表一个簇。该算法在每次迭代中对数据集中剩余的每个对象,根据其与各个簇中心的距离将每个对象重新赋给最近的簇。当考察完所有数据对象后,一次迭代运算完成,新的聚类中心被计算出来。如果在一次迭代前后,J的值没有发生变化,说明算法已经收敛。 算法过程如下: 1)从N个文档随机选取K个文档作为质心 2)对剩余的每个文档测量其到每个质心的距离,并把它归到最近的质心的类 3)重新计算已经得到的各个类的质心 4)迭代2~3步直至新的质心与原质心相等或小于指定阈值,算法结束 具体如下: 输入:k, data[n]; (1) 选择k个初始中心点,例如c[0]=data[0],…c[k-1]=data[k-1]; (2) 对于data[0]….data[n],分别与c[0]…c[k-1]比较,假定与c[i]差值最少,就标记为i; (3) 对于所有标记为i点,重新计算c[i]={ 所有标记为i的data[j]之和}/标记为i的个数; (4) 重复(2)(3),直到所有c[i]值的变化小于给定阈值。 折叠工作原理 K-MEANS算法的工作原理及流程 K-MEANS算法 输入:聚类个数k,以及包含 n个数据对象的数据库。 输出:满足方差最小标准的k个聚类。
我可以回答这个问题。以下是一个利用粒子群算法进行图像阈值分割的 Matlab 代码示例: ```matlab % 读取图像 img = imread('image.jpg'); % 将图像转换为灰度图像 gray_img = rgb2gray(img); % 初始化粒子群算法参数 max_iter = 100; % 最大迭代次数 pop_size = 50; % 粒子群大小 w = 0.5; % 惯性权重 c1 = 1; % 个体学习因子 c2 = 1; % 社会学习因子 % 初始化粒子群 pop = randi([0 255], pop_size, 1); % 计算适应度函数 fitness = zeros(pop_size, 1); for i = 1:pop_size threshold = pop(i); binary_img = gray_img > threshold; foreground_pixels = sum(binary_img(:)); background_pixels = numel(binary_img) - foreground_pixels; fitness(i) = foreground_pixels * background_pixels; end % 记录最优解 [best_fitness, best_idx] = max(fitness); best_threshold = pop(best_idx); % 迭代更新粒子群 for iter = 1:max_iter % 更新速度和位置 for i = 1:pop_size r1 = rand(); r2 = rand(); v = w * pop(i) + c1 * r1 * (best_threshold - pop(i)) + c2 * r2 * (best_threshold - pop(i)); pop(i) = min(max(round(pop(i) + v), 0), 255); end % 计算适应度函数 for i = 1:pop_size threshold = pop(i); binary_img = gray_img > threshold; foreground_pixels = sum(binary_img(:)); background_pixels = numel(binary_img) - foreground_pixels; fitness(i) = foreground_pixels * background_pixels; end % 更新最优解 [new_best_fitness, new_best_idx] = max(fitness); if new_best_fitness > best_fitness best_fitness = new_best_fitness; best_idx = new_best_idx; best_threshold = pop(best_idx); end end % 输出结果 binary_img = gray_img > best_threshold; imshow(binary_img); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清风似水流

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值