📄 dib.cpp
字号:
//判断Cr分量的数值,并修改标志
cmap = cr- 144 ;
if(cmap <=-2 || cmap>= 2)
{
lab = false;
}
//根据标志设定图像颜色
if(lab)
cmap = 255;
else
cmap = 0;
//保存图象颜色
*(lpRgb + lOffset++) = cmap;
*(lpRgb + lOffset++) = cmap;
*(lpRgb + lOffset++) = cmap;
}
}
void DIB::EyeMapb(LPBYTE lpRgb, const LPBYTE lpYcc, WORD wBytesPerLine, CRect faceLocation)
{
long lOffset;
int cr;
int cb;
for(int i=faceLocation.top; i<=faceLocation.bottom; i++)
for (int j=faceLocation.left; j<=faceLocation.right; j++)
{
lOffset = PixelOffset(i, j, wBytesPerLine);
cb = *(lpYcc + lOffset +2);
*(lpRgb + lOffset++) = cb;
*(lpRgb + lOffset++) = cb;
*(lpRgb + lOffset++) = cb;
}
}
void DIB::EyeMapR(LPBYTE lpRgb, const LPBYTE lpYcc, WORD wBytesPerLine, CRect faceLocation)
{
long lOffset;
int cr;
int cb;
for(int i=faceLocation.top; i<=faceLocation.bottom; i++)
for (int j=faceLocation.left; j<=faceLocation.right; j++)
{
lOffset = PixelOffset(i, j, wBytesPerLine);
cr = *(lpYcc + lOffset +1);
cb = *(lpYcc + lOffset +2);
*(lpRgb + lOffset++) = cr;
*(lpRgb + lOffset++) = cr;
*(lpRgb + lOffset++) = cr;
}
}
void DIB::ErasionFalseArea(HANDLE hDIB)
{
int PixelNum[255];
LPBITMAPINFOHEADER lpbi;
int width;
int height;
LPBYTE lpData;
WORD wBytesPerLine;
long lOffset;
//得到长宽信息
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
height = lpbi->biHeight;
width = lpbi->biWidth;
//得到数据区指针和每行字节数
lpData = FindDIBBits(hDIB);
wBytesPerLine = BytePerLine(hDIB);
//初始化象素累计数组
for (int i=0; i<255; i++)
{
PixelNum[i] = 0;
}
int calNum =1;
for (i=0; i<height; i++)
for (int j=0; j<width; j++)
{
lOffset = PixelOffset(i,j,wBytesPerLine);
//如果象素为白色
if (*(lpData + lOffset)==255)
{
//递归统计该区域连续的白色点象素点个数
RecursiveCal(lpData, i,j,wBytesPerLine, PixelNum[calNum],calNum);
calNum++;
}
}
for (i=0; i<calNum; i++)
{
//如果象素点个数小于一定数目则把这个标志设置为0
if (PixelNum[i] < AREAPIXEL)
{
PixelNum[i] = 0;
}
}
//下面的循环根据标志数组来最终设定图象的颜色
for(i=0; i<height; i++)
for (int j=0; j<width; j++)
{
lOffset = PixelOffset( i,j,wBytesPerLine);
int num = *(lpData + lOffset);
//如果当前点不是黑色点
if(num != 0)
{
//如果标志数组为0,则设置为黑色
if(PixelNum[num] == 0)
{
*(lpData+lOffset++) =0;
*(lpData+lOffset++) =0;
*(lpData+lOffset++) =0;
}
//否则设置为白色
else
{
*(lpData+lOffset++) =255;
*(lpData+lOffset++) =255;
*(lpData+lOffset++) =255;
}
}
}
}
void DIB::RecursiveCal(LPBYTE lpData, int y, int x, WORD wBytesPerLine, int &pixelNum, int num)
{
long lOffset;
lOffset = PixelOffset(y,x,wBytesPerLine);
//如果当前点为白色点
if(*(lpData+lOffset) == 255)
{
//把当前点大小设置成为序号值
*(lpData+lOffset++) = num;
*(lpData+lOffset++) = num;
*(lpData+lOffset++) = num;
//象素个数加一
pixelNum++;
int tempx;
int tempy;
//递归当前点上面的点
tempy = y-1;
tempx = x;
RecursiveCal(lpData,tempy,tempx,wBytesPerLine,pixelNum,num);
//下面的点
tempy = y+1;
tempx = x;
RecursiveCal(lpData,tempy,tempx,wBytesPerLine,pixelNum,num);
//左边的点
tempy = y;
tempx = x-1;
RecursiveCal(lpData,tempy,tempx,wBytesPerLine,pixelNum,num);
//右边的点
tempy = y;
tempx = x+1;
RecursiveCal(lpData,tempy,tempx,wBytesPerLine,pixelNum,num);
}
}
void DIB::eyeMap(LPBYTE lpResult, bool eyemapc[][ImgRange], bool eyemapl[][ImgRange], bool lab[][ImgRange], WORD wBytesPerLine, CRect faceLocation)
{
long lOffset;
//根据得到的亮度和色度信息对眼睛进行综合匹配
for(int i=faceLocation.top; i<=faceLocation.bottom; i++)
for (int j=faceLocation.left; j<faceLocation.right; j++)
{
lOffset = PixelOffset(i, j, wBytesPerLine);
//如果当前点的亮度和色度匹配都为真,并且在人脸区域内
//就设置为白色,否则设置为黑色
if((eyemapc[i][j]) && (eyemapl[i][j]) && lab[i][j])
{
*(lpResult + lOffset++) = 255;
*(lpResult + lOffset++) = 255;
*(lpResult + lOffset++) = 255;
}
else
{
*(lpResult + lOffset++) = 0;
*(lpResult + lOffset++) = 0;
*(lpResult + lOffset++) = 0;
}
}
}
void DIB::EyeMapL(LPBYTE lpRgb, WORD wBytesPerLine, CRect faceLocation)
{
int r;
int g;
int b;
int gray ;
long lOffset;
//下面的循环实现眼睛的亮度匹配
for (int i=faceLocation.top; i<=faceLocation.bottom; i++)
for (int j=faceLocation.left; j<=faceLocation.right; j++)
{
lOffset = PixelOffset(i, j, wBytesPerLine);
//得到rgb值
b = *(lpRgb + lOffset);
g = *(lpRgb + lOffset+1);
r = *(lpRgb + lOffset+2);
//计算得到灰度
gray = (r*10+g*30+b*60)/100;
//根据眼睛的亮度区域来设定图象的数值
if(100<gray && 125>gray)
gray =255;
else
gray = 0;
*(lpRgb + lOffset++) = gray;
*(lpRgb + lOffset++) = gray;
*(lpRgb + lOffset++) = gray;
}
}
void DIB::RgbtoYcb(HANDLE hDIB, LPBYTE lpYcb)
{
LPBITMAPINFOHEADER lpbi;
int width,height;
WORD wBytesPerLine;
LPBYTE lpData;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
//得到图象的基本信息
width = lpbi->biWidth;
height = lpbi->biHeight;
lpData = FindDIBBits(hDIB);
wBytesPerLine = BytePerLine(hDIB);
long lOffset;
//下面的循环实现从rgb到ycc的转化
for(int i=0;i<height;i++)
for(int j=0;j<width;j++)
{
lOffset = PixelOffset(i,j,wBytesPerLine);
//得到rgb数值
int b = *(lpData + lOffset);
int g = *(lpData + lOffset+1);
int r = *(lpData + lOffset+2);
//计算得到y,cr,cb的数值
int Y = (257*r+504*g+98*b)/1000+16;
int Cr = (439*r-368*g-71*b)/1000+128;
int Cb = (-148*r-291*g+439*b)/1000+128;
//保存计算得到的数值
*(lpYcb+lOffset++) = Y;
*(lpYcb+lOffset++) = Cr;
*(lpYcb+lOffset++) = Cb;
}
GlobalUnlock(hDIB);
}
void DIB::Erasion(HANDLE hDIB)
{
LPBITMAPINFOHEADER lpbi;
LPBYTE lpData;
WORD wBytesPerLine;
long lOffset;
long lOffsetJudge;
int height;
int width;
//得到基本数据
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
height = lpbi->biHeight;
width = lpbi->biWidth;
wBytesPerLine = BytePerLine(hDIB);
lpData = FindDIBBits(hDIB);
HANDLE hTempDIB;
LPBYTE lpTemp;
//申请同样大小的内存
hTempDIB = GlobalAlloc(GMEM_MOVEABLE,(DWORD)(sizeof(BITMAPINFOHEADER) + wBytesPerLine*height));
//判断内存情况
if(!hTempDIB)
{
GlobalFree(hTempDIB);
GlobalFree(hDIB);
return;
}
lpTemp = (LPBYTE)GlobalLock(hTempDIB);
lpTemp+= sizeof(BITMAPINFOHEADER);
//下面的循环实现腐蚀功能
for (int i=1; i<height-1; i++)
for (int j=1; j<width-1; j++)
{
lOffset = PixelOffset(i,j,wBytesPerLine);
//如果为白色点
if (*(lpData+lOffset) == 255)
{
//考察上面的点
lOffsetJudge = PixelOffset(i-1, j, wBytesPerLine);
//如果是黑色就把原来的点设置为黑色,并接着循环
if (*(lpData + lOffsetJudge) ==0)
{
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
continue;
}
//考察下面的点
lOffsetJudge = PixelOffset(i+1, j, wBytesPerLine);
if (*(lpData + lOffsetJudge) ==0)
{
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
continue;
}
//左面的点
lOffsetJudge = PixelOffset(i, j-1, wBytesPerLine);
if (*(lpData + lOffsetJudge) ==0)
{
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
continue;
}
//右面的点
lOffsetJudge = PixelOffset(i, j+1, wBytesPerLine);
if (*(lpData + lOffsetJudge) ==0)
{
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
continue;
}
//如果上下左右四个点都是白色,则设置为白色
lOffset = this->PixelOffset(i, j, wBytesPerLine);
*(lpTemp + lOffset) = 255;
*(lpTemp + lOffset+1) = 255;
*(lpTemp + lOffset+2) = 255;
}
//如果当前点为黑色,则在暂时的目标区域中设置为黑色
else
{
*(lpTemp + lOffset) = 0;
*(lpTemp + lOffset+1) = 0;
*(lpTemp + lOffset+2) = 0;
}
}
//把图象周边的点全部设置为黑色
for(i=0; i<height; i++)
{
lOffset = PixelOffset(i, 0, wBytesPerLine);
*(lpTemp + lOffset) = 0;
*(lpTemp + lOffset+1) = 0;
*(lpTemp + lOffset+2) = 0;
}
for(i=0; i<height; i++)
{
lOffset = PixelOffset(i, width-1, wBytesPerLine);
*(lpTemp + lOffset) = 0;
*(lpTemp + lOffset+1) = 0;
*(lpTemp + lOffset+2) = 0;
}
for (i=0; i<width; i++)
{
lOffset = PixelOffset(0, i, wBytesPerLine);
*(lpTemp + lOffset) = 0;
*(lpTemp + lOffset+1) = 0;
*(lpTemp + lOffset+2) = 0;
}
for (i=0; i<width; i++)
{
lOffset = PixelOffset(height-1, i, wBytesPerLine);
*(lpTemp + lOffset) = 0;
*(lpTemp + lOffset+1) = 0;
*(lpTemp + lOffset+2) = 0;
}
//把暂时区域的数值拷贝到原来的句柄下面
memcpy(lpData,lpTemp,wBytesPerLine*height);
GlobalUnlock(hDIB);
GlobalUnlock(hTempDIB);
GlobalFree(hTempDIB);
}
void DIB::Erasion2(HANDLE hDIB)
{
LPBITMAPINFOHEADER lpbi;
LPBYTE lpData;
WORD wBytesPerLine;
long lOffset;
long lOffsetJudge;
int height;
int width;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
height = lpbi->biHeight;
width = lpbi->biWidth;
wBytesPerLine = BytePerLine(hDIB);
lpData = FindDIBBits(hDIB);
HANDLE hTempDIB;
LPBYTE lpTemp;
//申请相同大小的内存
hTempDIB = GlobalAlloc(GMEM_MOVEABLE,(DWORD)(sizeof(BITMAPINFOHEADER) + wBytesPerLine*height));
if(!hTempDIB)
{
GlobalFree(hTempDIB);
GlobalFree(hDIB);
return;
}
lpTemp = (LPBYTE)GlobalLock(hTempDIB);
lpTemp+= sizeof(BITMAPINFOHEADER);
//下面的代码实现腐蚀功能
for (int i=1; i<height-1; i++)
for (int j=1; j<width-1; j++)
{
//如果当前点为白色
lOffset = PixelOffset(i,j,wBytesPerLine);
if (*(lpData+lOffset) == 255)
{
//判断左边的带你,如果是黑色的就把暂时区域中的对应点设置为黑色
lOffsetJudge = PixelOffset(i, j-1, wBytesPerLine);
if (*(lpData + lOffsetJudge) ==0)
{
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
continue;
}
//考察右边的点
lOffsetJudge = PixelOffset(i, j+1, wBytesPerLine);
if (*(lpData + lOffsetJudge) ==0)
{
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
continue;
}
//如果左右两边的点都是白色把点设置为白色
lOffset = this->PixelOffset(i, j, wBytesPerLine);
*(lpTemp + lOffset) = 255;
*(lpTemp + lOffset+1) = 255;
*(lpTemp + lOffset+2) = 255;
}
//如果当前点为黑色,则把暂时区域中对应点设置为黑色
else
{
*(lpTemp + lOffset) = 0;
*(lpTemp + lOffset+1) = 0;
*(lpTemp + lOffset+2) = 0;
}
}
//把图象四周的点设置为黑色
for(i=0; i<height; i++)
{
lOffset = PixelOffset(i, 0, wBytesPerLine);
*(lpTemp + lOffset) = 0;
*(lpTemp + lOffset+1) = 0;
*(lpTemp + lOffset+2) = 0;
}
for(i=0; i<height; i++)
{
lOffset = PixelOffset(i, width-1, wBytesPerLine);
*(lpTemp + lOffset) = 0;
*(lpTemp + lOffset+1) = 0;
*(lpTemp + lOffset+2) = 0;
}
for (i=0; i<width; i++)
{
lOffset = PixelOffset(0, i, wBytesPerLine);
*(lpTemp + lOffset) = 0;
*(lpTemp + lOffset+1) = 0;
*(lpTemp + lOffset+2) = 0;
}
for (i=0; i<width; i++)
{
lOffset = PixelOffset(height-1, i, wBytesPerLine);
*(lpTemp + lOffset) = 0;
*(lpTemp + lOffset+1) = 0;
*(lpTemp + lOffset+2) = 0;
}
//把暂时区域的点拷贝到原句柄下
memcpy(lpData,lpTemp,wBytesPerLine*height);
GlobalUnlock(hDIB);
GlobalUnlock(hTempDIB);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -