图像分割自适应阈值的求取

来源:互联网 发布:如何进行销售数据分析 编辑:程序博客网 时间:2024/06/09 16:31


代码实现:

//OpenCv版

int CFractalImageRecognitionDlg::BestThresholdValue(IplImage* m_grayImage) //灰度化图像
{
//判别分析法,返回最佳阈值
int height = m_grayImage->height;
int width = m_grayImage->width;
if (height*width>65536)
{
MessageBox("图片大小超出指定范围","提示");
return -1;//返回错误标识
}
int w1Src[65536],w2Src[65536];
double ratio[256],tempRatio=0.0;
int i,j,k,bestK=0;
for (k=0;k<256;k++)
{
int w1=0,w2=0,sumW1=0,sumW2=0;//像素数,总灰度值
double m1=0,m2=0,deta1=0,deta2=0,temp1=0,temp2=0;//灰度平均值,方差,求方差用到的中间变量
//逐行扫描
for(i = 0; i < height; i++)
{
//逐列扫描
for(j = 0; j < width; j++)
{
CvScalar s = cvGet2D(m_grayImage,i,j);
int grayValue = (int)s.val[0];
if (grayValue<k)
{
w1Src[w1] = grayValue;
w1++;
sumW1 += grayValue;
}
else
{
w2Src[w2] = grayValue;
w2++;
sumW2+= grayValue;
}
}
}
m1 = 1.0*sumW1/w1;
m2 = 1.0*sumW2/w2;
for (int m=0;m<w1;m++)
{
temp1 += pow((double)(w1Src[m]-m1),2);
}
deta1 = 1.0*temp1/w1;
for (int n=0;n<w2;n++)
{
temp2 += pow((double)(w2Src[n]-m2),2);
}
deta2 = 1.0*temp2/w2;
double avgPixel = (m1*w1+m2*w2)/(w1+w2);//灰度均值
double detaW = w1*deta1+w2*deta2;//组内方差
double detaB = w1*pow((m1-avgPixel),2)+w2*pow((m2-avgPixel),2);//组间方差
ratio[k] = detaB/detaW;
if(ratio[k]>tempRatio)
{
bestK = k;
tempRatio = ratio[k];
}
}
return bestK;
}

//VC++版

//判别分析法,返回最佳阈值
BYTE CCharaterRecognitionDlg::Threshold(LPSTR lpDIB, LPSTR lpDIBBits)
{
BYTE * lpSrc; // 指向DIB象素的指针
LONG lLineBytes;     // 图像每行的字节数
LPBITMAPINFO lpbmi;   // 指向BITMAPINFO结构的指针(Win3.0) 
LPBITMAPCOREINFO lpbmc;    // 指向BITMAPCOREINFO结构的指针 
lpbmi = (LPBITMAPINFO)lpDIB; // 获取指向BITMAPINFO结构的指针(Win3.0) 
lpbmc = (LPBITMAPCOREINFO)lpDIB; // 获取指向BITMAPCOREINFO结构的指针
int i,j,k;
// 计算图像每行的字节数
lLineBytes = WIDTHBYTES(bmpWidth * 8);
BYTE w1Src[BMP_SIZE*BMP_SIZE],w2Src[BMP_SIZE*BMP_SIZE];
double ratio[BMP_SIZE],tempRatio=0.0;
int bestK=0;

// 更换每个象素的颜色索引(即按照灰度映射表换成灰度值)
for (k=0;k<BMP_SIZE;k++)
{
int w1=0,w2=0,sumW1=0,sumW2=0;//像素数,总灰度值
double m1=0,m2=0,deta1=0,deta2=0,temp1=0,temp2=0;//灰度平均值,方差,求方差用到的中间变量
//逐行扫描
for(i = 0; i < bmpHeight; i++)
{
//逐列扫描
for(j = 0; j < bmpWidth; j++)
{
// 指向DIB第i行,第j个象素的指针
lpSrc = (unsigned char*)lpDIBBits+ lLineBytes * (bmpHeight - 1 - i) + j;

if (*lpSrc<k)
{
w1Src[w1] = *lpSrc;
w1++;
sumW1 += *lpSrc;
}
else
{
w2Src[w2] = *lpSrc;
w2++;
sumW2+= *lpSrc;
}

}
}
m1 = 1.0*sumW1/w1;
m2 = 1.0*sumW2/w2;
for (int m=0;m<w1;m++)
{
temp1 += pow((double)(w1Src[m]-m1),2);
}
deta1 = 1.0*temp1/w1;
for (int n=0;n<w2;n++)
{
temp2 += pow((double)(w2Src[n]-m2),2);
}
deta2 = 1.0*temp2/w2;
double avgPixel = (m1*w1+m2*w2)/(w1+w2);//灰度均值
double detaW = w1*deta1+w2*deta2;//组内方差
double detaB = w1*pow((m1-avgPixel),2)+w2*pow((m2-avgPixel),2);//组间方差
ratio[k] = detaB/detaW;
if(ratio[k]>tempRatio)
{
bestK = k;
tempRatio = ratio[k];
}
}
return bestK;
}

原创粉丝点击