www.pudn.com > Imagepro_4.rar > Dib.cpp
// Dib.cpp: implementation of the CDib class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Imagepro.h"
#include "Dib.h"
#include "math.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define THRESHOLD (RADIUS*2+1)*(RADIUS*2+1)*15
#define THRESHOLDCONTRAST 40
#define MAX(a,b) ((a)>(b))?(a):(b)
#define MIN(a,b) ((a)<(b))?(a):(b)
#define BOUND(c,i,j) (MAX((i),MIN((c),(j))))
#define srcPoint(x,y) srcimg[(x)+(y)*m_dwLine]
#define destPoint(x,y) destimg[(x)+(y)*m_dwLine]
#define ABS(x) (((x) < 0) ? -(x) : (((x) > 0) ? (x) : 0))
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDib::CDib()
{
m_pDib = NULL;
m_pDibBits=NULL;
m_pTempBits=NULL;
B_m_pTenpBits = NULL;
m_pSourceBits = NULL;
bLoadHistab = false ;
m_pBIH=NULL;
scale=1.0;
}
CDib::~CDib()
{
if( m_pDib != NULL )
delete [] m_pDib;
if( m_pTempBits != NULL )
delete [] m_pTempBits;
if( B_m_pTenpBits != NULL )
delete [] B_m_pTenpBits;
if(m_pSourceBits !=NULL)
delete []m_pSourceBits;
}
BOOL CDib::Load( const char *pszFilename )
{
AfxGetApp()->BeginWaitCursor();
CFile cf;
CString m_strfilename,m_strfiletitle;//文件全名,文件名
if( !cf.Open( pszFilename, CFile::modeRead ) )
{
AfxMessageBox("不能打开文件,请重试");
return( FALSE );
}
m_strfiletitle=cf.GetFileName();
m_strfilename=m_strfiletitle.Right(3);
cf.Close();
m_strfilename.MakeLower();
if(m_strfilename=="bmp")
{
if(!LoadBMPFile(pszFilename))
return FALSE;
}
scale=1.0;
AfxGetApp()->EndWaitCursor();
return( TRUE );
}
//载入BMP文件
BOOL CDib::LoadBMPFile(const char *BmpFilename)
{
// Attempt to open the Dib file for reading.
CFile cf;
if( !cf.Open(BmpFilename, CFile::modeRead ) )
return( FALSE );
m_strFileName=BmpFilename;
// Get the size of the file and store
// in a local variable. Subtract the
// size of the BITMAPFILEHEADER structure
// since we won't keep that in memory.
DWORD dwDibSize;
dwDibSize =
cf.GetLength() - sizeof( BITMAPFILEHEADER );
// Attempt to allocate the Dib memory.
unsigned char *pDib;
pDib = new unsigned char [dwDibSize];
if( pDib == NULL )
{
AfxMessageBox("内存不足!");
return( FALSE );
}
// Read in the Dib header and data.
try
{
// Did we read in the entire BITMAPFILEHEADER?
if( cf.Read(&m_pBFH, sizeof( BITMAPFILEHEADER ) )
!= sizeof( BITMAPFILEHEADER ) ||
// Is the type 'MB'?
m_pBFH.bfType != 'MB' ||
// Did we read in the remaining data?
cf.Read( pDib, dwDibSize ) != dwDibSize )
{
// Delete the memory if we had any
// errors and return FALSE.
delete [] pDib;
return( FALSE );
}
}
// If we catch an exception, delete the
// exception, the temporary Dib memory,
// and return FALSE.
catch( CFileException *e )
{
e->Delete();
delete [] pDib;
return( FALSE );
}
// If we got to this point, the Dib has been
// loaded. If a Dib was already loaded into
// this class, we must now delete it.
if( m_pDib != NULL )
delete m_pDib;
// Store the local Dib data pointer and
// Dib size variables in the class member
// variables.
m_pDib = pDib;
// m_dwDibSize = dwDibSize;
// Pointer our BITMAPINFOHEADER and RGBQUAD
// variables to the correct place in the Dib data.
m_pBIH = (BITMAPINFOHEADER *) pDib;
m_pPalette =
(RGBQUAD *) &pDib[sizeof(BITMAPINFOHEADER)];
//Get image's width and height and BitCount
m_dwWidth=m_pBIH->biWidth;
m_dwHeight=m_pBIH->biHeight;
m_iBitCount=m_pBIH->biBitCount;
if(m_iBitCount==2)
bIsBinary=true;
else
bIsBinary=false;
//扫描行补位
m_dwLine=m_dwWidth*m_iBitCount/8;
if(m_dwLine%4) //扫描行不被四整除
more=(m_dwLine/4+1)*4-m_dwLine;
else
more=0;
m_dwLine+=more; //此时该参数为每扫描行实际存储数据大小
// Calculate the number of palette entries.
m_nPaletteEntries = 1 << m_pBIH->biBitCount;
if( m_pBIH->biBitCount > 8 )
m_nPaletteEntries = 0;
else if( m_pBIH->biClrUsed != 0 )
m_nPaletteEntries = m_pBIH->biClrUsed;
//图象实际数据大小
m_dwDataSize=dwDibSize-sizeof(BITMAPINFOHEADER)-m_nPaletteEntries*sizeof(RGBQUAD);
// Point m_pDibBits to the actual Dib bits data.
m_pDibBits =
&pDib[sizeof(BITMAPINFOHEADER)+
m_nPaletteEntries*sizeof(RGBQUAD)];
if( B_m_pTenpBits != NULL )
{
delete [] B_m_pTenpBits;
B_m_pTenpBits = NULL;
}
B_m_pTenpBits = new BYTE[m_dwDataSize];
memset((LPBYTE)B_m_pTenpBits,0,m_dwDataSize);
memcpy(B_m_pTenpBits,m_pDibBits,m_dwDataSize);
// B_m_pBitsBackup = new BYTE[m_dwDataSize];
// memset((LPBYTE)B_m_pBitsBackup,0,m_dwDataSize);
// memcpy(B_m_pBitsBackup,m_pDibBits,m_dwDataSize);
// If we have a valid palette, delete it.
if( m_Palette.GetSafeHandle() != NULL )
m_Palette.DeleteObject();
// If there are palette entries, we'll need
// to create a LOGPALETTE then create the
// CPalette palette.
if( m_nPaletteEntries != 0 )
{
// Allocate the LOGPALETTE structure.
LOGPALETTE *pLogPal = (LOGPALETTE *) new char
[sizeof(LOGPALETTE)+
m_nPaletteEntries*sizeof(PALETTEENTRY)];
if( pLogPal != NULL )
{
// Set the LOGPALETTE to version 0x300
// and store the number of palette
// entries.
pLogPal->palVersion = 0x300;
pLogPal->palNumEntries = m_nPaletteEntries;
// Store the RGB values into each
// PALETTEENTRY element.
for( int i=0; ipalPalEntry[i].peRed =
m_pPalette[i].rgbRed;
pLogPal->palPalEntry[i].peGreen =
m_pPalette[i].rgbGreen;
pLogPal->palPalEntry[i].peBlue =
m_pPalette[i].rgbBlue;
}
// Create the CPalette object and
// delete the LOGPALETTE memory.
m_Palette.CreatePalette( pLogPal );
delete [] pLogPal;
}
}
return TRUE;
}
BOOL CDib::ShowImage(CDC* pDC,BOOL UnLoaded,CString pathname)
{
if(UnLoaded){
if(pathname=="")
return FALSE;
if(!Load(pathname))
return FALSE;
}
Draw(pDC);
return TRUE;
}
BOOL CDib::Draw( CDC *pDC, int nX, int nY, int nWidth, int nHeight)
{
// If we have not data we can't draw.
if( m_pDibBits == NULL )
return( FALSE );
// Check for the default values of -1
// in the width and height arguments. If
// we find -1 in either, we'll set them
// to the value that's in the BITMAPINFOHEADER.
if( nWidth == -1 )
nWidth = m_pBIH->biWidth;
if( nHeight == -1 )
nHeight = m_pBIH->biHeight;
// Use StretchDIBits to draw the Dib.
StretchDIBits( pDC->m_hDC, nX, nY,
(int)(scale*nWidth),(int)(scale*nHeight),
0, 0,
m_pBIH->biWidth, m_pBIH->biHeight,
m_pDibBits,
(BITMAPINFO *) m_pBIH,
DIB_RGB_COLORS,SRCCOPY);
return( TRUE );
}
BOOL CDib::SetPalette( CDC *pDC )
{
// If we have not data we
// won't want to set the palette.
if( m_pDib == NULL )
return( FALSE );
// Check to see if we have a palette
// handle. For Dibs greater than 8 bits,
// this will be NULL.
if( m_Palette.GetSafeHandle() == NULL )
return( TRUE );
// Select the palette, realize the palette,
// then finally restore the old palette.
CPalette *pOldPalette;
pOldPalette = pDC->SelectPalette( &m_Palette, FALSE );
pDC->RealizePalette();
pDC->SelectPalette( pOldPalette, FALSE );
return( TRUE );
}
BOOL CDib::CopyRect(LPCRECT lpRectSource, LPCRECT lpRectGoal,long srcLine,long destLine,
unsigned char* srcimg,unsigned char* destimg,BOOL bCut)
{
//此函数主要应用于图象特技显示
//功能为将要显示的图象的一部分拷贝到黑色背景中
//参数分别为原图象的区域坐标,目标图像的区域坐标,原图象扫描行大小,目的扫描行大小,
//原图象指针,目标图象指针
unsigned char *lab1,*lab2;
int S_Left,S_Top,S_Right,S_Bottom,S_Height,S_Width;
int G_Left,G_Top,G_Right,G_Bottom,G_Height,G_Width;
long i;
S_Left=lpRectSource->left;
S_Top=lpRectSource->top;
S_Right=lpRectSource->right;
S_Bottom=lpRectSource->bottom;
G_Left=lpRectGoal->left;
G_Top=lpRectGoal->top;
G_Right=lpRectGoal->right;
G_Bottom=lpRectGoal->bottom;
S_Left=BOUND(S_Left,0,m_dwWidth-1);
S_Right=BOUND(S_Right,0,m_dwWidth-1);
G_Left=BOUND(G_Left,0,m_dwWidth-1);
G_Right=BOUND(G_Right,0,m_dwWidth-1);
S_Top=BOUND(S_Top,0,m_dwHeight-1);
S_Bottom=BOUND(S_Bottom,0,m_dwHeight-1);
G_Top=BOUND(G_Top,0,m_dwHeight-1);
G_Bottom=BOUND(G_Bottom,0,m_dwHeight-1);
S_Height=(int)fabs(S_Bottom-S_Top)+1;
S_Width=(int)fabs(S_Right-S_Left)+1;
G_Height=(int)fabs(G_Bottom-G_Top)+1;
G_Width=(int)fabs(G_Right-G_Left)+1;
if(G_Height!=S_Height||G_Width!=S_Width)
{
AfxMessageBox("Image Block Copy Error",NULL,MB_OK);
return FALSE;
}
if((srcLine==0)&&(destLine==0))
srcLine=destLine=m_dwLine;
if(srcimg==NULL)
srcimg=m_pTempBits;
if(destimg==NULL)
destimg=m_pDibBits;
int copywidth=(int)(G_Width*m_iBitCount/8.0+0.5);
int destbegin=(int)(G_Left*m_iBitCount/8.0+0.5);
int srcbegin=(int)(S_Left*m_iBitCount/8.0+0.5);
for(i=0;i255) d=255;
destPoint(x,y)=(BYTE)d;
}
}
}
//sobel算子边缘检测
void CDib::Sobel_Edge(unsigned char *srcimg, long nWidth, long nHeight, unsigned char *destimg)
{
int x,y,x1,y1,i;
int d,max;
static s[8][9]={
{-1,-2,-1,0,0,0,1,2,1},
{0,-1,-2,1,0,-1,2,1,0},
{1,0,-1,2,0,-2,1,0,-1},
{2,1,0,1,0,-1,0,-1,-2},
{1,2,1,0,0,0,-1,-2,-1},
{0,1,2,-1,0,1,-2,-1,0},
{-1,0,1,-2,0,2,-1,0,1},
{-2,-1,0,-1,0,1,0,1,2}
};
for(y=1;ymax) max=d;
}
if (max>255) max=255;
destPoint(x,y)=(BYTE)max;
//destimg[x+y*m_dwLine]=(BYTE)max;
}
}
}
//拉普拉斯算子边缘检测
void CDib::Laplacian_filter8(unsigned char *srcimg, long dx, long dy, unsigned char *destimg)
{
MASK* msk_lap;
msk_lap=new MASK;
msk_lap->rows=3;
msk_lap->cols=3;
msk_lap->kern[0][0]=-1;
msk_lap->kern[0][1]=-1;
msk_lap->kern[0][2]=-1;
msk_lap->kern[1][0]=-1;
msk_lap->kern[1][1]=8;
msk_lap->kern[1][2]=-1;
msk_lap->kern[2][0]=-1;
msk_lap->kern[2][1]=-1;
msk_lap->kern[2][2]=-1;
img_convolve(srcimg,dx,dy,msk_lap,destimg);
}
//模板匹配
void CDib::img_convolve(unsigned char* srcimg,long dx,long dy,MASK* msk,unsigned char* destimg,BOOL bEmboss)
{
int x,y,mx,my,s,t;
float tempdata;
memset(destimg,BACKGROUND,m_dwDataSize); //初始化目标图象
mx=msk->rows/2;
my=msk->cols/2;
for(y=my;ybiBitCount/8;
/* for(int m=0;mkern[t+my][s+mx]*srcimg[(y+t)*m_dwLine+(x+s)];//*bits+m];
if(tempdata<0)
tempdata = -tempdata ;
tempdata=BOUND(tempdata,0,255);
destimg[y*m_dwLine+x*bits]=(int)(tempdata+0.5); //+m
//}
}
}
BOOL CDib::GetHistab(long imgwidth, long imgheight, int iBitcount, unsigned char *img)
{
//得到图像的直方图
int j,k,m,n,temp,overheight;
long i;
for(i=0;i<4;i++)
for(j=0;j<256;j++)
histab[i][j]=0;
i=0;
if(img==NULL)
img=m_pDibBits;
for(n=0;n>1;
}
else
break;
}
i++;
break;
case 4: //??????????????????????????????????
m++;
overheight++;
for(k=0;k<4;k++)
histab[k][(img[i]&240)>>3]++; //&11110000
overheight++;
if(overheight0;j--)
{ //BMP图象存储为BGR
histab[j][img[i]]++;
temp+=img[i++];
}
temp/=3;
histab[0][temp]++;
break;
}
}
i+=more;
}
for(i=0;i<256;i++)
probability[i]=(float)(histab[0][i]/(m_dwWidth*m_dwHeight*1.0));
bLoadHistab=true;
return TRUE;
}
//Nikhil R. Pal提出的全局熵的阈值选取方法
int CDib::global_entropy_shresh_sel(float *prob)
{
int i,j,s,gmax,gmin;
float Hb,Hw,Ht,tmp1,tmp2,Ps;
gmax=255;
while(prob[gmax]==0)
gmax--;
gmin=0;
while(prob[gmin]==0)
gmin++;
Ps=prob[gmin];
Ht=1;
tmp2=1-Ps;
for(j=(gmin+1);j<=gmax;j++)
{
tmp1=prob[j]/tmp2;
Ht+=(float)(tmp1*exp((double)(1-tmp1)));
}
for(i=(gmin+1);i0)
{
tmp1=prob[i]/tmp2;
Hw+=(float)(tmp1*exp((double)(1-tmp1)));
}
j++;
}
if((Hb+Hw)>Ht)
{
Ht=Hb+Hw;
s=i;
}
}
return s;
}
//C. H. Li提出的最小交叉熵的阈值选取方法
int CDib::min_cross_entropy_shresh_sel(float *prob)
{
int i,j,t,gmax,gmin;
float u1,u2,seta,min,tmp;
gmax=255;
while(prob[gmax]==0)
gmax--;
gmin=0;
while(prob[gmin]==0)
gmin++;
u2=0;
for(i=gmin;i<=gmax;i++)
u2+=i*prob[i];
min=0;
if(gmin==0)
t=1;
else
t=gmin;
for(i=t;i<=gmax;i++)
min+=(float)((i*prob[i])*log(i/u2));
u1=gmin*prob[gmin];
t=gmin;
tmp=prob[gmin];
for(i=(gmin+1);iseta)
{
min=seta;
t=i;
}
u1+=i*prob[i];
tmp+=prob[i];
}
return t;
}
//L. Y. Li提出的梯度均值的阈值选取方法
int CDib::gradient_mean_shresh_sel(float *prob)
{
int i;
float temp;
temp=0;
for(i=0;i<256;i++)
{
temp+=i*prob[i];
}
return((int)(temp+0.5));
}
//W. H. Tsai提出的矩保持的阈值选取方法
int CDib::moment_preserve_shresh_sel(float *prob)
{
int i,j;
float p0,p1,pd,z1,cd,c0,c1,m0,m1,m2,m3,ist,min,t[256];
m0=1;
m1=m2=m3=0;
for(i=0;i<256;i++)
{
t[i]=0;
ist=prob[i]*i;
m1+=ist;
ist*=i;
m2+=ist;
ist*=i;
m3+=ist;
}
cd=m0*m2-m1*m1;
if(cd==0)
return 128;
c0=(m1*m3-m2*m2)/cd;
c1=(m1*m2-m0*m3)/cd;
pd=c1*c1-4*c0;
if(pd<0)
return 128;
pd=(float)sqrt(pd);
z1=(float)(0.5*(pd-c1));
if(pd==0)
return 128;
p0=(z1-m1)/pd;
p1=1-p0;
t[0]=prob[0];
for(i=1;i<256;i++)
t[i]=t[i-1]+prob[i];
j=0;
min=(float)fabs(p0-t[0]);
for(i=1;i<256;i++)
{
if(fabs(p0-t[i])=max)
{
max=cta;
k=i;
}
}
n1=prob[k]/(k-k0);
n2=prob[k0]/(k-k0);
for(i=k0+1;id)
{
d=m;
j=i;
}
}
}
return j;
}
//S. S. Reddi提出的基于矩的阈值选取
int CDib::moment_shresh_sel2(float *prob)
{
int i,meand,meanb,maxp,minp;
float temp1,total1,temp2,total2;
minp=0;
while(prob[minp]==0)
minp++;
maxp=255;
while(prob[maxp]==0)
maxp--;
temp1=temp2=total1=total2=0;
for(i=minp;i<=maxp;i++)
total2+=i*prob[i];
i=minp-1;
do
{
i++;
temp1+=prob[i];
total1+=i*prob[i];
temp2=1-temp1;
if(temp2<=0)
{
i=128;
break;
}
meand=(int)(total1/temp1);
meanb=(int)((total2-total1)/temp2);
}while((fabs(meanb+meand-2*i)>=1)&&(i=0;i--){
if(prob[i]!=0)
{
maxg=i;
break;
}
}
for(i=ming;i<=maxg;i++)
ut+=i*prob[i];
t1[ming]=prob[ming];
t2[ming]=ming*prob[ming];
for(i=(ming+1);i<=maxg;i++)
{
t1[i]=t1[i-1]+prob[i];
t2[i]=t2[i-1]+i*prob[i];
}
for(i=ming;i<=maxg;i++)
{
if(t1[i]!=0)
{
ming=i;
break;
}
}
for(i=maxg;i>=ming;i--)
{
if(t1[i]<1)
{
maxg=i;
break;
}
}
s=(-999999);
for(i=ming;i<=maxg;i++)
{
if((t1[i]!=0)&&(t1[i]!=1))
{
buf=ut*t1[i]-t2[i];
buf=(buf*buf)/(t1[i]*(1-t1[i]));
}
else
buf=(-999999);
if(sMINNUM)
if(fabs(p[i]/p1)>MINNUM)
h1+=-1*(p[i]/p1)*(float)(log(p[i]/p1));
for(i=0;i<=t;i++)
if(fabs(p[i])>MINNUM)
h+=-1*p[i]*(float)(log(p[i]));
if(p1>MINNUM&&p2>MINNUM)
tempfei=(float)(log(p1*p2))+h/p1+(h1-h)/p2;
else
tempfei=-65535.0;
if(tempfei>fei) {
fei=tempfei;
T=t;
}
}
return T;
}
//G. Johannson提出的基于熵的阈值选取
int CDib::entropy_thresh_sel1(float* prob)
{
int i,j,ming,maxg,buf;
float t1[256],t2[256],t3[256],t4[256];
double s,pp;
memset(t1,0,256*sizeof(float));
memset(t2,0,256*sizeof(float));
memset(t3,0,256*sizeof(float));
memset(t4,0,256*sizeof(float));
for(i=0;i<256;i++)
{
if(prob[i]!=0)
{
ming=i;
break;
}
}
for(i=255;i>=0;i--){
if(prob[i]!=0)
{
maxg=i;
break;
}
}
t3[ming]=prob[ming];
for(i=(ming+1);i<=maxg;i++)
t3[i]=t3[i-1]+prob[i];
for(i=ming;i<=maxg;i++)
{
t4[i]=1-t3[i];
buf=i;
if(t4[i]<=0)
break;
}
maxg=buf-1;
for(i=ming;ipp){
s=pp;
j=i;
}
}
return j;
}
//J.N.Kapur提出的基于熵的阈值选取
int CDib::entropy_thresh_sel2(float* prob)
{
int i,j,ming,maxg;
float s,buf,bbb,t1[256],t2[256];
memset(t1,0,256*sizeof(float));
memset(t2,0,256*sizeof(float));
for(i=0;i<256;i++)
{
if(prob[i]!=0)
{
ming=i;
break;
}
}
for(i=255;i>=0;i--)
{
if(prob[i]!=0)
{
maxg=i;
break;
}
}
t1[ming]=prob[ming];
for(i=(ming+1);i<=maxg;i++)
t1[i]=t1[i-1]+prob[i];
for(i=ming;i<=maxg;i++)
for(j=ming;j<=i;j++)
if(prob[j]!=0)
t2[i]=t2[i]-prob[j]*(float)(log(prob[j]));
for(i=ming;i<=maxg;i++)
{
j=i;
if((1-t1[i])<=0)
break;
}
maxg=j-1;
s=-1*MAXNUM;
j=128;
for(i=ming;i<=maxg;i++)
{
bbb=t1[i]*(1-t1[i]);
if(bbb>0)
buf=(float)(log(bbb))+t2[i]/t1[i]+(t2[maxg]-t2[i])/(1-t1[i]);
else
buf=-1*MAXNUM;
if(srows=3;
msk_lap->cols=3;
msk_lap->kern[0][0]=0;
msk_lap->kern[0][1]=-1;
msk_lap->kern[0][2]=0;
msk_lap->kern[1][0]=-1;
msk_lap->kern[1][1]=4;
msk_lap->kern[1][2]=-1;
msk_lap->kern[2][0]=0;
msk_lap->kern[2][1]=-1;
msk_lap->kern[2][2]=0;
img_convolve(srcimg,dx,dy,msk_lap,destimg);
}
void CDib::Prewitt1(unsigned char *srcimg, long dx, long dy, unsigned char *destimg)
{
MASK* msk_lap;
msk_lap=new MASK;
unsigned char *temp1;
unsigned char *temp2;
temp1 = new unsigned char[m_dwDataSize];
temp2 = new unsigned char[m_dwDataSize];
msk_lap->rows=3;
msk_lap->cols=3;
msk_lap->kern[0][0]=1;
msk_lap->kern[0][1]=1;
msk_lap->kern[0][2]=1;
msk_lap->kern[1][0]=0;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=0;
msk_lap->kern[2][0]=-1;
msk_lap->kern[2][1]=-1;
msk_lap->kern[2][2]=-1;
img_convolve(srcimg,dx,dy,msk_lap, temp1);
msk_lap->kern[0][0]=-1;
msk_lap->kern[0][1]=0;
msk_lap->kern[0][2]=1;
msk_lap->kern[1][0]=-1;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=1;
msk_lap->kern[2][0]=-1;
msk_lap->kern[2][1]=0;
msk_lap->kern[2][2]=1;
img_convolve(srcimg,dx,dy,msk_lap,temp2);
for(int i =0 ;i< m_dwHeight;i++)
for(int j = 0 ; jtemp2[i*m_dwLine+j] )
destimg[i*m_dwLine+j] = temp1[i*m_dwLine+j];
else
destimg[i*m_dwLine+j] = temp2[i*m_dwLine+j];
}
delete[]temp1;
delete[]temp2;
}
//void CDib:: Prewitt2(unsigned char *srcimg, long dx, long dy, unsigned char *destimg)
void CDib::Prewitt8(unsigned char *srcimg, long dx, long dy, unsigned char *destimg)
{
MASK* msk_lap;
msk_lap=new MASK;
unsigned char *temp1;
unsigned char *temp2;
unsigned char *temp3;
unsigned char *temp4;
unsigned char *temp5;
unsigned char *temp6;
unsigned char *temp7;
unsigned char *temp8;
int i=0,j=0;
temp1 = new unsigned char[m_dwDataSize];
temp2 = new unsigned char[m_dwDataSize];
temp3 = new unsigned char[m_dwDataSize];
temp4 = new unsigned char[m_dwDataSize];
temp5 = new unsigned char[m_dwDataSize];
temp6 = new unsigned char[m_dwDataSize];
temp7 = new unsigned char[m_dwDataSize];
temp8 = new unsigned char[m_dwDataSize];
msk_lap->rows=3;
msk_lap->cols=3;
msk_lap->kern[0][0]=1;
msk_lap->kern[0][1]=0;
msk_lap->kern[0][2]=-1;
msk_lap->kern[1][0]=1;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=-1;
msk_lap->kern[2][0]=1;
msk_lap->kern[2][1]=0;
msk_lap->kern[2][2]=-1;
img_convolve(srcimg,dx,dy,msk_lap, temp1);
msk_lap->kern[0][0]=-1;
msk_lap->kern[0][1]=-1;
msk_lap->kern[0][2]=-1;
msk_lap->kern[1][0]=0;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=0;
msk_lap->kern[2][0]=1;
msk_lap->kern[2][1]=1;
msk_lap->kern[2][2]=1;
img_convolve(srcimg,dx,dy,msk_lap, temp2);
for(i =0 ;i< m_dwHeight;i++)
for( j = 0 ; jtemp2[i*m_dwLine+j] )
destimg[i*m_dwLine+j] = temp1[i*m_dwLine+j];
else
destimg[i*m_dwLine+j] = temp2[i*m_dwLine+j];
}
delete[]temp1;
delete[]temp2;
msk_lap->kern[0][0]=-1;
msk_lap->kern[0][1]=-1;
msk_lap->kern[0][2]=-0;
msk_lap->kern[1][0]=-1;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=1;
msk_lap->kern[2][0]=0;
msk_lap->kern[2][1]=1;
msk_lap->kern[2][2]=1;
img_convolve(srcimg,dx,dy,msk_lap, temp3);
for( i =0 ;i< m_dwHeight;i++)
for(j = 0 ; jdestimg[i*m_dwLine+j] )
destimg[i*m_dwLine+j] = temp3[i*m_dwLine+j];
}
delete[]temp3;
msk_lap->kern[0][0]=-1;
msk_lap->kern[0][1]=0;
msk_lap->kern[0][2]=1;
msk_lap->kern[1][0]=-1;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=1;
msk_lap->kern[2][0]=-1;
msk_lap->kern[2][1]=0;
msk_lap->kern[2][2]=1;
img_convolve(srcimg,dx,dy,msk_lap, temp4);
for(i =0 ;i< m_dwHeight;i++)
for( j = 0 ; jdestimg[i*m_dwLine+j] )
destimg[i*m_dwLine+j] = temp4[i*m_dwLine+j];
}
delete[]temp4;
msk_lap->kern[0][0]=0;
msk_lap->kern[0][1]=1;
msk_lap->kern[0][2]=1;
msk_lap->kern[1][0]=-1;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=1;
msk_lap->kern[2][0]=-1;
msk_lap->kern[2][1]=-1;
msk_lap->kern[2][2]=0;
img_convolve(srcimg,dx,dy,msk_lap, temp5);
for( i =0 ;i< m_dwHeight;i++)
for( j = 0 ; jdestimg[i*m_dwLine+j] )
destimg[i*m_dwLine+j] = temp5[i*m_dwLine+j];
}
delete[]temp5;
msk_lap->kern[0][0]=1;
msk_lap->kern[0][1]=1;
msk_lap->kern[0][2]=1;
msk_lap->kern[1][0]=0;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=0;
msk_lap->kern[2][0]=-1;
msk_lap->kern[2][1]=-1;
msk_lap->kern[2][2]=-1;
img_convolve(srcimg,dx,dy,msk_lap, temp6);
for( i =0 ;i< m_dwHeight;i++)
for( j = 0 ; jdestimg[i*m_dwLine+j] )
destimg[i*m_dwLine+j] = temp6[i*m_dwLine+j];
}
delete[]temp6;
msk_lap->kern[0][0]=1;
msk_lap->kern[0][1]=1;
msk_lap->kern[0][2]=0;
msk_lap->kern[1][0]=1;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=-1;
msk_lap->kern[2][0]=0;
msk_lap->kern[2][1]=-1;
msk_lap->kern[2][2]=-1;
img_convolve(srcimg,dx,dy,msk_lap, temp7);
for( i =0 ;i< m_dwHeight;i++)
for( j = 0 ; jdestimg[i*m_dwLine+j] )
destimg[i*m_dwLine+j] = temp7[i*m_dwLine+j];
}
delete[]temp7;
msk_lap->kern[0][0]=0;
msk_lap->kern[0][1]=-1;
msk_lap->kern[0][2]=-1;
msk_lap->kern[1][0]=1;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=-1;
msk_lap->kern[2][0]=1;
msk_lap->kern[2][1]=1;
msk_lap->kern[2][2]=0;
img_convolve(srcimg,dx,dy,msk_lap, temp8);
for( i =0 ;i< m_dwHeight;i++)
for( j = 0 ; jdestimg[i*m_dwLine+j] )
destimg[i*m_dwLine+j] = temp8[i*m_dwLine+j];
}
delete[]temp8;
}
void CDib::Krisch(unsigned char *srcimg, long dx, long dy, unsigned char *destimg)
{
MASK* msk_lap;
msk_lap=new MASK;
unsigned char *temp1;
unsigned char *temp2;
unsigned char *temp3;
unsigned char *temp4;
unsigned char *temp5;
unsigned char *temp6;
unsigned char *temp7;
unsigned char *temp8;
int i=0,j=0;
temp1 = new unsigned char[m_dwDataSize];
temp2 = new unsigned char[m_dwDataSize];
temp3 = new unsigned char[m_dwDataSize];
temp4 = new unsigned char[m_dwDataSize];
temp5 = new unsigned char[m_dwDataSize];
temp6 = new unsigned char[m_dwDataSize];
temp7 = new unsigned char[m_dwDataSize];
temp8 = new unsigned char[m_dwDataSize];
msk_lap->rows=3;
msk_lap->cols=3;
msk_lap->kern[0][0]=5;
msk_lap->kern[0][1]=5;
msk_lap->kern[0][2]=5;
msk_lap->kern[1][0]=-3;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=-3;
msk_lap->kern[2][0]=-3;
msk_lap->kern[2][1]=-3;
msk_lap->kern[2][2]=-3;
img_convolve(srcimg,dx,dy,msk_lap, temp1);
msk_lap->kern[0][0]=-3;
msk_lap->kern[0][1]=5;
msk_lap->kern[0][2]=5;
msk_lap->kern[1][0]=-3;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=5;
msk_lap->kern[2][0]=-3;
msk_lap->kern[2][1]=-3;
msk_lap->kern[2][2]=-3;
img_convolve(srcimg,dx,dy,msk_lap, temp2);
for(i =0 ;i< m_dwHeight;i++)
for( j = 0 ; jtemp2[i*m_dwLine+j] )
destimg[i*m_dwLine+j] = temp1[i*m_dwLine+j];
else
destimg[i*m_dwLine+j] = temp2[i*m_dwLine+j];
}
delete[]temp1;
delete[]temp2;
msk_lap->kern[0][0]=-3;
msk_lap->kern[0][1]=-3;
msk_lap->kern[0][2]=5;
msk_lap->kern[1][0]=-3;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=5 ;
msk_lap->kern[2][0]=-3;
msk_lap->kern[2][1]=-3;
msk_lap->kern[2][2]=5;
img_convolve(srcimg,dx,dy,msk_lap, temp3);
for( i =0 ;i< m_dwHeight;i++)
for(j = 0 ; jdestimg[i*m_dwLine+j] )
destimg[i*m_dwLine+j] = temp3[i*m_dwLine+j];
}
delete[]temp3;
msk_lap->kern[0][0]=-3;
msk_lap->kern[0][1]=-3;
msk_lap->kern[0][2]=-3;
msk_lap->kern[1][0]=-3;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=5;
msk_lap->kern[2][0]=-3;
msk_lap->kern[2][1]=5;
msk_lap->kern[2][2]=5;
img_convolve(srcimg,dx,dy,msk_lap, temp4);
for(i =0 ;i< m_dwHeight;i++)
for( j = 0 ; jdestimg[i*m_dwLine+j] )
destimg[i*m_dwLine+j] = temp4[i*m_dwLine+j];
}
delete[]temp4;
msk_lap->kern[0][0]=-3;
msk_lap->kern[0][1]=-3;
msk_lap->kern[0][2]=-3;
msk_lap->kern[1][0]=-3;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=-3;
msk_lap->kern[2][0]=5;
msk_lap->kern[2][1]=5;
msk_lap->kern[2][2]=5;
img_convolve(srcimg,dx,dy,msk_lap, temp5);
for( i =0 ;i< m_dwHeight;i++)
for( j = 0 ; jdestimg[i*m_dwLine+j] )
destimg[i*m_dwLine+j] = temp5[i*m_dwLine+j];
}
delete[]temp5;
msk_lap->kern[0][0]=-3;
msk_lap->kern[0][1]=-3;
msk_lap->kern[0][2]=-3;
msk_lap->kern[1][0]=5;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=-3;
msk_lap->kern[2][0]=5;
msk_lap->kern[2][1]=5;
msk_lap->kern[2][2]=-3;
img_convolve(srcimg,dx,dy,msk_lap, temp6);
for( i =0 ;i< m_dwHeight;i++)
for( j = 0 ; jdestimg[i*m_dwLine+j] )
destimg[i*m_dwLine+j] = temp6[i*m_dwLine+j];
}
delete[]temp6;
msk_lap->kern[0][0]=5;
msk_lap->kern[0][1]=-3;
msk_lap->kern[0][2]=-3;
msk_lap->kern[1][0]=5;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=-3;
msk_lap->kern[2][0]=5;
msk_lap->kern[2][1]=-3;
msk_lap->kern[2][2]=-3;
img_convolve(srcimg,dx,dy,msk_lap, temp7);
for( i =0 ;i< m_dwHeight;i++)
for( j = 0 ; jdestimg[i*m_dwLine+j] )
destimg[i*m_dwLine+j] = temp7[i*m_dwLine+j];
}
delete[]temp7;
msk_lap->kern[0][0]=5;
msk_lap->kern[0][1]=5;
msk_lap->kern[0][2]=-3;
msk_lap->kern[1][0]=5;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=-3;
msk_lap->kern[2][0]=-3;
msk_lap->kern[2][1]=-3;
msk_lap->kern[2][2]=-3;
img_convolve(srcimg,dx,dy,msk_lap, temp8);
for( i =0 ;i< m_dwHeight;i++)
for( j = 0 ; jdestimg[i*m_dwLine+j] )
destimg[i*m_dwLine+j] = temp8[i*m_dwLine+j];
}
delete[]temp8;
}
void CDib::Krisch2(unsigned char *srcimg, long dx, long dy, unsigned char *destimg)
{
MASK* msk_lap;
msk_lap=new MASK;
unsigned char *temp1;
unsigned char *temp2;
unsigned char *temp3;
unsigned char *temp4;
unsigned char *temp5;
unsigned char *temp6;
unsigned char *temp7;
unsigned char *temp8;
int i=0,j=0;
temp1 = new unsigned char[m_dwDataSize];
temp2 = new unsigned char[m_dwDataSize];
temp3 = new unsigned char[m_dwDataSize];
temp4 = new unsigned char[m_dwDataSize];
temp5 = new unsigned char[m_dwDataSize];
temp6 = new unsigned char[m_dwDataSize];
temp7 = new unsigned char[m_dwDataSize];
temp8 = new unsigned char[m_dwDataSize];
msk_lap->rows=3;
msk_lap->cols=3;
msk_lap->kern[0][0]=-5;
msk_lap->kern[0][1]=-5;
msk_lap->kern[0][2]=-5;
msk_lap->kern[1][0]=3;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=3;
msk_lap->kern[2][0]=3;
msk_lap->kern[2][1]=3;
msk_lap->kern[2][2]=3;
img_convolve(srcimg,dx,dy,msk_lap, temp1);
msk_lap->kern[0][0]=3;
msk_lap->kern[0][1]=-5;
msk_lap->kern[0][2]=-5;
msk_lap->kern[1][0]=3;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=-5;
msk_lap->kern[2][0]=3;
msk_lap->kern[2][1]=3;
msk_lap->kern[2][2]=3;
img_convolve(srcimg,dx,dy,msk_lap, temp2);
for(i =0 ;i< m_dwHeight;i++)
for( j = 0 ; jtemp2[i*m_dwLine+j] )
destimg[i*m_dwLine+j] = temp1[i*m_dwLine+j];
else
destimg[i*m_dwLine+j] = temp2[i*m_dwLine+j];
}
delete[]temp1;
delete[]temp2;
msk_lap->kern[0][0]=3;
msk_lap->kern[0][1]=3;
msk_lap->kern[0][2]=-5;
msk_lap->kern[1][0]=3;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=-5 ;
msk_lap->kern[2][0]=3;
msk_lap->kern[2][1]=3;
msk_lap->kern[2][2]=-5;
img_convolve(srcimg,dx,dy,msk_lap, temp3);
for( i =0 ;i< m_dwHeight;i++)
for(j = 0 ; jdestimg[i*m_dwLine+j] )
destimg[i*m_dwLine+j] = temp3[i*m_dwLine+j];
}
delete[]temp3;
msk_lap->kern[0][0]=3;
msk_lap->kern[0][1]=3;
msk_lap->kern[0][2]=3;
msk_lap->kern[1][0]=3;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=-5;
msk_lap->kern[2][0]=3;
msk_lap->kern[2][1]=-5;
msk_lap->kern[2][2]=-5;
img_convolve(srcimg,dx,dy,msk_lap, temp4);
for(i =0 ;i< m_dwHeight;i++)
for( j = 0 ; jdestimg[i*m_dwLine+j] )
destimg[i*m_dwLine+j] = temp4[i*m_dwLine+j];
}
delete[]temp4;
msk_lap->kern[0][0]=3;
msk_lap->kern[0][1]=3;
msk_lap->kern[0][2]=3;
msk_lap->kern[1][0]=3;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=3;
msk_lap->kern[2][0]=-5;
msk_lap->kern[2][1]=-5;
msk_lap->kern[2][2]=-5;
img_convolve(srcimg,dx,dy,msk_lap, temp5);
for( i =0 ;i< m_dwHeight;i++)
for( j = 0 ; jdestimg[i*m_dwLine+j] )
destimg[i*m_dwLine+j] = temp5[i*m_dwLine+j];
}
delete[]temp5;
msk_lap->kern[0][0]=3;
msk_lap->kern[0][1]=3;
msk_lap->kern[0][2]=3;
msk_lap->kern[1][0]=-5;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=3;
msk_lap->kern[2][0]=-5;
msk_lap->kern[2][1]=-5;
msk_lap->kern[2][2]=3;
img_convolve(srcimg,dx,dy,msk_lap, temp6);
for( i =0 ;i< m_dwHeight;i++)
for( j = 0 ; jdestimg[i*m_dwLine+j] )
destimg[i*m_dwLine+j] = temp6[i*m_dwLine+j];
}
delete[]temp6;
msk_lap->kern[0][0]=-5;
msk_lap->kern[0][1]=3;
msk_lap->kern[0][2]=3;
msk_lap->kern[1][0]=-5;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=3;
msk_lap->kern[2][0]=5;
msk_lap->kern[2][1]=-3;
msk_lap->kern[2][2]=-3;
img_convolve(srcimg,dx,dy,msk_lap, temp7);
for( i =0 ;i< m_dwHeight;i++)
for( j = 0 ; jdestimg[i*m_dwLine+j] )
destimg[i*m_dwLine+j] = temp7[i*m_dwLine+j];
}
delete[]temp7;
msk_lap->kern[0][0]=-5;
msk_lap->kern[0][1]=-5;
msk_lap->kern[0][2]=3;
msk_lap->kern[1][0]=-5;
msk_lap->kern[1][1]=0;
msk_lap->kern[1][2]=3;
msk_lap->kern[2][0]=3;
msk_lap->kern[2][1]=3;
msk_lap->kern[2][2]=3;
img_convolve(srcimg,dx,dy,msk_lap, temp8);
for( i =0 ;i< m_dwHeight;i++)
for( j = 0 ; jdestimg[i*m_dwLine+j] )
destimg[i*m_dwLine+j] = temp8[i*m_dwLine+j];
}
delete[]temp8;
}
BOOL CDib::Save( const char *pszFilename )
{
// If we have no data, we can't save.
if( m_pDibBits == NULL )
return( FALSE );
CFile cf;
// Attempt to create the file.
if( !cf.Open( pszFilename,
CFile::modeCreate | CFile::modeWrite ) )
return( FALSE );
// Write the data.
try
{
// First, create a BITMAPFILEHEADER
// with the correct data.
BITMAPFILEHEADER BFH;
memset( &BFH, 0, sizeof( BITMAPFILEHEADER ) );
BFH.bfType = 'MB';
BFH.bfSize = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER )
+m_nPaletteEntries * sizeof( RGBQUAD )+m_dwDataSize;
BFH.bfOffBits = sizeof( BITMAPFILEHEADER ) +
sizeof( BITMAPINFOHEADER ) +
m_nPaletteEntries * sizeof( RGBQUAD );
// Write the BITMAPFILEHEADER and the
// Dib data.
cf.Write( &BFH, sizeof( BITMAPFILEHEADER ) );
cf.Write( m_pBIH, sizeof( BITMAPINFOHEADER ) );
cf.Write( m_pPalette, m_nPaletteEntries * sizeof( RGBQUAD ));
cf.Write( m_pDibBits, m_dwDataSize );
cf.Close();
}
// If we get an exception, delete the exception and
// return FALSE.
catch( CFileException *e )
{
e->Delete();
return( FALSE );
}
return( TRUE );
}
void CDib:: Sub(unsigned char *srcimg, unsigned char *destimg)
{
}
void CDib:: Roberts2(unsigned char *srcimg, long dx, long dy, unsigned char *destimg)
{
int x,y;
int d;
for(y=0;y<-m_dwHeight-1;y++)
{
for(x=0;x255) d=255;
destPoint(x,y)=(BYTE)d;
}
}
}
HDIB CDib::LoadDIB(LPCTSTR lpFileName)
{
HANDLE hDIB;
HANDLE hFile;
//创建文件句柄
if((hFile = CreateFile(lpFileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL))!= INVALID_HANDLE_VALUE)
{
//读取数据
hDIB = ReadDIBFile(hFile);
//关闭文件句柄
CloseHandle(hFile);
return hDIB;
}
return NULL;
}
HDIB CDib::ReadDIBFile(HANDLE hFile)
{
BITMAPFILEHEADER bmfHeader;
DWORD dwBitsSize;
HANDLE hDIB;
HANDLE hDIBtmp;
LPBITMAPINFOHEADER lpbi;
DWORD dwRead;
//得到文件大小
dwBitsSize = GetFileSize(hFile,NULL);
hDIB = GlobalAlloc(GMEM_MOVEABLE,(DWORD)(sizeof(BITMAPINFOHEADER)));
if(!hDIB)
return NULL;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
if(!lpbi)
{
GlobalFree(hDIB);
return NULL;
}
if(!ReadFile(hFile,(LPBYTE)&bmfHeader,sizeof(BITMAPFILEHEADER),&dwRead,NULL))
goto ErrExit;
if(sizeof(BITMAPFILEHEADER)!=dwRead)//读取文件出错
goto ErrExit;
if(bmfHeader.bfType != 0x4d42)//文件类型不匹配
goto ErrExit;
if(!ReadFile(hFile,(LPBYTE)lpbi,sizeof(BITMAPINFOHEADER),&dwRead,NULL))
goto ErrExit;
if(sizeof(BITMAPINFOHEADER)!= dwRead)//读取数据出错
goto ErrExit;
GlobalUnlock(hDIB);
if(lpbi->biSizeImage==0)
lpbi->biSizeImage = (this->BytePerLine(hDIB))*lpbi->biHeight;
hDIBtmp = GlobalReAlloc(hDIB,lpbi->biSize+lpbi->biSizeImage,0);
if(!hDIBtmp)
goto ErrExitNoUnlock;
else
hDIB = hDIBtmp;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
//根据情况设定文件指针
if(bmfHeader.bfOffBits != 0L)
SetFilePointer(hFile,bmfHeader.bfOffBits,NULL,FILE_BEGIN);
//读取文件的象素颜色数据
if(ReadFile(hFile,(LPBYTE)lpbi+lpbi->biSize,lpbi->biSizeImage,&dwRead,NULL))
goto OKExit;
ErrExit:
GlobalUnlock(hDIB);
ErrExitNoUnlock:
GlobalFree(hDIB); //释放内存
return NULL;
OKExit:
GlobalUnlock(hDIB);
return hDIB;
}
BOOL CDib::PaintDIBTrue(HDC hDC,LPRECT lpDCRect,HANDLE hDIB,LPRECT lpDIBRect ,DWORD dwRop)
{
LPBYTE lpDIBHdr;
LPBYTE lpDIBBits;
BOOL bSuccess = FALSE;
if(!hDIB)
return FALSE;
lpDIBHdr = (LPBYTE)GlobalLock(hDIB);
lpDIBBits = lpDIBHdr + sizeof(BITMAPINFOHEADER);
bSuccess = StretchDIBits(hDC,lpDCRect->left,
lpDCRect->top,
RECTWIDTH(lpDCRect),
RECTHEIGHT(lpDCRect),
lpDIBRect->left,
((LPBITMAPINFOHEADER)lpDIBHdr)->biHeight-lpDIBRect->top-RECTHEIGHT(lpDIBRect),
RECTWIDTH(lpDIBRect),
RECTHEIGHT(lpDIBRect),
lpDIBBits,
(LPBITMAPINFO)lpDIBHdr,
DIB_RGB_COLORS,
SRCCOPY);
GlobalUnlock(hDIB);
return bSuccess;
}
WORD CDib::BytePerLine(HANDLE hDIB)
{
WORD i;
LPBITMAPINFOHEADER lpbi;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
i = WIDTHBYTES((lpbi->biWidth)*24);
GlobalUnlock(hDIB);
return i;
}
//函数实现图片从彩色到黑白的转换
HDIB CDib::ToGray(HANDLE hDIB)
{
HDIB hNewDIB = NULL;
LPBITMAPINFOHEADER lpSrc,lpDest;
LPBYTE lpS,lpD;
DWORD dwBytesPerLine;
DWORD dwImgSize;
WORD wBytesPerLine;
unsigned i ,j,height,width;
if(!hDIB)
return NULL;
lpSrc = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
dwBytesPerLine = WIDTHBYTES(24*(lpSrc->biWidth));
dwImgSize = lpSrc->biHeight * dwBytesPerLine;
//申请新的内存,大小等于原来图象的大小
hNewDIB = GlobalAlloc(GHND,sizeof(BITMAPINFOHEADER)+dwImgSize);
lpDest = (LPBITMAPINFOHEADER)GlobalLock(hNewDIB);
//保存图片的长宽、颜色深度等信息
memcpy((void*)lpDest,(void*)lpSrc,sizeof(BITMAPINFOHEADER));
DWORD dwSBytesPerLine;
dwSBytesPerLine = (24*(lpSrc->biWidth)+31)/32*4;
height = lpDest->biHeight;
width = lpDest->biWidth;
lpS = (LPBYTE)lpSrc;
wBytesPerLine = this->BytePerLine(hDIB);
lpD = (LPBYTE)lpDest;
lpS = lpS + sizeof(BITMAPINFOHEADER);
lpD = lpD + sizeof(BITMAPINFOHEADER);
unsigned r , g ,b,gray ;
//扫描整个图片,实现灰度化
for(i = 0 ;ibiWidth;j++)
{
//获得原来图片的颜色值
r = *(lpS++);
g = *(lpS++);
b = *(lpS++);
//计算灰度值
gray = (g*50+r*39+b*11)/100;
//保存灰度值到目标图片
*(lpD++)=gray;
*(lpD++) = gray;
*(lpD++) = gray;
}
//处理四字节对齐问题
unsigned k ;
for(k=0;kbiWidth*3;k++)
{
lpS++;
lpD++;
}
}
GlobalUnlock(hDIB);
GlobalUnlock(hNewDIB);
return hNewDIB;
}
void CDib::MedianFilterDIB(HANDLE hDIB)
{
HDIB hNewDIB;
LPBYTE lpS,lpD;
LPBITMAPINFOHEADER lpbi;
int r,g,b;
DWORD width,height;
WORD wBytesPerLine;
long lOffset;
if(!hDIB)
return;
SetCursor(LoadCursor(NULL,IDC_WAIT));
wBytesPerLine = this->BytePerLine(hDIB);
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
width = lpbi->biWidth;
height = lpbi->biHeight;
//申请一块新的内存
hNewDIB = GlobalAlloc(GHND,sizeof(BITMAPINFOHEADER)+lpbi->biSizeImage);
lpD = (LPBYTE)GlobalLock(hNewDIB);
lpS = (LPBYTE)lpbi;
memcpy(lpD,lpS,sizeof(BITMAPINFOHEADER));
lpS = lpS+sizeof(BITMAPINFOHEADER);
lpD = lpD+sizeof(BITMAPINFOHEADER);
//扫描整个图片
for(WORD i=1;iDoMedianFilterDIB(&r,&g,&b,i,j,wBytesPerLine,lpS);
lOffset = this->PixelOffset(i,j,wBytesPerLine);
*(lpD+lOffset++) = r;
*(lpD+lOffset++) = g;
*(lpD+lOffset) = b;
}
//把信息拷贝回原来的句柄
for( i = 1;iPixelOffset(i,j,wBytesPerLine);
//活得新图片的颜色
int color1 = *(lpD+lOffset++);
int color2 = *(lpD+lOffset++);
int color3 = *(lpD+lOffset++);
//拷贝到原来图片中
*(lpS+lOffset++) = color1;
*(lpS+lOffset++) = color2;
*(lpS+lOffset++) = color3;
}
SetCursor(LoadCursor(NULL,IDC_ARROW));
GlobalUnlock(hDIB);
GlobalUnlock(hNewDIB);
GlobalFree(hNewDIB);
}
void CDib::DoMedianFilterDIB(int *r,int *g,int*b,WORD i,WORD j,WORD wBytesPerLine,LPBYTE lpDIBBits)
{
long lOffset;
int rgb[9][3];
//把八个方位和当前位置得rgb值保存到数组rgb[9][3]中
lOffset = this->PixelOffset( i-1, j-1, wBytesPerLine);
rgb[0][0] = *(lpDIBBits+lOffset++);
rgb[0][1] = *(lpDIBBits+lOffset++);
rgb[0][2] = *(lpDIBBits+lOffset++);
lOffset = this->PixelOffset( i-1, j, wBytesPerLine);
rgb[1][0] = *(lpDIBBits+lOffset++);
rgb[1][1] = *(lpDIBBits+lOffset++);
rgb[1][2] = *(lpDIBBits+lOffset++);
lOffset = this->PixelOffset( i-1, j+1, wBytesPerLine);
rgb[2][0] = *(lpDIBBits+lOffset++);
rgb[2][1] = *(lpDIBBits+lOffset++);
rgb[2][2] = *(lpDIBBits+lOffset++);
lOffset = this->PixelOffset( i, j-1, wBytesPerLine);
rgb[3][0] = *(lpDIBBits+lOffset++);
rgb[3][1] = *(lpDIBBits+lOffset++);
rgb[3][2] = *(lpDIBBits+lOffset++);
lOffset = this->PixelOffset( i, j, wBytesPerLine);
rgb[4][0] = *(lpDIBBits+lOffset++);
rgb[4][1] = *(lpDIBBits+lOffset++);
rgb[4][2] = *(lpDIBBits+lOffset++);
lOffset = this->PixelOffset( i, j+1, wBytesPerLine);
rgb[5][0] = *(lpDIBBits+lOffset++);
rgb[5][1] = *(lpDIBBits+lOffset++);
rgb[5][2] = *(lpDIBBits+lOffset++);
lOffset = this->PixelOffset( i+1, j-1, wBytesPerLine);
rgb[6][0] = *(lpDIBBits+lOffset++);
rgb[6][1] = *(lpDIBBits+lOffset++);
rgb[6][2] = *(lpDIBBits+lOffset++);
lOffset = this->PixelOffset( i+1, j, wBytesPerLine);
rgb[7][0] = *(lpDIBBits+lOffset++);
rgb[7][1] = *(lpDIBBits+lOffset++);
rgb[7][2] = *(lpDIBBits+lOffset++);
lOffset = this->PixelOffset( i+1, j+1, wBytesPerLine);
rgb[8][0] = *(lpDIBBits+lOffset++);
rgb[8][1] = *(lpDIBBits+lOffset++);
rgb[8][2] = *(lpDIBBits+lOffset++);
this->MedianSearch( rgb,9,b,g,r);
}
int CDib::MedianSearch(int a[9][3],int n,int *r,int *g,int *b)
{
int result,i,j,temp;
//冒泡法排序,找出rgb中间值
for(i=0;i<9;i++)
for(j = 0 ;ja[j+1][0])
{
temp = a[j][0];
a[j][0] = a[j+1][0];
a[j+1][0]=temp;
}
if(a[j][1]>a[j+1][1])
{
temp = a[j][1];
a[j][1] = a[j+1][1];
a[j+1][1]=temp;
}
if(a[j][2]>a[j+1][2])
{
temp = a[j][2];
a[j][2] = a[j+1][2];
a[j+1][2]=temp;
}
}
//得到rgb得中间值
*b = a[5][0];
*g = a[5][1];
*r = a[5][2];
//根据需要也可以选用灰度值
result = (a[5][0]*39 +a[5][1]*50 + a[5][2]*11)/100;
return result;
}
HANDLE CDib:: Gradient(HANDLE hDIB)
{
LPBITMAPINFOHEADER lpbi;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
int width = lpbi->biWidth;
int height = lpbi->biHeight;
long lOffset;
LPBYTE lpS,lpD;
WORD wBytesPerLine = this->BytePerLine(hDIB);
HANDLE hNewDIB;
hNewDIB = GlobalAlloc(GMEM_MOVEABLE,(DWORD)(lpbi->biSize+lpbi->biSizeImage));
if(!hNewDIB)
{
AfxMessageBox("分配内存失败");
return NULL;
}
lpS = (LPBYTE)lpbi;
lpD =(LPBYTE) GlobalLock(hNewDIB);
memcpy(lpD,lpS,sizeof(BITMAPINFOHEADER));
lpS = this->FindDIBBits(hDIB);
lpD = this->FindDIBBits(hNewDIB);
int color1,color2;
for(int i=1;iPixelOffset(i+1,j+1,wBytesPerLine);
color1 = *(lpS+lOffset);
lOffset = this->PixelOffset(i-1,j-1,wBytesPerLine);
color2 = *(lpS+lOffset);
lOffset = this->PixelOffset(i,j,wBytesPerLine);
*(lpD+lOffset++) = abs(color2-color1)*3;
*(lpD+lOffset++) = abs(color2-color1)*3;
*(lpD+lOffset++) = abs(color2-color1)*3;
}
for(i =0;iPixelOffset(i,0,wBytesPerLine);
*(lpD+lOffset++) =0;
*(lpD+lOffset++) =0;
*(lpD+lOffset++) =0;
}
for(i =0;iPixelOffset(i,width-1,wBytesPerLine);
*(lpD+lOffset++) =0;
*(lpD+lOffset++) =0;
*(lpD+lOffset++) =0;
}
for(i =0;iPixelOffset(height-1,i,wBytesPerLine);
*(lpD+lOffset++) =0;
*(lpD+lOffset++) =0;
*(lpD+lOffset++) =0;
}
for(i =0;iPixelOffset(0,i,wBytesPerLine);
*(lpD+lOffset++) =0;
*(lpD+lOffset++) =0;
*(lpD+lOffset++) =0;
}
GlobalUnlock(hNewDIB);
GlobalUnlock(hDIB);
return hNewDIB;
}
long CDib:: PixelOffset(int i,int j,WORD wBytePerLine)
{
long Offset;
Offset = i*wBytePerLine + j*3;
return Offset;
}
LPBYTE CDib:: FindDIBBits(HANDLE hDIB)
{
LPBYTE lpDIB,lpDIBtmp;
LPBITMAPINFOHEADER lpbi;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
lpDIBtmp = (LPBYTE)lpbi;
lpDIB = lpDIBtmp + sizeof(BITMAPINFOHEADER);
GlobalUnlock(hDIB);
return lpDIB;
}
//函数寻找图片中的特征区域的中心点
void CDib:: LocateImporntPoint(HANDLE hDIB, int Radius, CPoint *pPoint)
{
LPBITMAPINFOHEADER lpbi;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
int width ,height;
width = lpbi->biWidth;
height = lpbi->biHeight;
WORD wBytesPerLine;
wBytesPerLine = this->BytePerLine(hDIB);
LPBYTE lpData;
lpData = this->FindDIBBits(hDIB);
int tempsum=0,sum=0;//定义两个变量用来记数
long lOffset;
//扫描整个图片(边缘点除外)寻找特征区域
for(int i=Radius;iPixelOffset(i+k1,j+k2,wBytesPerLine);
int color = *(lpData+lOffset);
tempsum +=color;//累加象素值
}
if(tempsum>sum)//如果得到的累计象素值大于已经得到的最大值
{
//更改累计象素值大小
sum = tempsum;
//更改特征区域中心点
(pPoint->x) = j;
(pPoint->y) = i;
}
}
//下面的代码把特征区域的边框设置成白色
for( i = -Radius;i<=Radius;i++)
{
lOffset = this->PixelOffset(pPoint->y-Radius,pPoint->x +i,wBytesPerLine);
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 255;
}
for( i = -Radius;i<=Radius;i++)
{
lOffset = this->PixelOffset(pPoint->y+Radius,pPoint->x +i,wBytesPerLine);
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 255;
}
for( i = -Radius;i<=Radius;i++)
{
lOffset = this->PixelOffset(pPoint->y+i,pPoint->x-Radius ,wBytesPerLine);
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 255;
}
for( i = -Radius;i<=Radius;i++)
{
lOffset = this->PixelOffset(pPoint->y+i,pPoint->x+Radius,wBytesPerLine);
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 255;
}
lOffset = this->PixelOffset(pPoint->y,pPoint->x ,wBytesPerLine);
*(lpData+lOffset++) = 0;
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 0;
GlobalUnlock(hDIB);
}
//函数在一幅图片中寻找匹配的中心点
BOOL CDib::MatchImportantPoint(HANDLE hDIB,int CharaterInfo[RADIUS*2+1][RADIUS*2+1][3],CPoint *ImPoint)
{
LPBITMAPINFOHEADER lpbi;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
int width = lpbi->biWidth;
int height = lpbi->biHeight;
LPBYTE lpData = this->FindDIBBits(hDIB);
WORD wBytesPerLine = this->BytePerLine(hDIB);
long lOffset;
long sum =100000,tempsum;
//扫描整个图片(边缘点)除外
for(int i=RADIUS ;iPixelOffset(i+k,j+kk,wBytesPerLine);
int colorblue = abs(*(lpData+lOffset++)-CharaterInfo[k+RADIUS][kk+RADIUS][0]);
int colorgreen = abs(*(lpData+lOffset++)-CharaterInfo[k+RADIUS][kk+RADIUS][1]);
int colorred = abs(*(lpData+lOffset++)-CharaterInfo[k+RADIUS][kk+RADIUS][2]);
tempsum +=colorgreen+colorblue+colorred;
}
if(tempsumx = j;
ImPoint->y = i;
}
}
if(sum PixelOffset(ImPoint->y-RADIUS,ImPoint->x+i,wBytesPerLine);
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 255;
}
for(i =-RADIUS;i<=RADIUS;i++)
{
lOffset = this->PixelOffset(ImPoint->y+RADIUS,ImPoint->x+i,wBytesPerLine);
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 255;
}
for(i =-RADIUS;i<=RADIUS;i++)
{
lOffset = this->PixelOffset(ImPoint->y+i,ImPoint->x+RADIUS,wBytesPerLine);
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 255;
}
for(i =-RADIUS;i<=RADIUS;i++)
{
lOffset = this->PixelOffset(ImPoint->y+i,ImPoint->x-RADIUS,wBytesPerLine);
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 255;
}
GlobalUnlock(hDIB);
return true;
}
else AfxMessageBox("Can't find the corresponding point!");
GlobalUnlock(hDIB);
return false;
}
BOOL CDib::ComPareImg(HANDLE hDIB1, HANDLE hDIB2 ,CPoint pt1,CPoint pt2)
{
if(abs(pt1.x-pt2.x)>3 || abs(pt1.y -pt2.y)>3)//图象偏差过大
{
AfxMessageBox("Imgs Offset are too big");
return false;
}
LPBITMAPINFOHEADER lpbi1,lpbi2;
lpbi1 = (LPBITMAPINFOHEADER)GlobalLock(hDIB1);
int width1 = lpbi1->biWidth;
int height1 = lpbi1->biHeight;
lpbi2 = (LPBITMAPINFOHEADER)GlobalLock(hDIB2);
int width2 = lpbi2->biWidth;
int height2 = lpbi2->biHeight;
if(width1 != width2 || height1 != height2)//图象长宽尺寸不同
{
GlobalUnlock(hDIB1);
GlobalUnlock(hDIB2);
AfxMessageBox("Img is not same size");
return false;
}
LPBYTE lpData1,lpData2;
lpData1 = this->FindDIBBits(hDIB1);
lpData2 = this->FindDIBBits(hDIB2);
WORD wBytesPerLine = this->BytePerLine(hDIB1);
int xleft,xright,ytop,ybottom;
//下面的一段代码实现图象对齐
if(pt1.x>=pt2.x)//第一幅图得特征中心点比第二幅图偏右
{
xleft = pt2.x;//要处理得左边得象素点个数
xright =width-pt1.x-1;//要处理得右边得象素点个数
}
else//第一幅图得特征中心点比第二幅图偏左
{
xleft = pt1.x;
xright = width1-pt2.x-1;
}
if(pt1.y >=pt2.y)//第一幅图得特征中心点得位置偏上
{
ytop = pt2.y;//要处理得中心点上面得象素个数
ybottom = height1-pt1.y-1;//要处理得中心点下面得象素个数
}
else//第一幅图得特征中心点得位置偏下
{
ytop = pt1.y;
ybottom = height1-pt2.y-1;
}
long sum=0;
long lOffset;
//计算两幅图片交叉区域得象素差值
for(int i=-ytop;i<=ybottom;i++)
for(int j=-xleft;j<=xright;j++)
{
//第一幅图
lOffset = this->PixelOffset(i+pt1.y,j+pt1.x,wBytesPerLine);
int c11 = *(lpData1+lOffset++);
int c12 = *(lpData1+lOffset++);
int c13 = *(lpData1+lOffset++);
//第二幅图
lOffset = this->PixelOffset(i+pt2.y,j+pt2.x,wBytesPerLine);
int c21 = *(lpData2+lOffset++);
int c22 = *(lpData2+lOffset++);
int c23 = *(lpData2+lOffset++);
//计算差值
sum += abs(c11-c21)+abs(c12-c22)+abs(c13-c23);
}
GlobalUnlock(hDIB1);
GlobalUnlock(hDIB2);
if(sum>width1*height1*3*2)//判断是否相似
return false;
else
return true;
}
BOOL CDib:: CompareImg2(HANDLE hDIBBK,HANDLE hDIBCurrent,CPoint pt1,CPoint pt2)
{
if(abs(pt1.x-pt2.x)>3 || abs(pt1.y -pt2.y)>3)
{
AfxMessageBox("Imgs Offset are too big");
return false;
}
LPBITMAPINFOHEADER lpbi1,lpbi2;
lpbi1 = (LPBITMAPINFOHEADER)GlobalLock(hDIBBK);
int width1 = lpbi1->biWidth;
int height1 = lpbi1->biHeight;
lpbi2 = (LPBITMAPINFOHEADER)GlobalLock(hDIBCurrent);
int width2 = lpbi2->biWidth;
int height2 = lpbi2->biHeight;
if(width1 != width2 || height1 != height2)
{
GlobalUnlock(hDIBBK);
GlobalUnlock(hDIBCurrent);
AfxMessageBox("Img is not same size");
return false;
}
LPBYTE lpData1,lpData2;
lpData1 = this->FindDIBBits(hDIBBK);
lpData2 = this->FindDIBBits(hDIBCurrent);
WORD wBytesPerLine = this->BytePerLine(hDIBBK);
int xleft,xright,ytop,ybottom;
if(pt1.x>=pt2.x)
{
xleft = pt2.x;
xright =width1-pt1.x-1;
}
else
{
xleft = pt1.x;
xright = width1-pt2.x-1;
}
if(pt1.y >=pt2.y)
{
ytop = pt2.y;
ybottom = height1-pt1.y-1;
}
else
{
ytop = pt1.y;
ybottom = height1-pt2.y-1;
}
long sum=0;
long lOffset;
for(int i=-ytop;i<=ybottom;i++)
for(int j=-xleft;j<=xright;j++)
{
lOffset = this->PixelOffset(i+pt1.y,j+pt1.x,wBytesPerLine);
int c11 = *(lpData1+lOffset++);
int c12 = *(lpData1+lOffset++);
int c13 = *(lpData1+lOffset++);
lOffset = this->PixelOffset(i+pt2.y,j+pt2.x,wBytesPerLine);
int c21 = *(lpData2+lOffset++);
int c22 = *(lpData2+lOffset++);
int c23 = *(lpData2+lOffset++);
lOffset = this->PixelOffset(i+pt2.y,j+pt2.x,wBytesPerLine);
*(lpData2+lOffset++) = abs(c11-c21);
*(lpData2+lOffset++) = abs(c12-c22);
*(lpData2+lOffset++) = abs(c13-c23);
}
for(i =0;ipt2.y+ybottom||jpt2.x+xright)
{
lOffset = this->PixelOffset(i,j,wBytesPerLine);
*(lpData2+lOffset++) = 0;
*(lpData2+lOffset++) = 0;
*(lpData2+lOffset++) = 0;
}
}
GlobalUnlock(hDIBBK);
GlobalUnlock(hDIBCurrent);
return true;
}