當前位置:首頁 » 編程語言 » 灰度圖像閾值分割C語言
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

灰度圖像閾值分割C語言

發布時間: 2023-08-17 09:17:54

Ⅰ 如何用C語言實現對圖像的二值化

/*************************************************************************
* 該函數用於對圖像進行閾值分割運算
* 參數:
* LPSTR lpDIBBits - 指向源DIB圖像指針
* LONG lWidth - 源圖像寬度(象素數)
* LONG lHeight - 源圖像高度(象素數)
************************************************************************/

BOOL ImageChangeProc::ThresholdDIB(LPSTR lpDIBBits,LONG lWidth, LONG lHeight)
{

// 指向源圖像的指針
LPSTR lpSrc;

// 指向緩存圖像的指針
LPSTR lpDst;

// 指向緩存DIB圖像的指針
LPSTR lpNewDIBBits;
HLOCAL hNewDIBBits;

//循環變數
long i;
long j;

unsigned char pixel;
long lHistogram[256];

//閾值,最大灰度值與最小灰度值,兩個區域的平均灰度值
unsigned char Threshold,NewThreshold,MaxGrayValue,MinGrayValue,Temp1GrayValue,Temp2GrayValue;

//用於計算區域灰度平均值的中間變數
long lP1,lP2,lS1,lS2;

//迭代次數
int IterationTimes;

LONG lLineBytes;
hNewDIBBits = LocalAlloc(LHND, lWidth * lHeight);

if (hNewDIBBits == NULL)
{
// 分配內存失敗
return FALSE;
}

// 鎖定內存
lpNewDIBBits = (char * )LocalLock(hNewDIBBits);

// 初始化新分配的內存
lpDst = (char *)lpNewDIBBits;
memset(lpDst, (BYTE)255, lWidth * lHeight);

lLineBytes = WIDTHBYTES(lWidth * 8);

for (i = 0; i < 256;i++)
{
lHistogram[i]=0;
}

//獲得直方圖
MaxGrayValue = 0;
MinGrayValue = 255;
for (i = 0;i < lWidth ;i++)
{
for(j = 0;j < lHeight ;j++)
{
lpSrc = (char *)lpDIBBits + lLineBytes * j + i;

pixel = (unsigned char)*lpSrc;

lHistogram[pixel]++;
//修改最大,最小灰度值
if(MinGrayValue > pixel)
{
MinGrayValue = pixel;
}
if(MaxGrayValue < pixel)
{
MaxGrayValue = pixel;
}
}
}

//迭代求最佳閾值
NewThreshold = (MinGrayValue + MaxGrayValue)/2;
Threshold = 0;

for(IterationTimes = 0; Threshold != NewThreshold && IterationTimes < 1000;IterationTimes ++)
{
Threshold = NewThreshold;
lP1 =0;
lP2 =0;
lS1 = 0;
lS2 = 0;
//求兩個區域的灰度平均值
for (i = MinGrayValue;i <=Threshold;i++)
{
lP1 += lHistogram[i]*i;
lS1 += lHistogram[i];
}

for (i = Threshold+1;i<MaxGrayValue;i++)
{
lP2 += lHistogram[i]*i;
lS2 += lHistogram[i];
}
if(lS1==0||lS2==0)
{
// 釋放內存
LocalUnlock(hNewDIBBits);
LocalFree(hNewDIBBits);
return FALSE;
}
Temp1GrayValue = (unsigned char)(lP1 / lS1);
Temp2GrayValue = (unsigned char)(lP2 / lS2);
NewThreshold = (Temp1GrayValue + Temp2GrayValue)/2;
}

//根據閾值將圖像二值化
for (i = 0;i < lWidth ;i++)
{
for(j = 0;j < lHeight ;j++)
{
lpSrc = (char *)lpDIBBits + lLineBytes * j + i;
lpDst = (char *)lpNewDIBBits + lLineBytes * j + i;
pixel = (unsigned char)*lpSrc;

if(pixel <= Threshold)
{
*lpDst = (unsigned char)0;
}
else
{
*lpDst = (unsigned char)255;
}
}
}

// 復制圖像
memcpy(lpDIBBits, lpNewDIBBits, lWidth * lHeight);

// 釋放內存
LocalUnlock(hNewDIBBits);
LocalFree(hNewDIBBits);

// 返回
return TRUE;
}

參考:http://topic.csdn.net/t/20030909/13/2240079.html