📄 pointpro.cpp
字号:
lGrayHigh += i * nHistogramBuffer[i];
}
if( lSumLow > 0 )
{
Mean1 = (float)lGrayLow / lSumLow;
}
else
{
Mean1 = 0.0;
}
if( lSumHigh > 0)
{
Mean2 = (float)lGrayHigh / lSumHigh;
}
else
{
Mean2 = 0.0;
}
//计算两类之间的方差
Sigma[th] = (float)lSumLow * lSumHigh
* (Mean1 - Mean2) * (Mean1 - Mean2);
}
//th循环结束,求方差最大的阈值
float MaxSigma = Sigma[nLevelLow];
int Thresh = 0;
for( i = nLevelLow + 1; i <= nLevelHigh; i++)
{
if(MaxSigma < Sigma[i])
{
MaxSigma = Sigma[i];
Thresh = i;
}
}
delete [] nHistogramBuffer;
return(Thresh);
}
////////////////////////////////////////////////////////////////////////
//BOOL Threshold( )
//----------------------------------------------------------------------
//基本功能:本函数对传入的CDibObject对象中的图像用给定的阈值进行阈值化
// (只对8位灰度图像有效)
//----------------------------------------------------------------------
//参数说明:int Thresh 阈值
// int Mode 阈值化方法,1对象置黑,0对象置白
// BOOL bSetPalette 是否设置调色板
// CDibObject *pDibObject, 默认为NULL。
//----------------------------------------------------------------------
//返 回:成功返回TRUE,失败返回FALSE。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
BOOL CPointPro::Threshold(int Thresh, int Mode, BOOL bSetPalette, CDibObject *pDibObject)
{
//CDibObject对象指针
if( pDibObject != NULL ) m_pDibObject = pDibObject;
//若未指定 CDibObject 对象指针返回FALSE
if( m_pDibObject == NULL ) return( -1 );
if( !IsGray256() ) return( -1 );
unsigned char *pBuffer, *pBits, *pTemp;
BITMAPINFOHEADER *pBIH;
RGBQUAD *pPalette;
int nWidthBytes, nNumColors, i;
pBuffer = (unsigned char *) m_pDibObject->GetDIBPointer( &nWidthBytes,
m_pDibObject->GetNumBits() );
if( pBuffer == NULL ) return( -1 );
//pBIH:获得位图信息头地址
pBIH = (BITMAPINFOHEADER *) &pBuffer[sizeof(BITMAPFILEHEADER)];
//nNumColors:获得调色板中的颜色数。图像为16位色或更高时为0
nNumColors = m_pDibObject->GetNumColors();
//pPalette:获得调色板数据地址
pPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
//pBits:获得位图数据地址
pBits = (unsigned char *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+
nNumColors*sizeof(RGBQUAD)];
//获取灰度图像的宽度和高度(以像素表示)
int nWidth = pBIH->biWidth;
int nHeight = pBIH->biHeight;
// 灰度映射表
unsigned char pMap[256];
switch (Mode)
{
case 1:
for( i = 0; i <= Thresh; i++) pMap[i] = 255;
for( i = Thresh + 1; i <= 255; i++) pMap[i] = 0;
break;
case 0:
for( i = 0; i <= Thresh; i++) pMap[i] = 0;
for( i = Thresh + 1; i <= 255; i++) pMap[i] = 255;
break;
}
for ( i = 0; i < nHeight; i ++)
{
pTemp = pBits;
pTemp += i * nWidthBytes; //位图数据下一行起始指针
for ( int j = 0; j < nWidth; j ++)
{
pTemp[j] = pMap[pTemp[j]];
}
}
m_pDibObject->ProcessPalette();
if( bSetPalette && m_pDibObject->m_nPaletteBytes > 0 )
{
CWindowDC WindowDC( NULL );
m_pDibObject->SetPalette( &WindowDC );
}
::GlobalUnlock( m_pDibObject->GetDib() );
m_pDibObject->m_nLastError = IMAGELIB_SUCCESS;
return TRUE;
}
////////////////////////////////////////////////////////////////////////
//BOOL IsGray256(CDibObject *pDibObject)
//----------------------------------------------------------------------
//基本功能:本函数判断传入的CDibObject对象中的图像是否为256级灰度图像。
//----------------------------------------------------------------------
//参数说明:CDibObject *pDibObject, 默认为NULL
//----------------------------------------------------------------------
//返回:BOOL:成功返回TRUE,失败返回FALSE。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
BOOL CPointPro::IsGray256( CDibObject *pDibObject )
{
//使用传入的CDibObject对象
if( pDibObject != NULL ) m_pDibObject = pDibObject;
//无CDibObject对象, 返回FALSE
if( m_pDibObject == NULL ) return( FALSE );
//不是8位图像,必不是256级灰度图像,不处理返回FALSE
if( m_pDibObject->GetNumBits() != 8 ) return( FALSE );
//定义变量
unsigned char *pBuffer;
RGBQUAD *pPalette;
int nWidthBytes, i;
//pBuffer: 获得位图数据指针
pBuffer = (unsigned char *) m_pDibObject->GetDIBPointer( &nWidthBytes,
m_pDibObject->GetNumBits() );
if( pBuffer == NULL ) return( FALSE );
//pPalette:获得调色板数据地址
pPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER)+
sizeof(BITMAPINFOHEADER)];
//检查是否为256色灰度调色板
for( i=0; i<256; i++ )
{
if( pPalette[i].rgbRed != pPalette[i].rgbGreen
|| pPalette[i].rgbRed != pPalette[i].rgbBlue
|| pPalette[i].rgbGreen != pPalette[i].rgbBlue )
return( FALSE);
}
::GlobalUnlock( m_pDibObject->GetDib() );
return( TRUE );
}
////////////////////////////////////////////////////////////////////////
//BOOL LinerTran(CImagObject *pDibObject, float fa, float fb)
//----------------------------------------------------------------------
//基本功能:本函数对传入的CDibObject对象中的图像进行灰度的线性变换。如
// 果进行此调整之前没有指定一个CDibObject对象指针,则必须在调
// 整时加以指定。任何未传入的坐标值或默认的-1坐标值都将被置为图
// 像的最大值或最大植。变量nX1和nY1将被置为0,nX2将被置为图像宽
// 度减1,nY2将被置为图像高度减1。想要在整个图像上进行操作时,
// 最好的方法是不传入nX1、nY1、nX2和nY2值。这样它们会被默认为整
// 个图像。
//----------------------------------------------------------------------
//参数说明:float fa 线性变换的斜率
// float fb 线性变换的截距
// int nX1, 默认为-1
// int nY1, 默认为-1
// int nX2, 默认为-1
// int nY2, 默认为-1
// CDibObject *pDibObject, 默认为NULL
//----------------------------------------------------------------------
//返回:BOOL;成功返回TRUE,失败返回FALSE。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
BOOL CPointPro::LinerTran(float fa, float fb,
int nX1,
int nY1,
int nX2,
int nY2,
CDibObject *pDibObject)
{
//CDibObject对象指针
if( pDibObject != NULL ) m_pDibObject = pDibObject;
//若未指定 CDibObject 对象指针返回FALSE
if( m_pDibObject == NULL ) return( FALSE );
BOOL bLessThanHalf, bCompleteImage;
m_pDibObject->NormalizeCoordinates( &nX1, &nY1, &nX2, &nY2,
&bCompleteImage,
&bLessThanHalf );
//定义变量
unsigned char *pBuffer, *pBits, *pTemp;
BITMAPINFOHEADER *pBIH;
RGBQUAD *pPalette;
int nWidthBytes, nNumColors, x, y, i;
//pBuffer: 获得位图数据指针
pBuffer = (unsigned char *) m_pDibObject->GetDIBPointer( &nWidthBytes,
m_pDibObject->GetNumBits() );
if( pBuffer == NULL ) return( FALSE );
//pBIH:获得位图信息头地址
pBIH = (BITMAPINFOHEADER *) &pBuffer[sizeof(BITMAPFILEHEADER)];
//nNumColors:获得调色板中的颜色数。图像为16位色或更高时为0
nNumColors = m_pDibObject->GetNumColors();
//pPalette:获得调色板数据地址
pPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
//pBits:获得位图数据地址
pBits = (unsigned char *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+
nNumColors*sizeof(RGBQUAD)];
LOGPALETTE *pLogPal = m_pDibObject->GetLogPal();
CPalette *_pPalette = m_pDibObject->GetPalette();
//创建灰度映射表
unsigned char *pMap = PointSlopeLinerTran(fa, fb);
switch( m_pDibObject->GetNumBits() )
{
case 1:
for( y=nY1; y<=nY2; y++ )
{
unsigned char Mask;
pTemp = pBits;
pTemp += ( ( ( m_pDibObject->GetHeight() - 1 - y )
* nWidthBytes ) + ( nX1 / 8 ) );
for( x=nX1; x<=nX2; x++ )
{
Mask = 0x80 >> ( x & 7 );
if( pTemp[0] & Mask ) pTemp[0] &= ( Mask ^ 0xff );
else pTemp[0] |= Mask;
if( ( x & 7 ) == 7 ) pTemp++;
}
}
break;
case 4:
if( bCompleteImage )
{
_pPalette->DeleteObject();
for( i=0; i<nNumColors; i++ )
{
pPalette[i].rgbRed = pMap[pPalette[i].rgbRed];
pPalette[i].rgbGreen = pMap[pPalette[i].rgbGreen];
pPalette[i].rgbBlue = pMap[pPalette[i].rgbBlue];
}
LOGPALETTE *pLogPal = m_pDibObject->CreateLogPalette(
pPalette, nNumColors );
if( pLogPal != NULL )
{
_pPalette->CreatePalette( pLogPal );
delete [] pLogPal;
}
}
else
{
unsigned char ucRed, ucGreen, ucBlue, Data;
for( y=nY1; y<=nY2; y++ )
{
pTemp = pBits;
pTemp += ( ( ( m_pDibObject->GetHeight() - 1 - y )
* nWidthBytes ) + ( nX1 / 2 ) );
for( x=nX1; x<=nX2; x++ )
{
Data = *pTemp;
if( !( x & 1 ) ) Data >>= 4;
else Data &= 0x0f;
ucRed = pPalette[Data].rgbRed;
ucGreen = pPalette[Data].rgbGreen;
ucBlue = pPalette[Data].rgbBlue;
ucRed = pMap[ucRed];
ucGreen = pMap[ucGreen];
ucBlue = pMap[ucBlue];
Data = (unsigned char) m_pDibObject->GetNearestIndex( ucRed, ucGreen,
ucBlue, pPalette, nNumColors );
if( !( x & 1 ) )
{
Data <<= 4;
(*pTemp) &= 0x0f;
(*pTemp) |= Data;
}
else
{
(*pTemp) &= 0xf0;
(*pTemp) |= Data;
pTemp++;
}
}
}
}
break;
case 8:
if(IsGray256())
{
for( y=nY1; y<=nY2; y++ )
{
pTemp = pBits;
pTemp += ( ( ( m_pDibObject->GetHeight() - 1 - y )
* nWidthBytes ) + nX1 );
for( x=nX1; x<=nX2; x++ )
{
pTemp[x] = pMap[pTemp[x]];
}
}
}
else if( bCompleteImage )
{
_pPalette->DeleteObject();
for( i=0; i<nNumColors; i++ )
{
pPalette[i].rgbRed = pMap[pPalette[i].rgbRed];
pPalette[i].rgbGreen = pMap[pPalette[i].rgbGreen];
pPalette[i].rgbBlue = pMap[pPalette[i].rgbBlue];
}
LOGPALETTE *pLogPal = m_pDibObject->CreateLogPalette( pPalette, nNumColors );
if( pLogPal != NULL )
{
_pPalette->CreatePalette( pLogPal );
delete [] pLogPal;
}
}
else
{
unsigned char ucRed, ucGreen, ucBlue, Data;
for( y=nY1; y<=nY2; y++ )
{
pTemp = pBits;
pTemp += ( ( ( m_pDibObject->GetHeight() - 1 - y )
* nWidthBytes ) + nX1 );
for( x=nX1; x<=nX2; x++ )
{
Data = *pTemp;
ucRed = pPalette[Data].rgbRed;
ucGreen = pPalette[Data].rgbGreen;
ucBlue = pPalette[Data].rgbBlue;
ucRed = pMap[ucRed];
ucGreen = pMap[ucGreen];
ucBlue = pMap[ucBlue];
Data = (unsigned char) m_pDibObject->GetNearestIndex( ucRed,
ucGreen, ucBlue, pPalette, nNumColors );
*pTemp++ = Data;
}
}
}
break;
case 16:
unsigned char ucRed, ucGreen, ucBlue;
for( y=0; y< nY2; y++ )
{
pTemp = pBits;
pTemp += ( ( m_pDibObject->GetHeight() - 1 - y )
* nWidthBytes );
pTemp += ( nX1 * 2 );
for( x=nX1; x<=nX2; x++ )
{
GETRGB555( ucRed, ucGreen, ucBlue, pTemp );
ucRed = pMap[ucRed];
ucGreen = pMap[ucGreen];
ucBlue = pMap[ucBlue];
PUTRGB555( ucRed, ucGreen, ucBlue, pTemp );
pTemp += 2;
}
}
break;
case 24:
for( y=nY1; y<=nY2; y++ )
{
pTemp = pBits;
pTemp += ( ( ( m_pDibObject->GetHeight() - 1 - y )
* nWidthBytes ) + ( nX1 * 3 ) );
for( x=nX1; x<=nX2; x++ )
{
pTemp[0] = pMap[pTemp[0]];
pTemp[1] = pMap[pTemp[1]];
pTemp[2] = pMap[pTemp[2]];
pTemp += 3;
}
}
break;
case 32:
for( y=nY1; y<=nY2; y++ )
{
pTemp = pBits;
pTemp += ( ( ( m_pDibObject->GetHeight() - 1 - y )
* nWidthBytes ) + ( nX1 * 4 ) );
for( x=nX1; x<=nX2; x++ )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -