📄 grayproc.cpp
字号:
nHoleNum -- ;
// 寻找面积小于阈值的空穴区域
for(n = 1; n <= nHoleNum; n++)
{
s = 0;
for (j = 0; j < lHeight - 1; j++)
{
for(i = 0; i < lWidth - 1; i++)
{
nBlackPix =pnBinary[lLineBytes * j + i];
if(nBlackPix == n)
s++;
// 如果区域面积已经大于阈值,跳出循环
if(s > nMinArea)
break;
}
if(s > nMinArea)
break;
}
// 小于阈值的区域,赋以与背景一样的颜色,进行消去
if(s <= nMinArea)
{
for (j = 0; j < lHeight - 1; j++)
{
for(i = 0; i < lWidth - 1; i++)
{
nBlackPix =pnBinary[lLineBytes * j + i + 1];
if(nBlackPix == n)
{
pnBinary[lLineBytes * j + i + 1] = 0;
}
}
}
}
}
// 存储象素值,输出
for(j = 0; j < lHeight; j++)
{
// 列
for(i = 0; i < lWidth; i++)
{
// 二值图象
temp = pnBinary[j * lLineBytes + i] ;
// 指向位图i行j列象素的指针
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * j + i;
// 更新源图像
if(temp!= 0)
* (lpSrc) = temp;
else
* (lpSrc) = 255;
}
}
delete pnBinary;
return true;
}
/*************************************************************************
*
* 函数名称:
* ToGray()
*
* 参数:
* HDIB hDIB - 待处理的DIB
*
* 返回值:
* void - 无返回值
*
* 说明:
* 该函数将彩色位图转化为灰度图像。
*
************************************************************************/
void CGrayProc::ToGray(HDIB hDIB)
{
// 循环变量
// LONG i;
// LONG j;
// WINDOW window;
// 指向DIB的指针
LPBYTE lpDIB;
// 指向DIB象素指针
LPBYTE lpDIBBits;
// 锁定DIB
lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);
// 找到DIB图像象素起始位置
lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
// DIB的宽度
LONG lWidth = m_clsDIB.DIBWidth(lpDIB);
// DIB的高度
LONG lHeight = m_clsDIB.DIBHeight(lpDIB);
//为原图象复制一个拷贝开始/////////////
LPBYTE lpBufBits;
HLOCAL hBufBits;
// 暂时分配内存,以保存新图像
hBufBits = LocalAlloc(LHND, lWidth *3 * lHeight);
if (hBufBits == NULL)
{
// 分配内存失败
return;
}
// 锁定内存
lpBufBits = (LPBYTE)LocalLock(hBufBits);
// 复制腐蚀后的图像
memcpy(lpBufBits, lpDIBBits, lWidth *3 * lHeight);
//////////////为原图象复制一个拷贝结束//////////////
// 判断是否是24-bpp位图
if (m_clsDIB.DIBBitCount(lpDIB) != 24)
{
// 提示用户
// MessageBoxA("请先将其转换为24位色位图,再进行处理!", "系统提示" , MB_ICONINFORMATION | MB_OK);
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 返回
return;
}
//************************
//************************
CVideoPro VideoPro;
WINDOW window1,window2,window3;
MaxValue m_houghL,m_houghR;
POINT ps,pe;
int u,v;
double Locx,Locy;
window1.LeftX=0;//int(0.01*lWidth);
window1.RightX=int(0.5*lWidth);
window1.BottomY=int(0.1*lHeight);
window1.TopY=int(0.9*lHeight);
window1.MinAngle=105;
window1.MaxAngle=175;
///////////////
window2.LeftX=int(0.1*lWidth);
window2.RightX=int(0.95*lWidth);
window2.BottomY=int(0.1*lHeight);
window2.TopY=int(0.8*lHeight);
window2.MinAngle=80;
window2.MaxAngle=100;
////////////////
window3.LeftX=int(0.5*lWidth);
window3.RightX=lWidth;//int(0.96*lWidth);
window3.BottomY=int(0.01*lHeight);
window3.TopY=int(0.99*lHeight);
window3.MinAngle=15;
window3.MaxAngle=75;
/////////////////
#ifdef DEBUG
//计算函数处理花费时间*********************
LARGE_INTEGER litmp;
LONG QPart1,QPart2;
double dfMinus,dfFreq,dfTim;
QueryPerformanceFrequency(&litmp);
// 获得计数器的时钟频率dfFreq
dfFreq = (double)litmp.QuadPart;
/********************/
QueryPerformanceCounter(&litmp);
QPart1 = litmp.QuadPart;// 获得初始值
/*******************/
/*处理过程*/
//*****************************/
VideoPro.ToGray(lpDIBBits,lHeight,lWidth);
//VideoPro.InteEqualize(lpDIBBits,lHeight,lWidth);
VideoPro.RapidSobel(lpDIBBits,lHeight,lWidth);
VideoPro.Threshold(lpDIBBits,lHeight,lWidth);
//VideoPro.MedianFilter(lpDIBBits,lHeight,lWidth);
// VideoPro.Hough(lpDIBBits,lHeight,lWidth,window2);
VideoPro.Hough(lpDIBBits,lHeight,lWidth,window2);
m_houghR= VideoPro.m_HoughPara;
ps=VideoPro.m_StartPoint;
pe=VideoPro.m_EndPoint;
u=ps.x;
v=ps.y;//坐标变换
Locx=-0.0002*u*u+0.0006*v*v+0.0024*u*v+0.09*u-0.6248*v-6.96;
Locy=0.0002*u*u+0.0077*v*v+0.0004*u*v-0.1308*u-0.784*v+93.32;
/******************************/
QueryPerformanceCounter(&litmp);
QPart2 = litmp.QuadPart;// 获得END值
dfMinus=(double)(QPart2-QPart1);
dfTim=1000*dfMinus/dfFreq;//dfTim单位是毫秒ValueAngleNumber
char buf[80];
sprintf(buf,"rate=%f,rho=%d, theta=%d,value=%d\n,\
StartX=%d,StartY=%d,EndX=%d,EndY=%d\n,LocationX=%f,,LocationY=%f",dfTim,m_houghR.Dist,\
m_houghR.AngleNumber,m_houghR.Value,ps.x,ps.y,pe.x,pe.y,Locx,Locy);
AfxMessageBox(buf);
#else
//计算函数处理花费时间*****
LARGE_INTEGER litmp;
LONG QPart1,QPart2;
double dfMinus,dfFreq,dfTim;
QueryPerformanceFrequency(&litmp);
// 获得计数器的时钟频率dfFreq
dfFreq = (double)litmp.QuadPart;
/********************/
QueryPerformanceCounter(&litmp);
QPart1 = litmp.QuadPart;// 获得初始值
/*******************/
/*处理过程*/
// VideoPro.InteEqualize(lpBufBits,lHeight,lWidth);
VideoPro.ToGray(lpBufBits,lHeight,lWidth);
VideoPro.RapidSobel(lpBufBits,lHeight,lWidth);
VideoPro.Threshold(lpBufBits,lHeight,lWidth);
VideoPro.Hough(lpBufBits,lpDIBBits,lHeight,lWidth,window3);
m_houghR= VideoPro.m_HoughPara;
ps=VideoPro.m_StartPoint;
pe=VideoPro.m_EndPoint;
u=ps.x;
v=ps.y;//坐标变换
Locx=-0.0002*u*u+0.0006*v*v+0.0024*u*v+0.09*u-0.6248*v-6.96;
Locy=0.0002*u*u+0.0077*v*v+0.0004*u*v-0.1308*u-0.784*v+93.32;
QueryPerformanceCounter(&litmp);
QPart2 = litmp.QuadPart;// 获得END值
dfMinus=(double)(QPart2-QPart1);
dfTim=1000*dfMinus/dfFreq;//dfTim单位是毫秒ValueAngleNumber
char buf[80];
sprintf(buf,"rate=%f,rho=%d, theta=%d,value=%d\n,\
StartX=%d,StartY=%d,EndX=%d,EndY=%d\n,LocationX=%f,,LocationY=%f",dfTim,m_houghR.Dist,\
m_houghR.AngleNumber,m_houghR.Value,ps.x,ps.y,pe.x,pe.y,Locx,Locy);
AfxMessageBox(buf);
#endif
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 释放内存
LocalUnlock(hBufBits);
LocalFree(hBufBits);
}
int* CGrayProc::GetIntensity(HDIB hDIB)
{
// 循环变量float *fPs_Y
LONG i;
LONG j;
//分配直方图数据缓存区(数组)
int *pBuffer = new int [256];
//分配直方图数据缓存区失败
if( pBuffer == NULL ) return( NULL );
//直方图数据缓存区清零
memset( pBuffer, 0, 256 * sizeof( int ) );
// 指向DIB的指针
LPBYTE lpDIB;
// 指向DIB象素指针
LPBYTE lpDIBBits;
// 锁定DIB
lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);
// 找到DIB图像象素起始位置
lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
// 判断是否是24-bpp位图
if (m_clsDIB.DIBBitCount(lpDIB) != 24)
{
// 提示用户
// MessageBox("请先将其转换为24位色位图,再进行处理!", "系统提示" , MB_ICONINFORMATION | MB_OK);
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 返回
return FALSE;
}
// 更改光标形状
// BeginWaitCursor();
// DIB的宽度
LONG lWidth = m_clsDIB.DIBWidth(lpDIB);
// DIB的高度
LONG lHeight = m_clsDIB.DIBHeight(lpDIB);
// 计算图像每行的字节数
LONG lLineBytes = lWidth *3;
int leftX,leftY;
int rightX,rightY;
leftX=int(0.3*lWidth);
leftY=int(0.45*lHeight);
rightX=int(0.5*lWidth);
rightY=int(0.8*lHeight);
RGB rgb;
// HSI hsi;
// 对各像素进行灰度转换
for (i = 0; i <lHeight; i ++)
{
for (j = 0; j <lWidth; j ++)
{
// 获取各颜色分量
unsigned char B= *((unsigned char *)lpDIBBits + 3*lWidth * i + 3*j);
unsigned char G= *((unsigned char *)lpDIBBits + 3*lWidth * i + 3*j+1);
unsigned char R= *((unsigned char *)lpDIBBits + 3*lWidth * i + 3*j+2);
rgb.b=B;
rgb.g=G;
rgb.r=R;
// RgbToHsi(&rgb,&hsi);
// 计算灰度值
unsigned char Y = (9798 * R + 19235 * G + 3735 * B) / 32768;
//unsigned char Y = ( R + G + B) / 3;//I1空间( R + G + B) / 3
// unsigned char Y = (B-R) +128;//I2空间(B-R) +128
// unsigned char Y = (G-R) +128;//I3空间(G-R) +128
//unsigned char Y = (255*hsi.Hue/360);
// unsigned char Y = (255*hsi.Saturation);
if (Y>255)Y=255;
// 灰度统计计数
pBuffer[Y]++;
}
}
/* for (i = leftY; i < rightY; i ++)
{
for (j = leftX; j <rightX; j ++)
{
// 获取各颜色分量
*((unsigned char *)lpDIBBits + 3*lWidth * i + 3*j)=0;
*((unsigned char *)lpDIBBits + 3*lWidth * i + 3*j+1)=255;
*((unsigned char *)lpDIBBits + 3*lWidth * i + 3*j+2)=255;
}
}
*/
//平滑灰度图曲线
// TableSmooth(pBuffer,256,10);
// 计算灰度分布密度
// for(i=0;i<256;i++)
// fPs_Y[i] = nNs_Y[i] / (lHeight * lWidth * 1.0f);
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 恢复光标
// EndWaitCursor();
return(pBuffer);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -