?? dib.cpp
字號:
// *r=r11;
//*g=g11;
// *b=b11;
// return (0x00ffffff&((b<<16)|(g<<8)|r));
}
HANDLE DIB::CopyHandle( HANDLE hSrc)
{
HANDLE hDst;
LPBITMAPINFOHEADER lpbi;
int width,height;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hSrc);
width = lpbi->biWidth;
height = lpbi->biHeight;
hDst = GlobalAlloc(GMEM_MOVEABLE,lpbi->biSize+lpbi->biSizeImage);
if(!hDst)
return NULL;
LPBYTE lpDest;
lpDest = (LPBYTE)GlobalLock(hDst);
memcpy(lpDest,(LPBYTE)lpbi,lpbi->biSize+lpbi->biSizeImage);
GlobalUnlock(hSrc);
GlobalUnlock(hDst);
return hDst;
}
HANDLE DIB:: 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;i<height-1;i++)
for(int j=1;j<width-1;j++)
{
lOffset = this->PixelOffset(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;i<height;i++)
{
lOffset = this->PixelOffset(i,0,wBytesPerLine);
*(lpD+lOffset++) =0;
*(lpD+lOffset++) =0;
*(lpD+lOffset++) =0;
}
for(i =0;i<height;i++)
{
lOffset = this->PixelOffset(i,width-1,wBytesPerLine);
*(lpD+lOffset++) =0;
*(lpD+lOffset++) =0;
*(lpD+lOffset++) =0;
}
for(i =0;i<width;i++)
{
lOffset = this->PixelOffset(height-1,i,wBytesPerLine);
*(lpD+lOffset++) =0;
*(lpD+lOffset++) =0;
*(lpD+lOffset++) =0;
}
for(i =0;i<width;i++)
{
lOffset = this->PixelOffset(0,i,wBytesPerLine);
*(lpD+lOffset++) =0;
*(lpD+lOffset++) =0;
*(lpD+lOffset++) =0;
}
GlobalUnlock(hNewDIB);
GlobalUnlock(hDIB);
return hNewDIB;
}
//函數尋找圖片中的特征區域的中心點
void DIB::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;i<height-Radius;i++)
for(int j= Radius;j<width-Radius;j++)
{ tempsum =0;
//掃描以Radius×2+1為邊長的正方形區域
for(int k1=-Radius;k1<=Radius;k1++)
for(int k2 =-Radius;k2<=Radius;k2++)
{
lOffset = this->PixelOffset(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);
}
#define THRESHOLD (RADIUS*2+1)*(RADIUS*2+1)*15
//函數在一幅圖片中尋找匹配的中心點
BOOL DIB::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 ;i<height-RADIUS;i++)
for(int j=RADIUS;j<width-RADIUS;j++)
{
tempsum =0;
//掃描以RADIUS*2+1為邊長的正方形區域
for(int k=-RADIUS;k<=RADIUS;k++)
for(int kk=-RADIUS;kk<=RADIUS;kk++)
{
//計算當前正方形和已知特征區域的顏色差值
lOffset = this->PixelOffset(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(tempsum<sum)
{ //更新差值
sum = tempsum;
//更改特征坐標點
ImPoint->x = j;
ImPoint->y = i;
}
}
if(sum <THRESHOLD){//找到滿足條件的區域
//下面的代碼把找到的區域的邊框設置成為白色
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+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 DIB::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 DIB:: 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;i<height1;i++)
for(int j=0;j<width1;j++)
{
if(i<pt2.y-ytop || i>pt2.y+ybottom||j<pt2.x-xleft || j >pt2.x+xright)
{
lOffset = this->PixelOffset(i,j,wBytesPerLine);
*(lpData2+lOffset++) = 0;
*(lpData2+lOffset++) = 0;
*(lpData2+lOffset++) = 0;
}
}
GlobalUnlock(hDIBBK);
GlobalUnlock(hDIBCurrent);
return true;
}
BOOL DIB::IsScaterPoint(int x, int y, int width, int height, LPBYTE lpData,WORD wBytesPerLine, int threshold,bool lab[m_HEIGHT][m_WIDTH])
{
long lOffset;
lOffset = this->PixelOffset(y,x,wBytesPerLine);
if(*(lpData+lOffset) == 255 && lab[y][x] == false)
{
this->lenth++;
lab[y][x] = true;
if(this->lenth >= threshold)
return true;
if(x+1<width && lab[y][x+1] == false)
{ IsScaterPoint(x+1,y,width,height,lpData,wBytesPerLine,threshold,lab);
if(this->lenth>=threshold)
return true;
}
if(x-1>=0 && lab[y][x-1] == false)
{
(IsScaterPoint(x-1,y,width,height,lpData,wBytesPerLine,threshold,lab));
if(this->lenth>=threshold)
return true;
}
if(y-1>=0 && lab[y-1][x]==false)
{
(IsScaterPoint(x,y-1,width,height,lpData,wBytesPerLine,threshold,lab));
if(this->lenth>=threshold)
return true;
}
if(y+1<height && lab[y+1][x]==false)
{ (IsScaterPoint(x,y+1,width,height,lpData,wBytesPerLine,threshold,lab));
if(this->lenth>=threshold)
return true;
}
if(y+1<height && x+1 <width && lab[y+1][x+1]==false)
{ (IsScaterPoint(x+1,y+1,width,height,lpData,wBytesPerLine,threshold,lab));
if(this->lenth>=threshold)
return true;
}
if(y+1<height && x-1 >=0 && lab[y+1][x-1]==false)
{ (IsScaterPoint(x-1,y+1,width,height,lpData,wBytesPerLine,threshold,lab));
if(this->lenth>=threshold)
return true;
}
if(y-1>=0 && x-1 >=0 &&lab[y-1][x-1]==false)
{ (IsScaterPoint(x-1,y-1,width,height,lpData,wBytesPerLine,threshold,lab));
if(this->lenth>=threshold)
return true;
}
if(y-1<height && x+1<width && lab[y+1][x]==false)
{ (IsScaterPoint(x+1,y-1,width,height,lpData,wBytesPerLine,threshold,lab));
if(this->lenth>=threshold)
return true;
}
}
return false;
}
//函數得到邊界得中心點
CPoint DIB:: GetEdgeCenter(HANDLE hDIB)
{
LPBITMAPINFOHEADER lpbi;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
int width = lpbi->biWidth;
int height = lpbi->biHeight;
WORD wBytesPerLine = this->BytePerLine(hDIB);
LPBYTE lpData = this->FindDIBBits(hDIB);
long lOffset;
int x =0,y =0,num =0;
//對整幅圖片進行掃描
for(int i=0;i<height;i++)
for(int j=0;j<width;j++)
{
lOffset = this->PixelOffset(i,j,wBytesPerLine);
if(*(lpData+lOffset) ==255)//如果是白色象素
{
x +=j;//中心點得橫坐標和縱坐標加上當前得橫坐標和縱坐標
y +=i;
num++;
}
}
//得到結果坐標點
CPoint result;
result.x = x/num;
result.y = y/num;
//把中心點設置為綠色
lOffset = this->PixelOffset(result.y,result.x,wBytesPerLine);
*(lpData+lOffset++) = 0;
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 0;
return result;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -