⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 func.c

📁 这是今年ADI大赛我参与的另一个获奖的项目列缝检测仪的源文件
💻 C
📖 第 1 页 / 共 4 页
字号:
/*****************************************************************************/
//func.c
//定义有关裂缝检测各图像处理函数
//处理针对8位/256色灰度图象进行
/*****************************************************************************/
#include "math.h"
#include "stdlib.h"
#include "func.h"

#define IMAGEWIDTH			480
#define IMAGEHEIGHT	 		640

#define LEFTSIDE			200
#define RIGHTSIDE			440

/*****************************************************************************/
//函数名称:Reserve()
//功能:图像反色处理
//参数:
//		unsigned char *pImage 图像数据指针
//		int nWidth, int nHeight 图象宽度、高度
//返回值:无
/*****************************************************************************/
void Reserve(unsigned char *pImage, int nWidth, int nHeight)
{
	int i,j;
	for(i=0; i<nHeight; i++)
	{
		for(j=0; j<nWidth; j++)
		{
			pImage[i*nWidth+j] = ~(pImage[i*nWidth+j]);
		}
	}
}

/*****************************************************************************/
//函数名称:SideWhite()
//功能:图像两侧变白处理
//参数:
//		unsigned char *pImage 图像数据指针
//		int nWidth, int nHeight 图象宽度、高度
//返回值:无
/*****************************************************************************/
void SidesWhite(unsigned char *pImage, int nWidth, int nHeight)
{
	int i;
	for(i=0; i<nHeight; i++)
	{
	/*	for(j=0; j<LEFTSIDE; j++)
		{
			pImage[i*nWidth+j] = 255;
		}
	/	for(j=RIGHTSIDE; j<nWidth; j++)
		{
			pImage[i*nWidth+j] = 255;
		} */
		memset((pImage+i*nWidth), 255, LEFTSIDE);
		memset((pImage+i*nWidth+RIGHTSIDE), 255, nWidth-RIGHTSIDE);
	}
}

/*****************************************************************************/
//函数名称:SegFixed()
//功能:图像固定阈值分割
//参数:
//		unsigned char *pImage 图像数据指针
//		int nWidth, int nHeight 图象宽度、高度
//		int nT 分割阈值
//返回值:无
/*****************************************************************************/
void SegFixed(unsigned char *pImage, int nWidth, int nHeight, int nT)
{
	int i,j;
	for(i=0; i<nHeight; i++)
	{
		for(j=0; j<nWidth; j++)
		{
			if(pImage[i*nWidth+j] > nT)
				pImage[i*nWidth+j] = 255;
			else
				pImage[i*nWidth+j] = 0;
		}
	}
}

/*****************************************************************************/
//函数名称:SegOver()
//功能:图像自适应迭代阈值分割
//参数:
//		unsigned char *pImage 图像数据指针
//		int nWidth, int nHeight 图象宽度、高度
//返回值:int 分割阈值
/*****************************************************************************/
int SegOver(unsigned char *pImage, int nWidth, int nHeight)
{	
	int i,j;
	int zhifangtu[256]={0};             //直方图
	int N;       
	int T,T1;                           //阈值
	int Temp0,Temp1,Temp2,Temp3;        //临时变量
	T = 127;                            //设置阈值初值
	T1 = 0;                               
	Temp0 = Temp1 = Temp2 = Temp3 = 0;

	//////////////////////////////////////////////////////////
	for(i=0; i<nHeight; i++) //直方图统计
	{
		for(j=LEFTSIDE; j<RIGHTSIDE; j++)
		{
			N = (int)pImage[i*nWidth+j];
			zhifangtu[N]++;
		}
	}
	
	///////////////////////////////////////////////////////////////////////
	while(1)                     			//进行迭代求取阈值
	{
		//计算下一个迭代阈值
		for(i=0; i<T; i++)
		{
			Temp0 += zhifangtu[i]*i;   		//灰度小于T的所有像素点的像素总和
			Temp1 += zhifangtu[i];     		//灰度小于T的所有像素点的点数
		}
		
		for(i=T;i<256;i++)
		{
			Temp2 += zhifangtu[i]*i;   //灰度大于T的所有像素点的像素总和
			Temp3 += zhifangtu[i];     //灰度大于T的所有像素点的点数
		}
		
		T1 = (Temp0/Temp1+Temp2/Temp3)/2;
		//看迭代结果是否收敛
		if(T == T1)
			break;                     //如果收敛,结束循环,T1为最终阈值
		else
			T = T1;                    //如果不收敛,继续,取T1为新的初始阈值
	}

	////////////////////////////////////////////////////////////////////////
	//按阈值T对图像进行分割
	for(i=0; i<nHeight; i++)
	{
		for(j=LEFTSIDE; j<RIGHTSIDE; j++)
		{
			if(pImage[i*nWidth+j] > T)
				pImage[i*nWidth+j] = 255;
			else
				pImage[i*nWidth+j] = 0;
		}
	}
	
	return T;//返回阈值
}



/*****************************************************************************/
//函数名称:SegOSTU()
//功能:图像OSTU阈值分割
//参数:
//		unsigned char *pImage 图像数据指针
//		int nWidth, int nHeight 图象宽度、高度
//		int *pSegWidth 输出参数,返回OSTU运算时截取的图像宽度,以nWidth/2为中心
//返回值:int 分割阈值
/*****************************************************************************/
int SegOSTU(unsigned char *pImage, int nWidth, int nHeight, int *pSegWidth)
{
	int nFlag=1;
	int nSegWidth = 80;
	int i,j;
	int zhifangtu[256]={0};      	//直方图
	int T=0;                     //T为门限
	int k;
	int N;
	float w[256];                	//w[k]为灰度低于k部分的像素占总像素的比例,
								//灰度高于k部分的像素占总像素的比例为1-w[k].
	
	float u1,u2,u,delta;         	//u为总体的灰度均值
	float fangcha;

	float num,mul;
	float temp1;  
	float temp2;                  
	float U1,U2;

	while(nFlag)
	{
		//////////////////////////////////////////////////////////
		//直方图统计清零
		for(i=0; i<256; i++)
			zhifangtu[i] = 0;
			
		//////////////////////////////////////////////////////////
		for(i=0; i<nHeight; i++) //直方图统计
		{
			for(j=(nWidth/2)-nSegWidth; j<(nWidth/2)+nSegWidth; j++)
			{
				N = (int)pImage[i*nWidth+j];
				zhifangtu[N]++;
			}
		}
	
		/////////////////////////////////////////////////////////////////
		//求出整体灰度均值u
		num = mul = 0;
		for(k=0; k<256; k++)
		{
			mul += k*zhifangtu[k];
			num += zhifangtu[k];
		}
		u = mul/num;
	
		/////////////////////////////////////////////////////////////////
		//计算图像均方差,以决定是否缩小直方图统计面积
		delta = mul = 0;
		for(i=0; i<256; i++)
		{
			mul += (i-u)*(i-u)*zhifangtu[i];
		}
		
		delta = sqrt(mul/num);
		if(delta < 32)				//如果均方差不满足,则将截取图像左右各缩短20像素
			nSegWidth -= 10;
		if((delta >= 32) || nSegWidth <= 10)
			nFlag = 0;			//如果满足,则统计出合适的直方图,结束运算
	}
	
	*pSegWidth = nSegWidth*2;
	/////////////////////////////////////////////////////////////////
    //求出w[k]
	temp1 = 0;
	for(k=0; k<256;k++)
	{
		temp1 += zhifangtu[k];
		w[k] = temp1/num;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -