📄 func.c
字号:
}
/////////////////////////////////////////////////////////////////
//比较取不同阈值时的方差大小,确定最终阈值
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 + -