?? facedetectiondoc.cpp
字號:
//左邊的點
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 CFaceDetectionDoc::FaceLocate(CRect faceLocation[10], int &faceNum)
{
HANDLE hDIBTemp;
hDIBTemp = CopyHandle(m_hDIB);
LPBITMAPINFOHEADER lpbi;
lpbi = (LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL) m_hDIB);//讀取頭文件
lLineBytesMulspec = WIDTHBYTES((lpbi->biWidth)*24);
::GlobalUnlock((HGLOBAL) m_hDIB);
//保存當前數據
int width,height;
LPBYTE lpData;
long wBytesPerLine;
wBytesPerLine = lLineBytesMulspec;
LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);
// 獲取DIB寬度
width= (int) ::DIBWidth(lpDIB);
// 獲取DIB高度
height= (int) ::DIBHeight(lpDIB);
lpData = (unsigned char*)::FindDIBBits(lpDIB);
//得到圖片每行的象素所占字節個數
long lOffset;
//人臉數目初始化為0
faceNum =0;
for(int k=0; k<10; k++)
{
//初始化區域
faceLocation[k].bottom = -1;
faceLocation[k].top = height;
faceLocation[k].right = -1;
faceLocation[k].left = width;
}
for(int i=0; i<height; i++)
for (int j=0; j<width; j++)
{
//偏移
lOffset = i*wBytesPerLine + j*3;
int num;
//當前點的數值
num = *(lpData + lOffset);
if (num !=0)//不是黑色
{
//遞歸計算
RecursiveLocateRect(lpData, wBytesPerLine, i, j, num, faceLocation[faceNum]);
faceNum++;
}
}
::GlobalUnlock((HGLOBAL) m_hDIB);
::GlobalFree((HGLOBAL) m_hDIB);
//數值還原
m_hDIB = (HDIB)CopyHandle(hDIBTemp);
LPSTR lpDIB2 = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);
lpData = (unsigned char*)::FindDIBBits(lpDIB2);
for (i=0; i<faceNum; i++)
for (int j=faceLocation[i].top; j<faceLocation[i].bottom; j++)
{
//把得到的人臉區域用綠色矩形標注,處理豎直的兩條邊
lOffset = j*wBytesPerLine + faceLocation[i].left*3;
*(lpData + lOffset++) = 0;
*(lpData + lOffset++) = 255;
*(lpData + lOffset++) = 0;
lOffset = j*wBytesPerLine + faceLocation[i].right*3;
*(lpData + lOffset++) = 0;
*(lpData + lOffset++) = 255;
*(lpData + lOffset++) = 0;
}
for (i=0; i<faceNum; i++)
for (int j=faceLocation[i].left; j<faceLocation[i].right; j++)
{
//處理水平的兩天矩形邊
lOffset = faceLocation[i].top*wBytesPerLine + j*3;
*(lpData + lOffset++) = 0;
*(lpData + lOffset++) = 255;
*(lpData + lOffset++) = 0;
lOffset = faceLocation[i].bottom*wBytesPerLine + j*3;
*(lpData + lOffset++) = 0;
*(lpData + lOffset++) = 255;
*(lpData + lOffset++) = 0;
}
::GlobalFree((HGLOBAL)hDIBTemp);
::GlobalUnlock((HGLOBAL) m_hDIB);
}
HANDLE CFaceDetectionDoc::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;
}
void CFaceDetectionDoc::RecursiveLocateRect(LPBYTE lpData,WORD wBytesPerLine, int y, int x, int num, CRect &faceRect)
{
long lOffset;
//得到偏移
lOffset = y*wBytesPerLine + x*3;
//數值判斷
if(*(lpData + lOffset) == num)
{
//更改顏色為黑色
*(lpData + lOffset++) = 0;
*(lpData + lOffset++) = 0;
*(lpData + lOffset++) = 0;
//修改矩形的上下左右四個點位置
if(faceRect.bottom < y)
{
faceRect.bottom = y;
}
if(faceRect.top > y)
{
faceRect.top = y;
}
if(faceRect.right < x)
{
faceRect.right = x;
}
if(faceRect.left > x)
{
faceRect.left = x;
}
//上下左右調用本函數進行區域判定
RecursiveLocateRect(lpData, wBytesPerLine, y-1, x, num,faceRect);
RecursiveLocateRect(lpData, wBytesPerLine, y+1, x, num, faceRect);
RecursiveLocateRect(lpData, wBytesPerLine, y, x-1, num, faceRect);
RecursiveLocateRect(lpData, wBytesPerLine, y, x+1, num, faceRect);
}
}
void CFaceDetectionDoc::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 =i*wBytesPerLine + j*3;
cr = *(lpYcc + lOffset +1);
cb = *(lpYcc + lOffset +2);
*(lpRgb + lOffset++) = cr;
*(lpRgb + lOffset++) = cr;
*(lpRgb + lOffset++) = cr;
}
}
void CFaceDetectionDoc::Crmap()
{
LPBYTE lpRB;
LPBITMAPINFOHEADER lpbi;
lpbi = (LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL) m_hDIB);//讀取頭文件
lLineBytesMulspec = WIDTHBYTES((lpbi->biWidth)*24);
::GlobalUnlock((HGLOBAL) m_hDIB);
int width,height;
LPBYTE lpData;
long wBytesPerLine;
LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);
// 獲取DIB寬度
width= (int) ::DIBWidth(lpDIB);
// 獲取DIB高度
height= (int) ::DIBHeight(lpDIB);
//得到圖片每行的象素所占字節個數
wBytesPerLine = lLineBytesMulspec;
lpRB = new BYTE[wBytesPerLine * height];
RgbtoYcb(m_hDIB,lpRB);
lpData = (unsigned char*)::FindDIBBits(lpDIB);
EyeMapR(lpData,lpRB,wBytesPerLine,CRect(0,0,width-1,height-1));
::GlobalUnlock((HGLOBAL) m_hDIB);
}
void CFaceDetectionDoc::EyeMapC(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++)
{
//得到Cr,Cb數值
lOffset = i*wBytesPerLine + j*3;
cr = *(lpYcc + lOffset +1);
cb = *(lpYcc + lOffset +2);
//標志
bool lab;
//判斷Cb分量的數值,并修改標志
int cmap = cb -120;//116 ;
if(cmap >-1 && cmap <4)
lab = true;
else
lab = false;
//判斷Cr分量的數值,并修改標志
cmap = cr- 143;//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 CFaceDetectionDoc::EyeMappingC()//調用EyeMapC函數進行眼睛的色度匹配
{
LPBYTE lpYcc2;
LPBITMAPINFOHEADER lpbi;
lpbi = (LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL) m_hDIB);//讀取頭文件
lLineBytesMulspec = WIDTHBYTES((lpbi->biWidth)*24);
::GlobalUnlock((HGLOBAL) m_hDIB);
int width,height;
LPBYTE lpData;
long wBytesPerLine;
LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);
// 獲取DIB寬度
width= (int) ::DIBWidth(lpDIB);
// 獲取DIB高度
height= (int) ::DIBHeight(lpDIB);
//得到圖片每行的象素所占字節個數
wBytesPerLine = lLineBytesMulspec;
lpYcc2 = new BYTE[wBytesPerLine * height];
RgbtoYcb( m_hDIBtemp,lpYcc2);//轉化為YCC空間
lpData = (unsigned char*)::FindDIBBits(lpDIB);
//memcpy(lpData,gDib.YcctoRgb(lpYcc,gwBytesPerLine,gheight,gwidth),gwBytesPerLine*gheight);
EyeMapC(lpData,lpYcc2,wBytesPerLine,CRect(0,0,width-1,height-1));
for(int i=0; i<height; i++)
for (int j=0; j<width; j++)
{
long lOffset;
lOffset = i*wBytesPerLine + j*3;
if(*(lpData + lOffset) == 255)
{
emymapc[i][j] = true;
}
}
::GlobalUnlock((HGLOBAL) m_hDIB);
}
void CFaceDetectionDoc::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 = i*wBytesPerLine + j*3;
//得到rgb值
b = *(lpRgb + lOffset);
g = *(lpRgb + lOffset+1);
r = *(lpRgb + lOffset+2);
//計算得到灰度
gray = (r*10+g*30+b*60)/100;
//根據眼睛的亮度區域來設定圖象的數值
if(/*100*/120<gray && /*125*/160>gray)
gray =255;
else
gray = 0;
*(lpRgb + lOffset++) = gray;
*(lpRgb + lOffset++) = gray;
*(lpRgb + lOffset++) = gray;
}
}
void CFaceDetectionDoc::EyeMappingL()//調用EyeMapC函數進行眼睛的色度匹配
{
LPBYTE lpYcc2;
LPBYTE lpDataR,lpDataD;
LPBITMAPINFOHEADER lpbi;
lpbi = (LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL) m_hDIB);//讀取頭文件
lLineBytesMulspec = WIDTHBYTES((lpbi->biWidth)*24);
::GlobalUnlock((HGLOBAL) m_hDIB);
int width,height;
LPBYTE lpData;
long wBytesPerLine;
LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);
LPSTR lpDIBtemp = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIBtemp);
// 獲取DIB寬度
width= (int) ::DIBWidth(lpDIB);
// 獲取DIB高度
height= (int) ::DIBHeight(lpDIB);
//得到圖片每行的象素所占字節個數
wBytesPerLine = lLineBytesMulspec;
lpYcc2 = new BYTE[wBytesPerLine * height];
lpDataR = (unsigned char*)::FindDIBBits(lpDIBtemp);
RgbtoYcb(m_hDIBtemp,lpYcc2);
lpDataD = (unsigned char*)::FindDIBBits(lpDIB);
memcpy(lpDataD,lpDataR,wBytesPerLine*height);
EyeMapL(lpDataD,wBytesPerLine, CRect(0,0,width-1,height-1));
for (int i=0; i<height; i++)
for (int j=0; j<width; j++)
{
long lOffset;
lOffset = i*wBytesPerLine + j*3;
if(*(lpDataD + lOffset) == 255)
{
emymapl[i][j] = true;
}
}
::GlobalUnlock((HGLOBAL) m_hDIB);
::GlobalUnlock((HGLOBAL) m_hDIBtemp);
}
void CFaceDetectionDoc::Eyemap()
{
LPBITMAPINFOHEADER lpbi;
lpbi = (LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL) m_hDIB);//讀取頭文件
lLineBytesMulspec = WIDTHBYTES((lpbi->biWidth)*24);
::GlobalUnlock((HGLOBAL) m_hDIB);
int width,height;
long wBytesPerLine;
LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);
// 獲取DIB寬度
width= (int) ::DIBWidth(lpDIB);
// 獲取DIB高度
height= (int) ::DIBHeight(lpDIB);
//得到圖片每行的象素所占字節個數
wBytesPerLine = lLineBytesMulspec;
LPBYTE lpData;
long lOffset;
lpData = (unsigned char*)::FindDIBBits(lpDIB);
for (int i=0; i<height; i++)
for (int j=0; j<width; j++)
{
lOffset = i*wBytesPerLine + j*3;
if( emymapc[i][j] && emymapl[i][j])
{
*(lpData + lOffset++) = 255;
*(lpData + lOffset++) = 255;
*(lpData + lOffset++) = 255;
}
else
{
*(lpData + lOffset++) = 0;
*(lpData + lOffset++) = 0;
*(lpData + lOffset++) = 0;
}
}
}
void CFaceDetectionDoc::DeleteFasleEye(CRect facelocation)
{
LPBITMAPINFOHEADER lpbi;
lpbi = (LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL) m_hDIB);//讀取頭文件
lLineBytesMulspec = WIDTHBYTES((lpbi->biWidth)*24);
::GlobalUnlock((HGLOBAL) m_hDIB);
int width,height;
long wBytesPerLine;
LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);
// 獲取DIB寬度
width= (int) ::DIBWidth(lpDIB);
// 獲取DIB高度
height= (int) ::DIBHeight(lpDIB);
//得到圖片每行的象素所占字節個數
wBytesPerLine = lLineBytesMulspec;
LPBYTE lpData;
long lOffset;
lpData = (unsigned char*)::FindDIBBits(lpDIB);
for (int i=0; i<height; i++)
for (int j=0; j<width; j++)
{
lOffset = i*wBytesPerLine + j*3;
if(*(lpData + lOffset) == 255)
{
if(i<(facelocation.bottom+facelocation.top)/2)
{
*(lpData + lOffset++) = 0;
*(lpData + lOffset++) = 0;
*(lpData + lOffset++) = 0;
}
}
}
::GlobalUnlock((HGLOBAL) m_hDIB);
}
void CFaceDetectionDoc::EyeCenter(CPoint &eye1, CPoint &eye2)
{
LPBITMAPINFOHEADER lpbi;
lpbi = (LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL) m_hDIB);//讀取頭文件
lLineBytesMulspec = WIDTHBYTES((lpbi->biWidth)*24);
::GlobalUnlock((HGLOBAL) m_hDIB);
int width,height;
long wBytesPerLine;
LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);
// 獲取DIB寬度
width= (int) ::DIBWidth(lpDIB);
// 獲取DIB高度
height= (int) ::DIBHeight(lpDIB);
//得到圖片每行的象素所占字節個數
wBytesPerLine = lLineBytesMulspec;
LPBYTE lpData;
long lOffset;
lpData = (unsigned char*)::FindDIBBits(lpDIB);
int pixelnum =0;
int num =0;
CRect faceLocation(0,0,width-1,height-1);
//考察人臉區域
for(int i=faceLocation.top; i<faceLocation.bottom; i++)
for (int j=faceLocation.left; j<faceLocation.right; j++)
{
lOffset = i*wBytesPerLine + j*3;
//白色點
if(*(lpData + lOffset) == 255)
//遞歸統計象素并修改象素值
RecursiveCal(lpData,i,j,wBytesPerLine,pixelnum,++num);
}
//初始化眼睛的坐標
eye1.x =0;
eye1.y =0;
eye2.x =0;
eye2.y =0;
//初始化象素點個數
int eye1count=0;
int eye2count =0;
for (i=faceLocation.top; i<faceLocation.bottom; i++)
for (int j=faceLocation.left; j<faceLocation.right; j++)
{
lOffset = i*wBytesPerLine + j*3;
//如果象素點的數值為1
if(*(lpData + lOffset) == 1)
{
//眼睛1的橫坐標和縱坐標加上當前點的坐標值
eye1.x +=j;
eye1.y +=i;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -