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

📄 func.c

📁 这是今年ADI大赛我参与的另一个获奖的项目列缝检测仪的源文件
💻 C
📖 第 1 页 / 共 4 页
字号:
		
	}
	/////////////////////////////////////////////////////////////////
	//比较取不同阈值时的方差大小,确定最终阈值
	mul=0;
	temp2=0;
    for(k=0; k<256; k++)             
    {
		mul += k*zhifangtu[k];
		u1 = mul/num;
		u2 = u-u1;
		U1 = u1/w[k];
		U2 = (u-u1)/(1-w[k]);
		fangcha = (w[k])*(1-w[k])*(U1-U2)*(U1-U2);
		if(fangcha >= temp2)
		{
			temp2 = fangcha;
			T=k;
		}
    }
	
	/////////////////////////////////////////////////////////////////
	//按阈值T对图像进行分割
	for(i=0; i<nHeight; i++)
	{
		for(j=LEFTSIDE; j<RIGHTSIDE; j++)//nWidth/2-nSegWidth nWidth/2+nSegWidth
		{
			if(pImage[i*nWidth+j] > T)
				pImage[i*nWidth+j] = 255;
			else
				pImage[i*nWidth+j] = 0;
		}
	}
	return T; 
}

/*****************************************************************************/
//函数名称:MeasurePart()
//功能:裂缝宽度分段测量
//参数:
//		unsigned char *pImage 图像数据指针
//		int nWidth, int nHeight 图象宽度、高度
//		int nLength 每段的长度
//返回值:int 最宽的部分的宽度
/*****************************************************************************/
int MeasurePart(unsigned char *pImage, int nWidth, int nHeight, int nLength)
{
	int i,j,k;
	int nLineWidth[IMAGEHEIGHT];		//整形数组,用于存放每行宽度
	int nLeft, nRight;						//左边界点,右边界点
	
	const int nPartLength = nLength;			//分段长度
	int nPartCount;						//每段的宽度总数  
	int nAvgPart;							//每段的平均宽度
	int nMaxAvg = 0;		    			//最大宽度平均值
	int nMaxPartNum;					//最大宽度部分的编号
	int nPartNum;						//分段数量

	for(i=0; i<nHeight; i++)
	{
		int nTempWidth=0;
		for(j=LEFTSIDE; j<RIGHTSIDE; j++)
		{
			if(pImage[i*nWidth+j] == 255 &&
			   pImage[i*nWidth+j+1] == 255 &&
			   pImage[i*nWidth+j-1] != 255 )
			{
				nLeft = j;
			}

			if(pImage[i*nWidth+j] == 255 &&
			   pImage[i*nWidth+j-1] == 255 &&
			   pImage[i*nWidth+j+1] != 255 )
			{
				nRight = j;
				if(nTempWidth < (nRight - nLeft))
					nTempWidth = nRight - nLeft;
			}
		}
		nLineWidth[i] = nTempWidth;
	}
	

	//获取分段数量-1
	nPartNum = nHeight/nPartLength;

	//统计整数部分的分段
	for(k=0; k<nPartNum; k++)
	{
		nPartCount = 0;
		for(i=k*nPartLength; i<k*nPartLength+nPartLength; i++)
		{
			nPartCount += nLineWidth[i];
		}
		nAvgPart = nPartCount/nPartLength;
		if(nAvgPart>nMaxAvg)
		{
			nMaxAvg = nAvgPart;
			nMaxPartNum = k;
		}
	}

	//统计最后一段
	nPartCount = 0;
	for(i=nPartNum*nPartLength; i<nHeight; i++)
	{
		nPartCount += nLineWidth[i];
	}
	nAvgPart = nPartCount/(nHeight-nPartNum*nPartLength);
	if(nAvgPart>nMaxAvg)
	{
		nMaxAvg = nAvgPart;
		nMaxPartNum = nPartNum+1;
	}

	//将最宽的部分置成灰色
	if(nMaxPartNum == nPartNum+1)//最后一段最宽的情况
	{
		for(i=nPartNum*nPartLength; i<nHeight; i++)
		{
			for(j=0; j<nWidth; j++)
			{	
				if(pImage[i*nWidth+j] == 255)
					pImage[i*nWidth+j] = 50;
			}
		}		
	}
	else//其他部分最宽的情况
	{
		for(i=nMaxPartNum*nPartLength; i<nMaxPartNum*nPartLength+nPartLength; i++)
		{
			for(j=0; j<nWidth; j++)
			{	
				if(pImage[i*nWidth+j] == 255)
					pImage[i*nWidth+j] = 100;
			}
		}
	}
	return nMaxAvg; //返回宽度
}



/*****************************************************************************/
//函数名称:SingleSpot()
//功能:以四联通为标准进行孤立点去除
//参数:
//		unsigned char *pImage 图像数据指针
//		int nWidth, int nHeight 图象宽度、高度
//返回值:int 去除的点数
/*****************************************************************************/
int SingleSpot(unsigned char *pImage, int nWidth, int nHeight)
{
	int i,j,nNum;
	nNum = 0;
	for(i=1; i<nHeight-1; i++)
	{
		for(j=1; j<nWidth-1; j++)
		{
			if((pImage[i*nWidth+j] == 255) &&
			   (pImage[i*nWidth+j+1] == 0) &&
			   (pImage[i*nWidth+j-1] == 0) &&
			   (pImage[(i+1)*nWidth+j] == 0) &&
			   (pImage[(i-1)*nWidth+j] == 0)
			   )
			{
				nNum++;
			   	pImage[i*nWidth+j] = 0;
			}
			
		}
	}
	return nNum;
}



/*****************************************************************************/
//函数名称:Mark()
//功能:二值图像区域标记
//参数:
//		unsigned char *pImage 图像数据指针
//		int nWidth, int nHeight 图象宽度、高度
//		int nNum 标记时,垂直方向图像中线上下截取的图像高度
//返回值:int 标记区域数目
/*****************************************************************************/
int Mark(unsigned char *pImage, int nWidth, int nHeight, int nNum)
{
	int i,j;
	int m,n;
	int N;
	int count;

	int U,V;                //从左向右,从上至下扫描图像,如果有某一像素点
	int x,y;                //左前和右上的像素点标号不同,则以右上为准合并标号
	//////////////////////////////////////////////////////
	int flag;
	count=1;
	flag=0;
	N=250;                  //从左到右,从上倒下遍历图像,找到第一个目标点
	for(i=nHeight/2+nNum;(i>=nHeight/2-nNum)&&(!flag);i--)
	{
		for(j=LEFTSIDE;(j<RIGHTSIDE)&&(!flag);j++)
		{
			if(pImage[i*nWidth+j]==255)
			{
				pImage[i*nWidth+j]=N; //第一个像素的灰度置为N=250
				m=i;
				n=j;
				flag=1;
			}
		}
	}

	////////////////////////////////////////////////////////////////////////
	for(i=m;i>=nHeight/2-nNum;i--)//从左到右,从上倒下遍历图像
	{
		for(j=LEFTSIDE;j<RIGHTSIDE;j++)
		{
			if(pImage[i*nWidth+j]==255)//如果找到一个目标点
			{

				if(pImage[(i+1)*nWidth+j+1]>0)//如果与右上为已标识的目标点
				{
					pImage[i*nWidth+j]=pImage[(i+1)*nWidth+j+1];//对此点加与右上相同的标识
				}

				else
					if(pImage[(i+1)*nWidth+j]>0)//如果与正上为已标识的目标点
					{
						pImage[i*nWidth+j]=pImage[(i+1)*nWidth+j];//对此点加与正上相同的标识
					}

					else 
						if(pImage[(i+1)*nWidth+j-1]>0)//如果与左上为已标识的目标点

⌨️ 快捷键说明

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