📄 areapro.cpp
字号:
pNeighborTemp += nWidthBytes * (nTempYc - i);
//第x - nTempXc + j列像素的指针
pNeighborTemp += (j - nTempXc);
//获取像素值
Data = *pNeighborTemp;
pGray[i * nTempW + j] = (float)Data;
}
}
//卷积核尺寸
int nSize = nTempW * nTempH;
//对红色分量作卷积
Convolution(pGray, fpArray, fCoef, nSize, &Data);
//将计算结果赋于新图像
*pNewTemp = Data;
//新旧图像数据指针加1
pOldTemp++;
pNewTemp++;
}
}
//释放内存
delete [] pGray;
//复制图像数据
memcpy( pOldBits, pNewBits, nWidthBytes * nHeight );
::GlobalUnlock( hNewDib );
::GlobalFree( hNewDib );
return( TRUE );
}
BOOL CAreaPro::GradSharping(int Threshold, int nX1, int nY1, int nX2, int nY2,
CDibObject *pDibObject)
{
//图像指针为空,无法操作返回
if(m_pDibObject == NULL) return(FALSE);
//只处理8位图像
if(m_pDibObject->GetNumBits() != 8)
{
AfxMessageBox("目前只支持8位灰度图像的处理!");
return( FALSE );
}
//坐标规整化
m_pDibObject->NormalizeCoordinates( &nX1, &nY1, &nX2, &nY2 );
//获取图像宽度和高度(以像素为单位)
int nWidth = m_pDibObject->GetWidth();
int nHeight = m_pDibObject->GetHeight();
int nTempXc = 0;
int nTempYc = 0;
int nTempW = 2;
int nTempH = 2;
//对边界像素不作处理
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, *pNewBits1, *pNewBits2;
RGBQUAD *pPalette;
int nWidthBytes, nNumColors;
DWORD dwNewSize;
//获得图像指针
pBuffer = (unsigned char *) m_pDibObject->GetDIBPointer( &nWidthBytes,
m_pDibObject->GetNumBits() );
if( pBuffer == NULL ) return( NULL );
//获得颜色数
nNumColors = m_pDibObject->GetNumColors();
//获得调色板指针
pPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)];
//获得位图数据指针
pBits = (unsigned char *) &pBuffer[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
+ nNumColors * sizeof(RGBQUAD)];
HGLOBAL hNewDib1, hNewDib2;
//新图像文件大小(以字节为单位)
dwNewSize = nWidthBytes * nHeight;
//为新图像分配内存
hNewDib1 = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewSize );
//内存分配失败
if( hNewDib1 == NULL )
{
m_pDibObject->m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR;
::GlobalUnlock( m_pDibObject->GetDib() );
return( FALSE );
}
//新图像指针
pNewBits1 = (unsigned char *) ::GlobalLock( hNewDib1 );
if( pNewBits1 == NULL )
{
::GlobalFree( hNewDib1 );
m_pDibObject->m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
return( FALSE );
}
//复制图像数据
memcpy(pNewBits1, pBits, nWidthBytes * nHeight);
//为新图像分配内存
hNewDib2 = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewSize );
//内存分配失败
if( hNewDib2 == NULL )
{
m_pDibObject->m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR;
::GlobalUnlock( m_pDibObject->GetDib() );
return( FALSE );
}
//新图像指针
pNewBits2 = (unsigned char *) ::GlobalLock( hNewDib2 );
if( pNewBits2 == NULL )
{
::GlobalFree( hNewDib2 );
m_pDibObject->m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
return( FALSE );
}
//复制图像数据
memcpy(pNewBits2, pBits, nWidthBytes * nHeight);
float aTemplate[4];
//Roberts H1模板
aTemplate[0] = 1.0;
aTemplate[1] = 0.0;
aTemplate[2] = -1.0;
aTemplate[3] = 0.0;
//调用Template操作函数
if(!TemplateOperation(aTemplate, 1.0, nTempW, nTempH, nTempXc, nTempYc,
pNewBits1, nWidthBytes,
nX1, nY1, nX2, nY2))
{
return(FALSE);
}
//Roberts H2模板
aTemplate[0] = 0.0;
aTemplate[1] = 1.0;
aTemplate[2] = 0.0;
aTemplate[3] = -1.0;
//调用Template操作函数
if(!TemplateOperation(aTemplate, 1.0, nTempW, nTempH, nTempXc, nTempYc,
pNewBits2, nWidthBytes,
nX1, nY1, nX2, nY2))
{
return(FALSE);
}
//定义与图像数据操作有关的变量
unsigned char *pOldTemp, *pNewTemp1, *pNewTemp2;
int x, y;
DWORD dwTemp;
switch(m_pDibObject->GetNumBits())
{
case 8: //8位图像
//行位置
for(y = nY1; y <= nY2; y++ )
{
//原图像数据指针定位到起始位置
pOldTemp = pBits;
//原图像数据指针定位到图像数据每行的起始零位置
pOldTemp += y * nWidthBytes;
//原图像数据指针定位到图像数据每行的起始nX1-1位置
pOldTemp += nX1;
//新图像数据指针定位到起始位置
pNewTemp1 = pNewBits1;
//新图像数据指针定位到图像数据每行的起始零位置
pNewTemp1 += y * nWidthBytes;
//新图像数据指针定位到图像数据每行的起始nX1位置
pNewTemp1 += nX1;
//新图像数据指针定位到起始位置
pNewTemp2 = pNewBits2;
//新图像数据指针定位到图像数据每行的起始零位置
pNewTemp2 += y * nWidthBytes;
//新图像数据指针定位到图像数据每行的起始nX1位置
pNewTemp2 += nX1;
//列位置
for(x = nX1; x <= nX2; x++)
{
//计算目标图像中当前点的最终像素值
dwTemp = (DWORD)(pNewTemp1[x] + pNewTemp2[x]);
//dwTemp = (DWORD)(sqrt(pNewTemp1[x] * pNewTemp1[x]
// + pNewTemp2[x] * pNewTemp2[x]));
//判断是否小于阈值
if(dwTemp < 255)
{
//判断是否大于阈值,对于小于的情况,灰度值不变
if((int)dwTemp >= Threshold)
{
pOldTemp[x] = (unsigned char)dwTemp;
}
}
else
{
//直接赋值为255
pOldTemp[x] = 255;
}
}
}
break;
}
//内存解锁
::GlobalUnlock(m_pDibObject->GetDib());
//释放不再使用的内存
::GlobalUnlock( hNewDib1 );
::GlobalFree( hNewDib1 );
::GlobalUnlock( hNewDib2 );
::GlobalFree( hNewDib2 );
return( TRUE );
}
////////////////////////////////////////////////////////////////////////
//BOOL TemplateRotating()
//----------------------------------------------------------------------
//基本功能:该函数用于对传入的模板进行旋转操作,以获取不同方向上的模板。
//----------------------------------------------------------------------
//参数说明:float *fpTemplate 指向模板数组的指针
//----------------------------------------------------------------------
//返 回:无
//----------------------------------------------------------------------
//注 意:此函数为保护型,只能在CAreaPro类中使用,并只能用于3×3的模板。
// 此函数每次旋转45°
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
void CAreaPro::TemplateRotating(float *fpTemplate)
{
float fTemp[8];
float fDataTemp;
//将模板周围值按顺时针方向赋于一临时数组
fTemp[0] = fpTemplate[0];
fTemp[1] = fpTemplate[1];
fTemp[2] = fpTemplate[2];
fTemp[3] = fpTemplate[5];
fTemp[4] = fpTemplate[8];
fTemp[5] = fpTemplate[7];
fTemp[6] = fpTemplate[6];
fTemp[7] = fpTemplate[3];
//f进行数据旋转
fDataTemp = fTemp[7];
for(int i = 7; i > 0; i--)
{
fTemp[i] = fTemp[i - 1];
}
fTemp[0] = fDataTemp;
//求得结果
fpTemplate[0] = fTemp[0];
fpTemplate[1] = fTemp[1];
fpTemplate[2] = fTemp[2];
fpTemplate[5] = fTemp[3];
fpTemplate[8] = fTemp[4];
fpTemplate[7] = fTemp[5];
fpTemplate[6] = fTemp[6];
fpTemplate[3] = fTemp[7];
}
////////////////////////////////////////////////////////////////////////
//BOOL GetMedian()
//----------------------------------------------------------------------
//基本功能:本函数对指定的一个数组进行排序,并得到其中值。
//----------------------------------------------------------------------
//参数说明:int nType 排序方式,其取值如下:
// 0——冒泡排序
// 1——数组排序
// unsigned char *pData 数组
// int nSize 数组大小
//----------------------------------------------------------------------
//返 回:无。
//----------------------------------------------------------------------
//注 意:此函数声明为私有型,只能在CAreaPro类中使用
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
unsigned char CAreaPro::GetMedian(unsigned char *pData, int nSize, int nType)
{
int nMedian;
//指定的排序算法不可识别,用冒泡排序算法。
if(nType < 0 || nType > 1) nType = 1;
switch( nType )
{
case 0: //冒泡排序
{
int nTemp;
int nLast = nSize - 1;
bool bSorted = true;
do
{
bSorted = true;
for (int i = 0; i < nLast; i++)
{
if (pData[i] > pData[i + 1])
{
nTemp = pData[i];
pData[i] = pData[i + 1];
pData[i + 1] = nTemp;
bSorted = false;
}
}
nLast--;
} while (!bSorted);
}
nMedian = pData[nSize / 2];
break;
case 1:
{
int i;
int nHisto[256];
for( i = 0; i < 256; i++) nHisto[ i ] = 0;
//统计相同灰度值出现的次数
for( i = 0; i < nSize; i++)
{
nHisto[(int)pData[i]]++;
}
//取直方图的中值
int nCount = 0;
for( i = 0; i < 256; i++)
{
//存放直方图中相同灰度值出现次数的累加和
nCount += nHisto[i];
if(nCount >= (int)(nSize / 2 + 1))
{
nMedian = i;
break;
}
}
}
break;
}
return nMedian;
}
////////////////////////////////////////////////////////////////////////
//BOOL EdgeTracing()
//----------------------------------------------------------------------
//基本功能:本函数对传入的CDibObject图像对象进行轮廓跟踪。
//----------------------------------------------------------------------
//参数说明:CDibObject *pDibObject 图像对象指针
//----------------------------------------------------------------------
//返 回:BOOL
// 成功时返回TRUE,失败时返回FALSE。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
BOOL CAreaPro::EdgeTracing(CDibObject *pDibObject)
{
//图像指针为空,无法操作返回
if(m_pDibObject == NULL) return(FALSE);
//只支持8位图像
if(m_pDibObject->GetNumBits() != 8)
{
// 提示用户参数设置错误
AfxMessageBox("只支持8位图像,请重新载入!");
// 返回
return( FALSE );
}
//获取图像宽度和高度(以像素为单位)
int nWidth = m_pDibObject->GetWidth();
int nHeight = m_pDibObject->GetHeight();
//定义变量
unsigned char *pOldBuffer;
unsigned char *pOldBits, *pNewBits;
unsigned char *pOldTemp, *pNewTemp;
BITMAPFILEHEADER *pOldBFH;
BITMAPINFOHEADER *pOldBIH;
RGBQUAD *pOldPalette;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -