?? suanfa1.cpp
字號:
* 該函數(shù)對DIB圖像進(jìn)行中值濾波。
*
************************************************************************/
BOOL WINAPI myMedianFilter(LPSTR lpDIBBits, LONG lWidth, LONG lHeight,
int iFilterH, int iFilterW,
int iFilterMX, int iFilterMY)
{
// 指向源圖像的指針
unsigned char* lpSrc;
// 指向要復(fù)制區(qū)域的指針
unsigned char* lpDst;
// 指向復(fù)制圖像的指針
LPSTR lpNewDIBBits;
HLOCAL hNewDIBBits;
// 指向濾波器數(shù)組的指針
unsigned char * aValue;
HLOCAL hArray;
// 循環(huán)變量
LONG i;
LONG j;
LONG k;
LONG l;
// 圖像每行的字節(jié)數(shù)
LONG lLineBytes;
// 計算圖像每行的字節(jié)數(shù)
lLineBytes = WIDTHBYTES(lWidth * 8);
// 暫時分配內(nèi)存,以保存新圖像
hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight);
// 判斷是否內(nèi)存分配失敗
if (hNewDIBBits == NULL)
{
// 分配內(nèi)存失敗
return FALSE;
}
// 鎖定內(nèi)存
lpNewDIBBits = (char * )LocalLock(hNewDIBBits);
// 初始化圖像為原始圖像
memcpy(lpNewDIBBits, lpDIBBits, lLineBytes * lHeight);
// 暫時分配內(nèi)存,以保存濾波器數(shù)組
hArray = LocalAlloc(LHND, iFilterH * iFilterW);
// 判斷是否內(nèi)存分配失敗
if (hArray == NULL)
{
// 釋放內(nèi)存
LocalUnlock(hNewDIBBits);
LocalFree(hNewDIBBits);
// 分配內(nèi)存失敗
return FALSE;
}
// 鎖定內(nèi)存
aValue = (unsigned char * )LocalLock(hArray);
// 開始中值濾波
// 行(除去邊緣幾行)
for(i = iFilterMY; i < lHeight - iFilterH + iFilterMY + 1; i++)
{
// 列(除去邊緣幾列)
for(j = iFilterMX; j < lWidth - iFilterW + iFilterMX + 1; j++)
{
// 指向新DIB第i行,第j個象素的指針
lpDst = (unsigned char*)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j;
// 讀取濾波器數(shù)組
for (k = 0; k < iFilterH; k++)
{
for (l = 0; l < iFilterW; l++)
{
// 指向DIB第i - iFilterMY + k行,第j - iFilterMX + l個象素的指針
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i + iFilterMY - k) + j - iFilterMX + l;
// 保存象素值
aValue[k * iFilterW + l] = *lpSrc;
}
}
// 獲取中值
* lpDst = myGetMedianNum(aValue, iFilterH * iFilterW);
}
}
// 復(fù)制變換后的圖像
memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);
// 釋放內(nèi)存
LocalUnlock(hNewDIBBits);
LocalFree(hNewDIBBits);
LocalUnlock(hArray);
LocalFree(hArray);
// 返回
return TRUE;
}
/*************************************************************************
*
* 函數(shù)名稱:
* GetMedianNum()
*
* 參數(shù):
* unsigned char * bpArray - 指向要獲取中值的數(shù)組指針
* int iFilterLen - 數(shù)組長度
*
* 返回值:
* unsigned char - 返回指定數(shù)組的中值。
*
* 說明:
* 該函數(shù)用冒泡法對一維數(shù)組進(jìn)行排序,并返回數(shù)組元素的中值。
*
************************************************************************/
unsigned char WINAPI myGetMedianNum(unsigned char * bArray, int iFilterLen)
{
// 循環(huán)變量
int i;
int j;
// 中間變量
unsigned char bTemp;
// 用冒泡法對數(shù)組進(jìn)行排序
for (j = 0; j < iFilterLen - 1; j ++)
{
for (i = 0; i < iFilterLen - j - 1; i ++)
{
if (bArray[i] > bArray[i + 1])
{
// 互換
bTemp = bArray[i];
bArray[i] = bArray[i + 1];
bArray[i + 1] = bTemp;
}
}
}
// 計算中值
if ((iFilterLen & 1) > 0)
{
// 數(shù)組有奇數(shù)個元素,返回中間一個元素
bTemp = bArray[(iFilterLen + 1) / 2];
}
else
{
// 數(shù)組有偶數(shù)個元素,返回中間兩個元素平均值
bTemp = (bArray[iFilterLen / 2] + bArray[iFilterLen / 2 + 1]) / 2;
}
// 返回中值
return bTemp;
}
/*************************************************************************
*
* 函數(shù)名稱:
* InteEqualize()
*
* 參數(shù):
* LPSTR lpDIBBits - 指向源DIB圖像指針
* LONG lWidth - 源圖像寬度(象素數(shù))
* LONG lHeight - 源圖像高度(象素數(shù))
*
* 返回值:
* BOOL - 成功返回TRUE,否則返回FALSE。
*
* 說明:
* 該函數(shù)用來對圖像進(jìn)行直方圖均衡。
*
************************************************************************/
BOOL WINAPI InteEqualize(LPSTR lpDIBBits, LONG lWidth, LONG lHeight)
{
// 指向源圖像的指針
unsigned char* lpSrc;
// 臨時變量
LONG lTemp;
// 循環(huán)變量
LONG i;
LONG j;
// 灰度映射表
BYTE bMap[256];
// 灰度映射表
LONG lCount[256];
// 圖像每行的字節(jié)數(shù)
LONG lLineBytes;
// 計算圖像每行的字節(jié)數(shù)
lLineBytes = WIDTHBYTES(lWidth * 8);
// 重置計數(shù)為0
for (i = 0; i < 256; i ++)
{
// 清零
lCount[i] = 0;
}
// 計算各個灰度值的計數(shù)
for (i = 0; i < lHeight; i ++)
{
for (j = 0; j < lWidth; j ++)
{
lpSrc = (unsigned char *)lpDIBBits + lLineBytes * i + j;
// 計數(shù)加1
lCount[*(lpSrc)]++;
}
}
// 計算灰度映射表
for (i = 0; i < 256; i++)
{
// 初始為0
lTemp = 0;
for (j = 0; j <= i ; j++)
{
lTemp += lCount[j];
}
// 計算對應(yīng)的新灰度值
bMap[i] = (BYTE) (lTemp * 255 / lHeight / lWidth);
}
// 每行
for(i = 0; i < lHeight; i++)
{
// 每列
for(j = 0; j < lWidth; j++)
{
// 指向DIB第i行,第j個象素的指針
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;
// 計算新的灰度值
*lpSrc = bMap[*lpSrc];
}
}
// 返回
return TRUE;
}
/*************************************************************************
*
* 函數(shù)名稱:
* AddMinusDIB()
*
* 參數(shù):
* LPSTR lpDIBBits - 指向源DIB圖像指針
* LPSTR lpDIBBitsBK - 指向背景DIB圖像指針
* LONG lWidth - 源圖像寬度(象素數(shù))
* LONG lHeight - 源圖像高度(象素數(shù))
* bool bAddMinus - 為true時執(zhí)行加運(yùn)算,否則執(zhí)行減運(yùn)算。
*
* 返回值:
* BOOL - 運(yùn)算成功返回TRUE,否則返回FALSE。
*
* 說明:
* 該函數(shù)用于對兩幅圖像進(jìn)行加減運(yùn)算。
*
* 要求目標(biāo)圖像為255個灰度值的灰度圖像。
************************************************************************/
BOOL WINAPI AddMinusDIB(LPSTR lpDIBBits, LPSTR lpDIBBitsBK, LONG lWidth, LONG lHeight ,bool bAddMinus)
{
// 指向源圖像的指針
LPSTR lpSrc,lpSrcBK;
// 指向緩存圖像的指針
LPSTR lpDst;
// 指向緩存DIB圖像的指針
LPSTR lpNewDIBBits;
HLOCAL hNewDIBBits;
//循環(huán)變量
long i;
long j;
//像素值
unsigned char pixel,pixelBK;
// 圖像每行的字節(jié)數(shù)
LONG lLineBytes;
// 暫時分配內(nèi)存,以保存新圖像
hNewDIBBits = LocalAlloc(LHND, lWidth * lHeight);
if (hNewDIBBits == NULL)
{
// 分配內(nèi)存失敗
return FALSE;
}
// 鎖定內(nèi)存
lpNewDIBBits = (char * )LocalLock(hNewDIBBits);
// 初始化新分配的內(nèi)存,設(shè)定初始值為255
lpDst = (char *)lpNewDIBBits;
memset(lpDst, (BYTE)255, lWidth * lHeight);
// 計算圖像每行的字節(jié)數(shù)
lLineBytes = WIDTHBYTES(lWidth * 8);
for (j = 0;j < lHeight ;j++)
{
for(i = 0;i < lWidth ;i++)
{
// 指向源圖像倒數(shù)第j行,第i個象素的指針
lpSrc = (char *)lpDIBBits + lLineBytes * j + i;
lpSrcBK = (char *)lpDIBBitsBK + lLineBytes * j + i;
// 指向目標(biāo)圖像倒數(shù)第j行,第i個象素的指針
lpDst = (char *)lpNewDIBBits + lLineBytes * j + i;
pixel = (unsigned char)*lpSrc;
pixelBK = (unsigned char)*lpSrcBK;
if(bAddMinus)
*lpDst = pixel + pixelBK > 255 ? 255 : pixel + pixelBK;
else
// *lpDst = pixel - pixelBK < 0 ? 0 : pixel - pixelBK;
if(abs(pixel - pixelBK)<10)
*lpDst=0;
else
*lpDst=pixel;
}
}
// 復(fù)制腐蝕后的圖像
memcpy(lpDIBBits, lpNewDIBBits, lWidth * lHeight);
// 釋放內(nèi)存
LocalUnlock(hNewDIBBits);
LocalFree(hNewDIBBits);
// 返回
return TRUE;
}
/*************************************************************************
*
* 函數(shù)名稱:
* myCropDIB()
*
* 參數(shù):
* HDIB hDIB - 指向源DIB圖像句柄
* LPRECT lpRect - 指向要剪裁的矩形區(qū)域
*
* 返回值:
* HDIB - 返回裁剪后的矩形區(qū)域圖像句柄。
*
* 說明:
* 該函數(shù)用于對指定圖像進(jìn)行指定區(qū)域裁剪操作。
*
* 要求目標(biāo)圖像為255個灰度值的灰度圖像。
************************************************************************/
HDIB WINAPI myCropDIB(HDIB hDIB, LPRECT lpRect)
{
LPBITMAPINFO lpbmi = NULL;
LPBYTE lpSourceBits, lpTargetBits, lpResult;
HDC hDC = NULL, hSourceDC, hTargetDC;
HBITMAP hSourceBitmap, hTargetBitmap, hOldTargetBitmap, hOldSourceBitmap;
DWORD dwSourceBitsSize, dwTargetBitsSize, dwTargetHeaderSize;
int nWidth, nHeight;
HDIB hNewDIB;
DWORD dwSize;
// Get DIB pointer
if (! hDIB)
{
return NULL;
}
LPBITMAPINFO lpSrcDIB = (LPBITMAPINFO)GlobalLock(hDIB);
if (! lpSrcDIB)
{
return NULL;
}
// Allocate and fill out a BITMAPINFO struct for the new DIB
dwTargetHeaderSize = sizeof( BITMAPINFOHEADER ) + PaletteSize((LPSTR)lpSrcDIB);
lpbmi = (LPBITMAPINFO)malloc( dwTargetHeaderSize );
memcpy(lpbmi, lpSrcDIB, dwTargetHeaderSize);
nWidth = RECTWIDTH(lpRect);
nHeight = RECTHEIGHT(lpRect);
lpbmi->bmiHeader.biWidth = nWidth;
lpbmi->bmiHeader.biHeight = nHeight;
// Gonna use DIBSections and BitBlt() to do the conversion, so make 'em
hDC = ::GetDC( NULL );
hTargetBitmap = CreateDIBSection( hDC, lpbmi, DIB_RGB_COLORS, (VOID **)&lpTargetBits, NULL, 0 );
hSourceBitmap = CreateDIBSection( hDC, lpSrcDIB, DIB_RGB_COLORS, (VOID **)&lpSourceBits, NULL, 0 );
hSourceDC = CreateCompatibleDC( hDC );
hTargetDC = CreateCompatibleDC( hDC );
// Flip the bits on the source DIBSection to match the source DIB
dwSourceBitsSize = lpSrcDIB->bmiHeader.biHeight * BytesPerLine((LPBYTE)&(lpSrcDIB->bmiHeader));
dwTargetBitsSize = lpbmi->bmiHeader.biHeight * BytesPerLine((LPBYTE)&(lpbmi->bmiHeader));
memcpy( lpSourceBits, FindDIBBits((LPSTR)lpSrcDIB), dwSourceBitsSize );
lpbmi->bmiHeader.biSizeImage = dwTargetBitsSize;
// Select DIBSections into DCs
hOldSourceBitmap = (HBITMAP)SelectObject( hSourceDC, hSourceBitmap );
hOldTargetBitmap = (HBITMAP)SelectObject( hTargetDC, hTargetBitmap );
// put old bitmap in new bitmap
BitBlt(hTargetDC, 0, 0, nWidth, nHeight, hSourceDC, lpRect->left, lpRect->top, SRCCOPY);
// Clean up and delete the DCs
SelectObject( hSourceDC, hOldSourceBitmap );
SelectObject( hTargetDC, hOldTargetBitmap );
DeleteDC( hSourceDC );
DeleteDC( hTargetDC );
::ReleaseDC( NULL, hDC );
// Flush the GDI batch, so we can play with the bits
GdiFlush();
// Allocate enough memory for the new CF_DIB, and copy bits
dwSize = dwTargetHeaderSize + dwTargetBitsSize;
hNewDIB =(HDIB)GlobalAlloc(GHND, dwSize);
lpResult = (LPBYTE)GlobalLock(hNewDIB);//malloc( dwTargetHeaderSize + dwTargetBitsSize );
memcpy( lpResult, lpbmi, dwTargetHeaderSize );
memcpy( FindDIBBits( (LPSTR)lpResult ), lpTargetBits, dwTargetBitsSize );
// final cleanup
DeleteObject( hTargetBitmap );
DeleteObject( hSourceBitmap );
free( lpbmi );
GlobalUnlock(hDIB);
GlobalUnlock(hNewDIB);
return hNewDIB;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -