?? areapro.cpp
字號:
//坐標(biāo)規(guī)整化
m_pDibObject->NormalizeCoordinates( &nX1, &nY1, &nX2, &nY2 );
//獲取圖像寬度和高度(以像素為單位)
int nWidth = m_pDibObject->GetWidth();
int nHeight = m_pDibObject->GetHeight();
//對邊界像素不作處理
if( nX1 < nTempXc ) nX1 = nTempXc;
if( nY1 < nTempYc ) nY1 = nTempYc;
if( nX2 > nWidth - nTempW + nTempXc + 1) nX2 = nWidth - nTempW + nTempXc + 1;
if( nY2 > nHeight - nTempH + nTempYc + 1) nY2 = nHeight - nTempH + nTempYc + 1;
//定義變量
unsigned char *pBuffer, *pBits;
RGBQUAD *pPalette;
int nWidthBytes, nNewWidthBytes, nNumColors;
DWORD dwNewSize;
//獲得圖像指針
pBuffer = (unsigned char *) m_pDibObject->GetDIBPointer( &nWidthBytes,
m_pDibObject->GetNumBits(),
&nNewWidthBytes, 8);
if( pBuffer == NULL ) return( NULL );
//獲得顏色數(shù)
nNumColors = m_pDibObject->GetNumColors();
//獲得調(diào)色板指針
pPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)];
//獲得位圖數(shù)據(jù)指針
pBits = (unsigned char *) &pBuffer[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
+ nNumColors * sizeof(RGBQUAD)];
dwNewSize = nNewWidthBytes * nHeight;
//定義用于存儲色相值的臨時(shí)數(shù)組
double *pHue = new double [dwNewSize];
if(pHue == NULL) return(FALSE);
memset(pHue, 0, dwNewSize * sizeof(double));
//定義用于存儲飽和度值的臨時(shí)數(shù)組
double *pSaturation = new double [dwNewSize];
if(pSaturation == NULL) return(FALSE);
memset(pSaturation, 0, dwNewSize * sizeof(double));
//定義用于存儲亮度值的臨時(shí)數(shù)組
unsigned char *pLight = new unsigned char [dwNewSize];
if(pLight == NULL) return(FALSE);
memset(pLight, 0, dwNewSize * sizeof(unsigned char));
float *fTempArray;
//默認(rèn)為3×3的高通濾波器1模板
static float fpDefaultArray[] = {-1.0, -1.0, -1.0,
-1.0, 9.0, -1.0,
-1.0, -1.0, -1.0};
//沒有傳入模板,用默認(rèn)模板
if( fpArray == NULL ) fTempArray = fpDefaultArray;
//采用傳入的模板
else fTempArray = fpArray;
//調(diào)用Template操作函數(shù)
if(!TemplateOperation(fTempArray, fCoef, nTempW, nTempH, nTempXc, nTempYc,
pBits, nWidthBytes, nX1, nY1, nX2, nY2))
{
return(FALSE);
}
//內(nèi)存解鎖
::GlobalUnlock(m_pDibObject->GetDib());
return( TRUE );
}
////////////////////////////////////////////////////////////////////////
//BOOL MedianFilter()
//----------------------------------------------------------------------
//基本功能:本函數(shù)對傳入的CDibObject圖像對象進(jìn)行中值濾波。任何未指定的或
// 默認(rèn)為-1的坐標(biāo)將被置為圖像的邊緣值。比如:nX1和nY1會被置為0;
// nX2和nY2會被置為圖像的寬和高。對整個圖像進(jìn)行中值濾波的最好方
// 法是不傳遞任何參數(shù)。如果不指定一個CDibObject對象指針,函數(shù)將
// 使用原先傳入的CDibObject對象指針。
//----------------------------------------------------------------------
//參數(shù)說明:int nType 獲取中值的方式, 默認(rèn)為1
// 0——冒泡排序
// 1——數(shù)組排序
// int nTempW 窗口的寬度
// int nTempH 窗口的高度
// int nTempXc 窗口的中心元素X坐標(biāo)
// int nTempYc 窗口的中心元素Y坐標(biāo)
// int nX1 默認(rèn)為-1
// int nY1 默認(rèn)為-1
// int nX2 默認(rèn)為-1
// int nY2 默認(rèn)為-1
//
//----------------------------------------------------------------------
//返 回:BOOL
// 成功時(shí)返回TRUE,失敗時(shí)返回FALSE。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
BOOL CAreaPro::MedianFilter(int nType, int nTempW, int nTempH, int nTempXc,
int nTempYc, int nX1, int nY1, int nX2, int nY2)
{
//圖像指針為空,無法操作返回
if(m_pDibObject == NULL) return(FALSE);
//對1位及4位圖像不作任何操作直接返回
if(m_pDibObject->GetNumBits() != 8)
{
// 提示用戶參數(shù)設(shè)置錯誤
AfxMessageBox("只支持8位圖像,請重新載入!");
// 返回
return( FALSE );
}
//坐標(biāo)規(guī)整化
m_pDibObject->NormalizeCoordinates( &nX1, &nY1, &nX2, &nY2 );
//獲取圖像寬度和高度(以像素為單位)
int nWidth = m_pDibObject->GetWidth();
int nHeight = m_pDibObject->GetHeight();
//對邊界像素不作處理
if( nX1 < nTempXc ) nX1 = nTempXc;
if( nY1 < nTempYc ) nY1 = nTempYc;
if( nX2 >= nWidth - nTempW + nTempXc) nX2 = nWidth - nTempW + nTempXc + 1;
if( nY2 >= nHeight - nTempH + nTempYc) nY2 = nHeight - nTempH + nTempYc + 1;
//定義變量
unsigned char Data;
//定義與圖像數(shù)據(jù)操作有關(guān)的變量
unsigned char *pOldBuffer, *pNewBuffer,
*pOldBits, *pNewBits,
*pOldTemp, *pNewTemp,
*pNeighborTemp;
BITMAPFILEHEADER *pOldBFH, *pNewBFH;
BITMAPINFOHEADER *pOldBIH, *pNewBIH;
RGBQUAD *pOldPalette, *pNewPalette;
int nWidthBytes, nNumColors, x, y, i, j;
//獲取原圖像指針
pOldBuffer = (unsigned char *) m_pDibObject->GetDIBPointer( &nWidthBytes,
m_pDibObject->GetNumBits() );
if( pOldBuffer == NULL ) return( FALSE );
//原圖像文件頭
pOldBFH = (BITMAPFILEHEADER *) pOldBuffer;
//原圖像信息頭
pOldBIH = (BITMAPINFOHEADER *) &pOldBuffer[sizeof(BITMAPFILEHEADER)];
//原圖像顏色數(shù)
nNumColors = m_pDibObject->GetNumColors();
//原圖像調(diào)色板指針
pOldPalette = (RGBQUAD *) &pOldBuffer[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)];
//原圖像數(shù)據(jù)指針
pOldBits = (unsigned char *) &pOldBuffer[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
+ nNumColors * sizeof(RGBQUAD)];
DWORD dwNewSize;
HGLOBAL hNewDib;
//新圖像文件大小(以字節(jié)為單位)
dwNewSize = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) +
nNumColors * sizeof( RGBQUAD ) + nWidthBytes * nHeight;
//為新圖像分配內(nèi)存
hNewDib = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewSize );
//內(nèi)存分配失敗
if( hNewDib == NULL )
{
m_pDibObject->m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR;
::GlobalUnlock( m_pDibObject->GetDib() );
return( FALSE );
}
//新圖像指針
pNewBuffer = (unsigned char *) ::GlobalLock( hNewDib );
if( pNewBuffer == NULL )
{
::GlobalFree( hNewDib );
m_pDibObject->m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
::GlobalUnlock( m_pDibObject->GetDib() );
return( FALSE );
}
//新圖像文件頭
pNewBFH = (BITMAPFILEHEADER *) pNewBuffer;
//新圖像信息頭
pNewBIH = (BITMAPINFOHEADER *) &pNewBuffer[sizeof(BITMAPFILEHEADER)];
//新圖像調(diào)色板指針
pNewPalette = (RGBQUAD *) &pNewBuffer[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)];
//新圖像數(shù)據(jù)指針
pNewBits = (unsigned char *) &pNewBuffer[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
+ nNumColors*sizeof(RGBQUAD)];
//復(fù)制原圖像數(shù)據(jù)到新圖像
//復(fù)制文件頭
memcpy(pNewBFH, pOldBFH, sizeof(BITMAPFILEHEADER));
//復(fù)制信息頭
memcpy(pNewBIH, pOldBIH, sizeof(BITMAPINFOHEADER));
//復(fù)制調(diào)色板
for(i = 0; i < nNumColors; i++ ) pNewPalette[i] = pOldPalette[i];
//復(fù)制圖像數(shù)據(jù)
memcpy( pNewBits, pOldBits, nWidthBytes * nHeight );
//計(jì)算模板的尺寸
int nSize = nTempW * nTempH;
//定義查找中值用的臨時(shí)數(shù)組
unsigned char *pGray = new unsigned char [nTempW * nTempH];
if(pGray == NULL) return( NULL );
memset(pGray, 0, (nSize) * sizeof(unsigned char));
unsigned char nData;
switch(m_pDibObject->GetNumBits())
{
case 8: //8位圖像
//行位置
for(y = nY1; y < nY2; y++ )
{
//原圖像數(shù)據(jù)指針定位到起始位置
pOldTemp = pOldBits;
//原圖像數(shù)據(jù)指針定位到圖像數(shù)據(jù)每行的起始零位置
pOldTemp += (nHeight - 1 - y) * nWidthBytes;
//原圖像數(shù)據(jù)指針定位到圖像數(shù)據(jù)每行的起始nX1位置
pOldTemp += nX1;
//新圖像數(shù)據(jù)指針定位到起始位置
pNewTemp = pNewBits;
//新圖像數(shù)據(jù)指針定位到圖像數(shù)據(jù)每行的起始零位置
pNewTemp += (nHeight - 1 - y) * nWidthBytes;
//新圖像數(shù)據(jù)指針定位到圖像數(shù)據(jù)每行的起始nX1位置
pNewTemp += nX1;
//列位置
for(x = nX1; x < nX2; x++)
{
//取出原圖像nTempW×nTempH鄰域內(nèi)的像素值
for (i = 0; i < nTempH; i++)
{
for (j = 0; j < nTempW; j++)
{
//數(shù)據(jù)指針指向當(dāng)前像素
pNeighborTemp = pOldTemp;
//數(shù)據(jù)指針指向原圖像第y - nTempYc + i行。
pNeighborTemp += nWidthBytes * (nTempYc - i);
//第x - nTempXc + j列像素的指針
pNeighborTemp += (j - nTempXc);
//獲取像素值
Data = *pNeighborTemp;
pGray[i*nTempW+j] = ( pOldPalette[Data].rgbRed * 30 +
pOldPalette[Data].rgbGreen * 59 +
pOldPalette[Data].rgbBlue * 11 ) / 100;
}
}
nData = GetMedian(pGray, nSize, nType);
//將計(jì)算結(jié)果賦于新圖像
*pNewTemp = (unsigned char) m_pDibObject->GetNearestIndex(
pNewPalette[nData].rgbRed, pNewPalette[nData].rgbGreen,
pNewPalette[nData].rgbBlue, pNewPalette, nNumColors );
//新舊圖像數(shù)據(jù)指針加1
pOldTemp++;
pNewTemp++;
}
}
break;
}
//釋放內(nèi)存
delete [] pGray;
::GlobalUnlock( m_pDibObject->GetDib() );
::GlobalFree( m_pDibObject->GetDib() );
::GlobalUnlock( hNewDib );
m_pDibObject->SetDib( hNewDib );
return(TRUE);
}
////////////////////////////////////////////////////////////////////////
//BOOL TemplateOperation()
//----------------------------------------------------------------------
//基本功能:該函數(shù)用指定的模板(任意大小)來對圖像數(shù)據(jù)區(qū)的數(shù)據(jù)進(jìn)行模板操
// 作,參數(shù)nTempH指定模板的高度,參數(shù)nTempW指定模板的寬度,參數(shù)
// nTempXc和nTempYc指定模板的中心元素坐標(biāo),參數(shù)fpArray為指定模
// 板元素?cái)?shù)組的指針,fCoef指定模板系數(shù)。
//----------------------------------------------------------------------
//參數(shù)說明:float *fpArray 指向模板數(shù)組的指針
// float fCoef 模板系數(shù)
// int nTempW 模板的寬度
// int nTempH 模板的高度
// int nTempXc 模板的中心元素X坐標(biāo) ( <= nTempW - 1)
// int nTempYc 模板的中心元素Y坐標(biāo) ( <= nTempH - 1)
// unsigned char *pData 圖像數(shù)據(jù)指針
// int nWidthBytes 圖像字節(jié)寬度
// int nX1 處理區(qū)域左邊界
// int nY1 處理區(qū)域上邊界
// int nX2 處理區(qū)域右邊界
// int nY2 處理區(qū)域下邊界
//----------------------------------------------------------------------
//返 回:BOOL
// 成功時(shí)返回TRUE,失敗時(shí)返回FALSE。
//----------------------------------------------------------------------
//注 意:此函數(shù)聲明為保護(hù)型,只能在CAreaPro類中使用。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
BOOL CAreaPro::TemplateOperation(float *fpArray, float fCoef,
int nTempW, int nTempH, int nTempXc, int nTempYc,
unsigned char *pData, int nWidthBytes,
int nX1, int nY1, int nX2, int nY2)
{
//獲取圖像高度(以像素為單位)
int nHeight = m_pDibObject->GetHeight();
//定義變量
unsigned char Data;
//定義與圖像數(shù)據(jù)操作有關(guān)的變量
unsigned char *pOldBits, *pNewBits,
*pOldTemp, *pNewTemp,
*pNeighborTemp;
int nNumColors, x, y, i, j;
DWORD dwNewSize;
//原圖像顏色數(shù)
nNumColors = m_pDibObject->GetNumColors();
//原圖像數(shù)據(jù)指針
pOldBits = pData;
HGLOBAL hNewDib;
//新圖像文件大小(以字節(jié)為單位)
dwNewSize = nWidthBytes * nHeight;
//為新圖像分配內(nèi)存
hNewDib = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewSize );
//內(nèi)存分配失敗
if( hNewDib == NULL )
{
m_pDibObject->m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR;
::GlobalUnlock( m_pDibObject->GetDib() );
return( FALSE );
}
//新圖像指針
pNewBits = (unsigned char *) ::GlobalLock( hNewDib );
if( pNewBits == NULL )
{
::GlobalFree( hNewDib );
m_pDibObject->m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
return( FALSE );
}
//復(fù)制圖像數(shù)據(jù)
memcpy( pNewBits, pOldBits, nWidthBytes * nHeight );
//定義卷積運(yùn)算中用的臨時(shí)數(shù)組
float *pGray = new float [nTempW * nTempH];
if(pGray == NULL) return( NULL );
memset(pGray, 0, (nTempW * nTempH) * sizeof(float));
//行位置
for(y = nY1; y < nY2; y++ )
{
//原圖像數(shù)據(jù)指針定位到起始位置
pOldTemp = pOldBits;
//原圖像數(shù)據(jù)指針定位到圖像數(shù)據(jù)每行的起始零位置
pOldTemp += (nHeight -1 - y) * nWidthBytes;
//原圖像數(shù)據(jù)指針定位到圖像數(shù)據(jù)每行的起始nX1-1位置
pOldTemp += nX1;
//新圖像數(shù)據(jù)指針定位到起始位置
pNewTemp = pNewBits;
//新圖像數(shù)據(jù)指針定位到圖像數(shù)據(jù)每行的起始零位置
pNewTemp += (nHeight -1 - y) * nWidthBytes;
//新圖像數(shù)據(jù)指針定位到圖像數(shù)據(jù)每行的起始nX1位置
pNewTemp += nX1;
//列位置
for(x = nX1; x < nX2; x++)
{
//取出原圖像nTempW×nTempH鄰域內(nèi)的像素值
for (i = 0; i < nTempH; i++)
{
for (j = 0; j < nTempW; j++)
{
//數(shù)據(jù)指針指向當(dāng)前像素
pNeighborTemp = pOldTemp;
//數(shù)據(jù)指針指向原圖像第y - nTempYc + i行。
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -