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