📄 mainfrm.cpp
字号:
CapParms.fMakeUserHitOKToCapture=!CapParms.fMCIControl;
CapParms.wPercentDropForError=100;
CapParms.wNumVideoRequested=5;
CapParms.wChunkGranularity=0;
CapParms.fYield=TRUE;
CapParms.fCaptureAudio=FALSE;//don't capture video
CapParms.vKeyAbort=0;
CapParms.fAbortLeftMouse=CapParms.fAbortRightMouse=FALSE;
CapParms.dwRequestMicroSecPerFrame=100000/10;
// AfxMessageBox("采集参数设置完毕",MB_OK,NULL);
capSetCallbackOnYield(m_hWndCap,NULL);
//set the new setup info
capCaptureSetSetup(m_hWndCap,&CapParms,sizeof(CAPTUREPARMS));
// AfxMessageBox("开始采集",MB_OK,NULL);
capCaptureSequenceNoFile(m_hWndCap);
//capDlgVideoDisplay(m_hWndCap);
}
else
{
capCaptureAbort(m_hWndCap);
m_iscapture=FALSE;
AfxMessageBox("开始检测人脸吧!",MB_OK,NULL);
m_enable_skindect=TRUE;
}
}
//---------------------------------------------------------
//得到每行像素所占用的字节数;
DWORD CMainFrame::BytePerLine(LPBITMAPINFOHEADER lpbi)
{
DWORD i;
// i=(lpbi->biWidth)*24; //lpbi文件信息头指针
i=(lpbi->biWidth)*3;
return i;
}
//得到像素点数据在整个数据区中的偏移;
long CMainFrame::PixelOffset(int i,int j,DWORD wBytesPerLine)
{
long Offset;
Offset=i*wBytesPerLine+j*3;//计算偏移
return Offset;
}
//-------------------------------------------------------------------------
//视频帧数据信息的拷贝函数
void CMainFrame::RGB_Copydata()//把RGB空间的视频帧数据信息拷贝到m_rgb_buffer[6000000]中;
{
unsigned char * lpb=m_rgb_buffer;
LPBITMAPINFOHEADER lpbi_rgb;
lpbi_rgb=&m_rgb_bitmapheader; //lpbi_rgb是指向"存放'以RGB色彩空间表达的数据信息'的信息头信息"的指针;
//拷贝视频帧的信息头;
CMainFrame * p_CMainFrame=(CMainFrame*)AfxGetMainWnd();
lpbi_rgb->biSize=p_CMainFrame->m_dibinfo.bitmapinfoheader.biSize;
lpbi_rgb->biWidth=p_CMainFrame->m_dibinfo.bitmapinfoheader.biWidth;
lpbi_rgb->biHeight=p_CMainFrame->m_dibinfo.bitmapinfoheader.biHeight;
lpbi_rgb->biPlanes=p_CMainFrame->m_dibinfo.bitmapinfoheader.biPlanes;
lpbi_rgb->biBitCount=p_CMainFrame->m_dibinfo.bitmapinfoheader.biBitCount;
lpbi_rgb->biCompression=p_CMainFrame->m_dibinfo.bitmapinfoheader.biCompression;
lpbi_rgb->biSizeImage=p_CMainFrame->m_dibinfo.bitmapinfoheader.biSizeImage;
lpbi_rgb->biXPelsPerMeter=p_CMainFrame->m_dibinfo.bitmapinfoheader.biXPelsPerMeter;
lpbi_rgb->biYPelsPerMeter=p_CMainFrame->m_dibinfo.bitmapinfoheader.biYPelsPerMeter;
lpbi_rgb->biClrUsed=p_CMainFrame->m_dibinfo.bitmapinfoheader.biClrUsed;
lpbi_rgb->biClrImportant=p_CMainFrame->m_dibinfo.bitmapinfoheader.biClrImportant;
//拷贝视频帧的数据信息;
memcpy(lpb,((CMainFrame*)AfxGetMainWnd())->m_dibinfo.buffer
+((CMainFrame*)AfxGetMainWnd())->m_dibinfo.VideoFormatSize,
lpbi_rgb->biSizeImage);
}
void CMainFrame::RGB_Skin_detection()//RGB空间的肤色识别公式
{
int i,j;
long Offset;
unsigned char r,g,b;
unsigned char * lpb=m_rgb_buffer;
LPBITMAPINFOHEADER lpbi;
lpbi=&m_rgb_bitmapheader;
DWORD wBytesPerLine=BytePerLine(lpbi);//得到每行像素所占用的字节数;
for(i=0;i<lpbi->biHeight;i++)
{
for(j=0;j<lpbi->biWidth;j++)
{
Offset=PixelOffset(i,j,wBytesPerLine); //得到像素点数据在整个数据区中的偏移;
b=*(lpb+Offset);
g=*(lpb+Offset+1);
r=*(lpb+Offset+2);
if((r>95)&&(g>40)&&(b>20))
{
unsigned char temp=bgr_max(b,g,r)-bgr_min(b,g,r);
if((temp>15)&&(abs(r-g))&&(r>g)&&(r>b))
{
*(lpb+Offset)=255;
*(lpb+Offset+1)=255;
*(lpb+Offset+2)=255;
// AfxMessageBox("设置为白色!",MB_OK,0);
}
else
{
*(lpb+Offset)=0;
*(lpb+Offset+1)=0;
*(lpb+Offset+2)=0;
// AfxMessageBox("设置为黑色1!",MB_OK,0);
continue;
}
}
else
{
*(lpb+Offset)=0;
*(lpb+Offset+1)=0;
*(lpb+Offset+2)=0;
// AfxMessageBox("设置为黑色2!",MB_OK,0);
}
}
}
}
//-------------------------------------------------------------------------
//rgb色彩空间的像素统计
void CMainFrame::rgb_histogram()
{
int i,j,n;
long Offset;
unsigned char b,g,r;
unsigned char * lpb=m_rgb_buffer;
LPBITMAPINFOHEADER lpbi_rgb;
lpbi_rgb=&m_rgb_bitmapheader;
for(n=0;n<256;n++)
{
m_bhist[n]=0;
m_ghist[n]=0;
m_rhist[n]=0;
}
DWORD wBytesPerLine=BytePerLine(lpbi_rgb);//得到每行像素所占用的字节数;
for(i=0;i<lpbi_rgb->biHeight;i++)
{
for(j=0;j<lpbi_rgb->biWidth;j++)
{
Offset=PixelOffset(i,j,wBytesPerLine); //得到像素点数据在整个数据区中的偏移;
b=*(lpb+Offset);
m_bhist[b]++;
g=*(lpb+Offset+1);
m_ghist[g]++;
r=*(lpb+Offset+2);
m_rhist[r]++;
}
}
}
//-------------------------------------------------------------------------
//色彩空间转换函数(RGBàYCrCb)
void CMainFrame::RGBToYCrCb()
{
int i,j;
long Offset;
unsigned char b,g,r,y,cr,cb;
unsigned char * lpb=m_ycc_buffer;
LPBITMAPINFOHEADER lpbi_ycc;
lpbi_ycc=&m_bitmapheader; //lpbi_ycc是指向"存放'以YCrCb色彩空间表达的数据信息'的信息头信息"的指针;
//拷贝视频帧的信息头;
CMainFrame * p_CMainFrame=(CMainFrame*)AfxGetMainWnd();
lpbi_ycc->biSize=p_CMainFrame->m_dibinfo.bitmapinfoheader.biSize;
lpbi_ycc->biWidth=p_CMainFrame->m_dibinfo.bitmapinfoheader.biWidth;
lpbi_ycc->biHeight=p_CMainFrame->m_dibinfo.bitmapinfoheader.biHeight;
lpbi_ycc->biPlanes=p_CMainFrame->m_dibinfo.bitmapinfoheader.biPlanes;
lpbi_ycc->biBitCount=p_CMainFrame->m_dibinfo.bitmapinfoheader.biBitCount;
lpbi_ycc->biCompression=p_CMainFrame->m_dibinfo.bitmapinfoheader.biCompression;
lpbi_ycc->biSizeImage=p_CMainFrame->m_dibinfo.bitmapinfoheader.biSizeImage;
lpbi_ycc->biXPelsPerMeter=p_CMainFrame->m_dibinfo.bitmapinfoheader.biXPelsPerMeter;
lpbi_ycc->biYPelsPerMeter=p_CMainFrame->m_dibinfo.bitmapinfoheader.biYPelsPerMeter;
lpbi_ycc->biClrUsed=p_CMainFrame->m_dibinfo.bitmapinfoheader.biClrUsed;
lpbi_ycc->biClrImportant=p_CMainFrame->m_dibinfo.bitmapinfoheader.biClrImportant;
// memcpy(lpbi_ycc,&(((CMainFrame*)AfxGetMainWnd())->m_dibinfo.bitmapinfoheader),
// (unsigned int)( &(((CMainFrame*)AfxGetMainWnd())->m_dibinfo.bitmapinfoheader).biSize));
LPBYTE lp_rgb=((CMainFrame*)AfxGetMainWnd())->m_dibinfo.buffer+
((CMainFrame*)AfxGetMainWnd())->m_dibinfo.VideoFormatSize;
//lp_rgb表示的是RGB色彩空间中的视频帧图像数据的其始位置;
DWORD wBytesPerLine=BytePerLine(lpbi_ycc);//得到每行像素所占用的字节数;
for(i=0;i<lpbi_ycc->biHeight;i++)
{
for(j=0;j<lpbi_ycc->biWidth;j++)
{
Offset=PixelOffset(i,j,wBytesPerLine); //得到像素点数据在整个数据区中的偏移;
b=*(lp_rgb+Offset);
g=*(lp_rgb+Offset+1);
r=*(lp_rgb+Offset+2);
y=(299*r+587*g+114*b)/1000;
cr=r-y;
cb=b-y;
*(lpb+Offset)=y;
*(lpb+Offset+1)=cr;
*(lpb+Offset+2)=cb;
}
}
return;
}
//-------------------------------------------------------------------------
//ycc色彩空间的像素统计
void CMainFrame::ycc_histogram()
{
int i,j,n;
long Offset;
unsigned char y,cr,cb;
unsigned char * lpb=m_ycc_buffer;
LPBITMAPINFOHEADER lpbi_ycc;
lpbi_ycc=&m_bitmapheader; //lpbi_ycc是指向"存放'以YCrCb色彩空间表达的数据信息'的信息头信息"的指针;
for(n=0;n<256;n++)
{
m_yhist[n]=0;
m_crhist[n]=0;
m_cbhist[n]=0;
}
DWORD wBytesPerLine=BytePerLine(lpbi_ycc);//得到每行像素所占用的字节数;
for(i=0;i<lpbi_ycc->biHeight;i++)
{
for(j=0;j<lpbi_ycc->biWidth;j++)
{
Offset=PixelOffset(i,j,wBytesPerLine); //得到像素点数据在整个数据区中的偏移;
y=*(lpb+Offset);
++m_yhist[y];
cr=*(lpb+Offset+1);
++m_crhist[cr];
cb=*(lpb+Offset+2);
++m_cbhist[cb];
/*
if(((cr>=0)&&(cr<=43))||((cb>=0)&&(cb<=43)))
{
*(lpb+Offset)=255;
*(lpb+Offset+1)=255;
*(lpb+Offset+2)=255;
}
else
{
*(lpb+Offset)=0;
*(lpb+Offset+1)=0;
*(lpb+Offset+2)=0;
}*/
}
}
}
//肤色识别函数;
void CMainFrame::Skin_detection()
{
const double pi=3.14;
int i,j;
long Offset;
unsigned char cr,cb;
unsigned char * lpb=m_ycc_buffer;
LPBITMAPINFOHEADER lpbi_ycc;
lpbi_ycc=&m_bitmapheader;
//lpbi_ycc是指向"存放'以YCrCb色彩空间表达的数据信息'的信息头信息"的指针;
DWORD wBytesPerLine=BytePerLine(lpbi_ycc);
//得到每行像素所占用的字节数;
LPBYTE lp_rgb=((CMainFrame*)AfxGetMainWnd())->m_dibinfo.buffer+
((CMainFrame*)AfxGetMainWnd())->m_dibinfo.VideoFormatSize;
//lp_rgb表示的是RGB色彩空间中的视频帧图像数据的其始位置;
for(i=0;i<lpbi_ycc->biHeight;i++)
for(j=0;j<lpbi_ycc->biWidth;j++)
{
Offset= PixelOffset(i,j,wBytesPerLine);
//得到像素点数据在整个数据区中的偏移;
cr=*(lp_rgb+Offset+1);
cb=*(lp_rgb+Offset+2);
double c=(double)(cb/cr);
double temp1=1/tan(c);
unsigned char temp2=(unsigned char)sqrt((double)(cb*cb+cr*cr));
// if((temp1>=(0.2611*pi))&&(temp1<=(0.3111*pi))&&(temp2>=43)&&(temp2<=78))
// if((temp1>=(0.25*pi))&&(temp1<=(0.3611*pi))&&(temp2>=0)&&(temp2<=70))
if((c>=1.0)&&(c<=1.1)&&(cr<=180))//0.0到2.0之间
{
// AfxMessageBox("设置为白色!",MB_OK,0);
*(lpb+Offset)=255;
*(lpb+Offset+1)=255;
*(lpb+Offset+2)=255;
}
else
{
// AfxMessageBox("设置为黑色!",MB_OK,0);
*(lpb+Offset)=0;
*(lpb+Offset+1)=0;
*(lpb+Offset+2)=0;
}
}
/*
for(i=0;i<lpbi_ycc->biHeight;i++)
for(j=0;j<lpbi_ycc->biWidth;j++)
{
Offset= PixelOffset(i,j,wBytesPerLine);
unsigned char y=*(lpb+Offset);
unsigned char c1=*(lpb+Offset+1);
unsigned char c2=*(lpb+Offset+2);
}
*/
}
//膨胀操作;
void CMainFrame::dilation()
{
int i,j;
long Offset;
unsigned char * lpb;
lpb=m_ycc_buffer;
// lpb=m_rgb_buffer;
LPBITMAPINFOHEADER lpbi;
// lpbi=&m_bitmapheader;
//lpbi_ycc是指向"存放'以YCrCb色彩空间表达的数据信息'的信息头信息"的指针;
lpbi=&m_rgb_bitmapheader;
DWORD wBytesPerLine=BytePerLine(lpbi);//得到每行像素所占用的字节数;
for(i=1;i<(lpbi->biHeight-1);i++)
for(j=1;j<(lpbi->biWidth-1);j++)
{
Offset= PixelOffset(i,j,wBytesPerLine); //得到像素点数据在整个数据区中的偏移;
if(*(lpb+Offset)==0)
{
//考察当前点正下方的点;
Offset= PixelOffset(i+1,j,wBytesPerLine);
if(*(lpb+Offset)==255)
{
//如果是白色,把当前点设置成白色,返回;
Offset= PixelOffset(i,j,wBytesPerLine);
*(lpb+Offset)=255;
*(lpb+Offset+1)=255;
*(lpb+Offset+2)=255;
continue;
}
//考察当前点正上方的点;
Offset= PixelOffset(i-1,j,wBytesPerLine);
if(*(lpb+Offset)==255)
{
//如果是白色,把当前点设置成白色,返回;
Offset= PixelOffset(i,j,wBytesPerLine);
*(lpb+Offset)=255;
*(lpb+Offset+1)=255;
*(lpb+Offset+2)=255;
continue;
}
//考察当前点正右方的点;
Offset= PixelOffset(i,j+1,wBytesPerLine);
if(*(lpb+Offset)==255)
{
Offset= PixelOffset(i,j,wBytesPerLine);
*(lpb+Offset)=255;
*(lpb+Offset+1)=255;
*(lpb+Offset+2)=255;
continue;
}
//考察当前点正左方的点;
Offset= PixelOffset(i,j-1,wBytesPerLine);
if(*(lpb+Offset)==255)
{
Offset= PixelOffset(i,j,wBytesPerLine);
*(lpb+Offset)=255;
*(lpb+Offset+1)=255;
*(lpb+Offset+2)=255;
continue;
}
}
}
}
//腐蚀操作;
void CMainFrame::erosion()
{
int i,j;
long Offset;
unsigned char * lpb;
// lpb=m_ycc_buffer;
lpb=m_rgb_buffer;
LPBITMAPINFOHEADER lpbi;
// lpbi_ycc=&m_bitmapheader;
//lpbi_ycc是指向"存放'以YCrCb色彩空间表达的数据信息'的信息头信息"的指针;
lpbi=&m_rgb_bitmapheader;
DWORD wBytesPerLine=BytePerLine(lpbi);//得到每行像素所占用的字节数;
for(i=1;i<(lpbi->biHeight-1);i++)
for(j=1;j<(lpbi->biWidth-1);j++)
{
Offset= PixelOffset(i,j,wBytesPerLine); //得到像素点数据在整个数据区中的偏移;
if(*(lpb+Offset)==255)
{
//考察当前点正下方的点;
Offset= PixelOffset(i+1,j,wBytesPerLine);
if(*(lpb+Offset)==0)
{
//如果是黑色,把当前点设置成黑色,返回;
Offset=PixelOffset(i,j,wBytesPerLine);
*(lpb+Offset)=0;
*(lpb+Offset+1)=0;
*(lpb+Offset+2)=0;
continue;
}
//考察当前点正上方的点;
Offset= PixelOffset(i-1,j,wBytesPerLine);
if(*(lpb+Offset)==0)
{
Offset= PixelOffset(i,j,wBytesPerLine);
*(lpb+Offset)=0;
*(lpb+Offset+1)=0;
*(lpb+Offset+2)=0;
continue;
}
//考察当前点正右方的点;
Offset= PixelOffset(i,j+1,wBytesPerLine);
if(*(lpb+Offset)==0)
{
Offset= PixelOffset(i,j,wBytesPerLine);
*(lpb+Offset)=0;
*(lpb+Offset+1)=0;
*(lpb+Offset+2)=0;
continue;
}
//考察当前点正左方的点;
Offset= PixelOffset(i,j-1,wBytesPerLine);
if(*(lpb+Offset)==0)
{
Offset= PixelOffset(i,j,wBytesPerLine);
*(lpb+Offset)=0;
*(lpb+Offset+1)=0;
*(lpb+Offset+2)=0;
continue;
}
}
}
}
//去掉非人脸的区域,返回人脸的个数;
int CMainFrame::ErasionFalseArea()
{
int PixelNum[255];//记录连续区域的白色像素点个数
int i,j;
long Offset;
unsigned char * lpb;
lpb=m_ycc_buffer;
// lpb=m_rgb_buffer;
LPBITMAPINFOHEADER lpbi;
lpbi=&m_bitmapheader;
//lpbi_ycc是指向"存放'以YCrCb色彩空间表达的数据信息'的信息头信息"的指针;
// lpbi=&m_rgb_bitmapheader;
DWORD wBytesPerLine=BytePerLine(lpbi);//得到每行像素所占用的字节数;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -