📄 pointpro.cpp
字号:
m_pDibObject->ProcessImageHeader();
m_pDibObject->m_nLastError = IMAGELIB_SUCCESS;
return( TRUE );
}
////////////////////////////////////////////////////////////////////////
//void SetDibObjectClass(CDibObject *pDibObject)
//----------------------------------------------------------------------
//基本功能:本函数为CImagePointProcess类对象指定一个CDibObject对象指针
//----------------------------------------------------------------------
//参数说明:CDibObject *pDibObject, 默认为NULL。
//----------------------------------------------------------------------
//返 回:无。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
void CPointPro::SetDibObjectClass( CDibObject *pDibObject )
{
m_pDibObject = pDibObject;
}
////////////////////////////////////////////////////////////////////////
//int *CreateHistogram()
//----------------------------------------------------------------------
//基本功能:本函数创建传入的CDibObject对象中图像的直方图。如果进行此调
// 整之前没有指定一个CDibObject对象指针,则必须在调整时加以指
// 定。任何未传入的坐标值或默认的-1坐标值都将被置为图像的最大值
// 或最大植。变量nX1和nY1将被置为0,nX2将被置为图像宽度减1,nY2
// 将被置为图像高度减1。想要在整个图像上进行操作时,最好的方法
// 是不传入nX1、nY1、nX2和nY2值。这样它们会被默认为整个图像。
//----------------------------------------------------------------------
//参数说明:int nX1 默认为-1
// int nY1 默认为-1
// int nX2 默认为-1
// int nY2 默认为-1
// unsigned char *pData 图像位图数据指针
// RGBQUAD *pPalette 图像调色板指针
// int nWidthBytes 图像字节宽度
// CDibObject *pDibObject 默认为NULL。
//----------------------------------------------------------------------
//返 回:直方图数组指针*pBuffer其中:
// pBuffer[] 存储亮度直方图数据
// pBuffer[256] 存储红色直方图数据
// pBuffer[512] 存储绿色直方图数据
// pBuffer[768] 存储蓝直方图数据
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
int *CPointPro::CreateHistogram( int nX1, int nY1, int nX2, int nY2,
unsigned char *pData, RGBQUAD *pPalette,
int nWidthBytes, CDibObject *pDibObject )
{
//图像指针为空,无法操作返回
if( pDibObject != NULL ) m_pDibObject = pDibObject;
if( m_pDibObject == NULL ) return( FALSE );
//分配直方图数据缓存区(数组)
int *pBuffer = new int [256 * 4];
//分配直方图数据缓存区失败
if( pBuffer == NULL ) return( NULL );
//直方图数据缓存区清零
memset( pBuffer, 0, ( 256 * 4) * sizeof( int ) );
//变量定义
DWORD dwGray;
int x, y;
unsigned char *pTemp, ucRed, ucGreen, ucBlue;
//图像的高度
int nHeight = m_pDibObject->GetHeight();
switch( m_pDibObject->GetNumBits() )
{
case 1: //每像素位数为1,不处理
break;
case 4: //每像素位数为4,不处理
break;
case 8: //每像素位数为8
for( y = nY1; y <= nY2; y++ )
{
//数据指针定位到图像数据起始位置
pTemp = pData;
//数据指针定位到图像数据每行的起始零位置
pTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
//数据指针定位到图像数据每行的起始nX1位置
pTemp += nX1;
for( x = nX1; x <= nX2; x++ )
{
//pTemp[x]为当前像素值,它为调色板项的索引值,
//以此为索引,取出调色板项的相应红绿蓝分量值。
ucRed = pPalette[pTemp[x]].rgbRed;
ucGreen = pPalette[pTemp[x]].rgbGreen;
ucBlue = pPalette[pTemp[x]].rgbBlue;
//按关系L=0.3R+0.59G+0.11B,得到亮度值
dwGray = ( (DWORD) ucRed * 30 +
(DWORD) ucGreen * 59 +
(DWORD) ucBlue * 11 ) / 100;
dwGray &= 0x000000ff;
//亮度直方图数据
pBuffer[dwGray]++;
//红色直方图数据
pBuffer[256 + ucRed]++;
//绿色直方图数据
pBuffer[512 + ucGreen]++;
//蓝色直方图数据
pBuffer[768 + ucBlue]++;
}
}
break;
case 16: //每像素位数为16
for( y = nY1; y <= nY2; y++ )
{
//数据指针定位到图像数据起始位置
pTemp = pData;
//数据指针定位到图像数据每行的起始零位置
pTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
//数据指针定位到图像数据每行的起始nX1位置
pTemp += ( nX1 * 2 );
for( x = nX1; x <= nX2; x++ )
{
//获取三原色分量
GETRGB555( ucRed, ucGreen, ucBlue, pTemp );
//按关系L=0.3R+0.59G+0.11B,得到亮度值
dwGray = ( (DWORD) ucRed * 30 +
(DWORD) ucGreen * 59 +
(DWORD) ucBlue * 11 ) / 100;
dwGray &= 0x000000ff;
//亮度直方图数据
pBuffer[dwGray]++;
//红色直方图数据
pBuffer[256 + ucRed]++;
//绿色直方图数据
pBuffer[512 + ucGreen]++;
//蓝色直方图数据
pBuffer[768 + ucBlue]++;
//数据指针加2
pTemp += 2;
}
}
break;
case 24: //每像素位数为24
for( y = nY1; y < nY2; y++ )
{
//数据指针定位到图像数据起始位置
pTemp = pData;
//数据指针定位到图像数据每行的起始零位置
pTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
//数据指针定位到图像数据每行的起始nX1位置
pTemp += ( nX1 * 3 );
for( x=nX1; x<=nX2; x++ )
{
//获取像素颜色的三原色。
ucRed = pTemp[x * 3 + 2];
ucGreen = pTemp[x * 3 + 1];
ucBlue = pTemp[x * 3];
//按关系L=0.3R+0.59G+0.11B,得到亮度值
dwGray = ( (DWORD) ucRed * 30 +
(DWORD) ucGreen * 59 +
(DWORD) ucBlue * 11 ) / 100;
dwGray &= 0x000000ff;
//亮度直方图数据
pBuffer[dwGray]++;
//红色直方图数据
pBuffer[256 + ucRed]++;
//绿色直方图数据
pBuffer[512 + ucGreen]++;
//蓝色直方图数据
pBuffer[768 + ucBlue]++;
//数据指针加3
pTemp += 3;
}
}
break;
case 32: //每像素位数为24
for( y = nY1; y <= nY2; y++ )
{
//数据指针定位到图像数据起始位置
pTemp = pData;
//数据指针定位到图像数据每行的起始零位置
pTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
//数据指针定位到图像数据每行的起始nX1位置
pTemp += ( nX1 * 4 );
for( x = nX1; x <= nX2; x++ )
{
//获取像素颜色的三原色。
GETRGB888( ucRed, ucGreen, ucBlue, pTemp );
//按关系L=0.3R+0.59G+0.11B,得到亮度值
dwGray = ( (DWORD) ucRed * 30 +
(DWORD) ucGreen * 59 +
(DWORD) ucBlue * 11 ) / 100;
dwGray &= 0x000000ff;
//亮度直方图数据
pBuffer[dwGray]++;
//红色直方图数据
pBuffer[256 + ucRed]++;
//绿色直方图数据
pBuffer[512 + ucGreen]++;
//蓝色直方图数据
pBuffer[768 + ucBlue]++;
pTemp += 4;
}
}
break;
}
return( pBuffer );
}
////////////////////////////////////////////////////////////////////////
//int FindThresh_Auto( CDibObject *pDibObject )
//----------------------------------------------------------------------
//基本功能:本函数对传入的CDibObject对象中的图像用用自调整阈值法确定阈
// 值(只对8位灰度图像有效)
//----------------------------------------------------------------------
//参数说明:CDibObject *pDibObject, 默认为NULL。
//----------------------------------------------------------------------
//返 回:int 阈值
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
int CPointPro::FindThresh_Auto( CDibObject *pDibObject )
{
if( pDibObject != NULL ) m_pDibObject = pDibObject; //CDibObject对象指针
if( m_pDibObject == NULL ) return( -1 ); //若未指定 CDibObject 对象指针返回FALSE
unsigned char *pBuffer, *pBits;
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)];
if (pBIH->biBitCount != 8) return (-1);
//获取灰度图像的宽度和高度(以像素表示)
int nWidth = pBIH->biWidth;
int nHeight = pBIH->biHeight;
int *pHistogram = GetHistogram();
long MaxPiex1 = 0;
long MaxPiex2 = 0;
unsigned char MaxGray1, MaxGray2;
for(i = 0; i < 256; i++)
{
if ( pHistogram[i] > MaxPiex1)
{
MaxPiex1 = pHistogram[i];
MaxGray1 = i;
}
}
for(i = 0; i < 256; i++)
{
if ( pHistogram[i] > MaxPiex2 && pHistogram[i] < MaxPiex1)
{
MaxPiex2 = pHistogram[i];
MaxGray2 = i;
}
}
unsigned char Temp;
if(MaxGray1 > MaxGray2)
{
Temp = MaxGray1;
MaxGray1 = MaxGray2;
MaxGray2 = MaxGray1;
}
int Thresh;
long MinPiex = nWidth * nHeight;
for(i = MaxGray1; i <= MaxGray2; i++)
{
if(pHistogram[i] < MinPiex) Thresh = i;
}
delete [] pHistogram;
return(Thresh);
}
////////////////////////////////////////////////////////////////////////
//int FindThresh( CDibObject *pDibObject )
//----------------------------------------------------------------------
//基本功能:本函数对传入的CDibObject对象中的图像用判别分析法确定阈值,
// 本函数中对于像素总数大于等于255的图像采用其直方图数据作为最
// 佳阈值的数据源,对于像素总数小于255的图像直接采用图像数据作
// 为最佳阈值的数据源,这样可大大提高计算速度。
//----------------------------------------------------------------------
//参数说明:CDibObject *pDibObject, 默认为NULL。
//----------------------------------------------------------------------
//返 回:int 阈值
//----------------------------------------------------------------------
//注: 只对8位灰度图像有效
////////////////////////////////////////////////////////////////////////
int CPointPro::FindThresh_Discriminant( CDibObject *pDibObject )
{
//CDibObject对象指针
if( pDibObject != NULL ) m_pDibObject = pDibObject;
//若未指定 CDibObject 对象指针返回FALSE
if( m_pDibObject == NULL ) return( -1 );
unsigned char *pBuffer, *pBits;
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)];
if (pBIH->biBitCount != 8) return (-1);
//获取灰度图像的宽度和高度(以像素表示)
int nWidth = pBIH->biWidth;
int nHeight = pBIH->biHeight;
int *nHistogramBuffer = GetHistogram();
float Sigma[256];
float Mean1, Mean2;
//Sigma[256]数组清零
for( i = 0;i < 256; i++) Sigma[i] = 0.0;
int nLevelLow = 0;
int nLevelHigh = 0;
//查找最小灰度值
i = 0;
while(nLevelLow == 0)
{
if( nHistogramBuffer[i] != 0 )
{
nLevelLow = i;
}
i++;
}
//查找最大灰度值
i = 255;
while(nLevelHigh == 0)
{
if( nHistogramBuffer[i] != 0 )
{
nLevelHigh = i;
}
i--;
}
//th循环,小于阈值th的像素归为第一类,大于th的像素归为第二类
//th=0、1、2、…、nLevel。
for(int th = nLevelLow; th <= nLevelHigh; th++)
{
long lGrayLow = 0;
long lGrayHigh = 0;
long lSumLow = 0;
long lSumHigh = 0;
for(i = nLevelLow; i < th; i++)
{
lSumLow += nHistogramBuffer[i];
lGrayLow += i * nHistogramBuffer[i];
}
for(i = th; i <= nLevelHigh; i++)
{
lSumHigh += nHistogramBuffer[i];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -