📄 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 + -