人脸识别、人脸比较、图像转换

// peizhi.cpp : Defines the entry point for the console application.

//

 

#include "stdafx.h"

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <assert.h>

#include <math.h>

#include <float.h>

#include <limits.h>

#include <time.h>

#include <ctype.h>

#include "cv.h"

#include "highgui.h"

#include "cvcam.h"

#include "cxcore.h"

 

static CvMemStorage* storage=0;

static CvHaarClassifierCascade* cascade = 0;

void detect_and_draw( IplImage* image );

void cam_move(double length,double f);

void change_focus(double length,double f);

IplImage *CvRectToImage(IplImage *img);//根据已知的矩形获取图像

IplImage *ThreeToOne(IplImage *img); //将三通道彩色图像转换成单通道灰度图像

IplImage *GetExampleImage(char *filename);//获得用于对比的目标图像的函数

int JudgeResult();

void compare_picture(IplImage *example,IplImage *object);

static  double Width=0,Height=0;//表示摄像头获得图像的大小

IplImage *face=0;//用于指向检测到的人脸

#define MAX1  0.5

#define MIN1   0.2

#define  SIZE    0.3//人脸占整个图片的比例调节在0.2-0.5的范围外时(以高度计算),统一修改成比例0.3,

const char *cascade_name ="C://Program Files//OpenCV//data//haarcascades//haarcascade_frontalface_alt2.xml";

CvRect info=cvRect(50,50,50,50); //包含了检测到的图像的坐标信息

int _tmain(int argc, _TCHAR* argv[])

{

storage = cvCreateMemStorage(0);

 char filename[20]="01.bmp";

     IplImage *img=GetExampleImage(filename);//目标图像

cvNamedWindow("ex",1);

if(!img)

{

printf("出错/n");

exit(0);

}

cvShowImage("ex",img);

    CvCapture* capture =cvCaptureFromCAM(0);

    IplImage *frame, *frame_copy = 0;

    cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );

    if( !cascade )

    {

         printf("无法找到文件/n");

        return -1;

    }

else

printf("找到了相应的文件/n");

    cvNamedWindow( "result", 1 );

cvNamedWindow("face",1);

        for(;;)

        {

            if(!cvGrabFrame(capture))

{

                printf("无法打开摄像头/n");

break;

}

            frame = cvRetrieveFrame( capture );

Width=(double)frame->width;

Height=(double)frame->height;

            if(!frame )

                break;

            if( !frame_copy )

                frame_copy = cvCreateImage( cvSize(frame->width,frame->height),

                                            IPL_DEPTH_8U, frame->nChannels );

            if( frame->origin == IPL_ORIGIN_TL )

                cvCopy( frame, frame_copy, 0 );

            else

             cvFlip( frame, frame_copy, 0 );

            detect_and_draw( frame_copy );

face=CvRectToImage(frame);

//cvResize(face,img,2);

cvShowImage("face",face);

compare_picture(img,face);

if(JudgeResult()==1)

printf("识别成功/n");

//change_focus(2,0.0036);

   // cam_move(2.0,0.0036);

//printf("%d",info->x);

             cvWaitKey(100);

        }

        cvReleaseImage( &frame_copy );

cvReleaseImage(&face);

        cvReleaseCapture( &capture );

    cvWaitKey(0);

    cvDestroyWindow("result");

cvDestroyWindow("face");

cvDestroyWindow("ex");

    return 0;

}

 

void detect_and_draw( IplImage* img )

{

    static CvScalar colors[] = 

    {

        {{0,0,255}},

        {{0,128,255}},

        {{0,255,255}},

        {{0,255,0}},

        {{255,128,0}},

        {{255,255,0}},

        {{255,0,0}},

        {{255,0,255}}

    };

    double scale = 1.3;

    IplImage* gray = cvCreateImage( cvSize(img->width,img->height), 8, 1 );

    IplImage* small_img = cvCreateImage( cvSize( cvRound (img->width/scale),cvRound (img->height/scale)),8, 1 );

    int i;

    cvCvtColor( img, gray, CV_BGR2GRAY );

    cvResize( gray, small_img, CV_INTER_LINEAR );

    cvEqualizeHist( small_img, small_img );

    cvClearMemStorage( storage );

    if( cascade )

    {

        //double t = (double)cvGetTickCount();

        CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,1.1, 2, 0,cvSize(30, 30) );

        for( i = 0; i < (faces ? faces->total : 0); i++ )

        {

            CvRect* r = (CvRect*)cvGetSeqElem( faces, i );

info = *r;

            CvPoint center;

            int radius;

            center.x = cvRound((r->x + r->width*0.5)*scale);

            center.y = cvRound((r->y + r->height*0.5)*scale);

            radius = cvRound((r->width + r->height)*0.25*scale);

            cvCircle( img, center, radius, colors[i%8], 3, 8, 0 );

        }

    }

    cvShowImage( "result", img );

    cvReleaseImage( &gray );

    cvReleaseImage( &small_img );

}

void cam_move(double length,double f)//length表示摄像机到人脸的距离,f是焦距,以米为单位,控制摄像头的移动

{

double center_h=Height/2;

double center_w=Width/2;//图片中心的坐标

double  face_w=((double)info.x+(double)info.x+(double)info.width)/2;

double  face_h=((double)info.y+(double)info.y+(double)info.height)/2;//检测到的人脸中心坐标

/*摄像头的ccd规格尺寸是 4.8mm 3.6mm,利用公式W/w=length/f进行计算*/

double move_x=(length/f)*(0.0048)*((face_w-center_w)/Width);//实际物体的偏移量

double  move_y=(length/f)*(0.0036)*((face_h-center_h)/Height);//实际物体的偏移量

double angle_x=0,angle_y=0;

if(move_x>=0) //右偏

{

angle_x=atan(move_x/length)*180/3.14159;//使用反三角函数求角度

//右移angle_x

}

else

{

angle_x=atan(move_x*(-1)/length)*180/3.14159;

//左偏转角度angle_x)

}

if(move_y>=0)

{

angle_y=atan(move_y/length)*180/3.14159;

//下移转角angle_y

}

else

{

angle_y=atan(move_y*(-1)/length)*180/3.14159;

//上移angle_y

}

// printf("移动的角度%lf/t%lf/n",angle_x,angle_y);

}

void change_focus(double length,double f)//调焦函数

{

     if(info.height/Height>=MIN1&&info.height/Height<=MAX1)

return;  //不需要调节

double pre_w=(length/f)*0.0048;//调焦前的图片对应的实际宽度

double pre_h=(length/f)*0.0036;//实际高度

double times=(info.height/Height)/SIZE;//实际比例与所需调节比例的倍数关系

f=f/times;//修改焦距

//控制摄像头修改焦距

//printf("焦距是:%lf/n",f);

 

}

IplImage *ThreeToOne(IplImage *img)//多通道与单通道转换

{

IplImage *dst=cvCreateImage(cvGetSize(img),img->depth,1);

cvCvtColor(img,dst,CV_BGR2GRAY);

return dst;

}

int HistogramBins = 256;

float HistogramRange1[2]={0,255};

float *HistogramRange[1]={&HistogramRange1[0]};

double compare_result[2]={0};//用于存储两个图像的比较结果

/*注意,该函数比较的必须是单通道灰度图像,否则需要转换*/

void compare_picture(IplImage *example,IplImage *object)//比较两个图像的相似度

{

example=ThreeToOne(example);

object=ThreeToOne(object);

//cvResize(example,object);

CvHistogram *Histogram1=cvCreateHist(1,&HistogramBins,CV_HIST_SPARSE,HistogramRange);//创建直方图

CvHistogram *Histogram2=cvCreateHist(1,&HistogramBins,CV_HIST_SPARSE,HistogramRange);

cvCalcHist(&example,Histogram1);//计算图像的直方图

cvCalcHist(&object,Histogram2);

cvNormalizeHist(Histogram1,1);//归一化直方图

cvNormalizeHist(Histogram2,1);

double  chisqr=cvCompareHist(Histogram1,Histogram2,CV_COMP_CHISQR);//卡方

double  bha=cvCompareHist(Histogram1,Histogram2,CV_COMP_BHATTACHARYYA);//Bhattacharyya

compare_result[0]=chisqr;//存储卡方,卡方越小越相似

compare_result[1]=bha;//存储Bhattacharyya,越小越相似

}

#define  CHISQR  0.25  //当chisqr<=0.15时判断为相同

#define   BHA    0.25  //当bha<=0.15时判断相同

int JudgeResult()//根据比较结果判断是否相同

{

//printf("%f/t%f/n",compare_result[0],compare_result[1]);

if(compare_result[0]<=CHISQR&&compare_result[1]<=BHA)

return 1;  //表示两张图片结果相同

else

return 0;  //表示两张图片结果不相同

}

#define SCALE 1.2

IplImage *CvRectToImage(IplImage *img)//通过原图像和所得矩阵,获得检测到人脸的图像

{

CvRect info_copy=info;

info_copy.width*=SCALE;

info_copy.height*=SCALE;

info_copy.x*=SCALE;

info_copy.y*=SCALE;

cvSetImageROI(img, info_copy);

    IplImage *smallface=cvCreateImage( cvSize(info_copy.width,info_copy.height), 8, 3 );

    cvCopy(img,smallface);

    cvResetImageROI(img);

cvConvertImage(smallface,smallface,CV_CVTIMG_FLIP );

return  smallface;

}

IplImage *GetExampleImage(char *filename)

{

IplImage *img=cvLoadImage(filename,-1);

double scale =SCALE;

IplImage* gray = cvCreateImage( cvSize(img->width,img->height), 8, 1 );

    IplImage* small_img = cvCreateImage( cvSize( cvRound (img->width/scale),cvRound (img->height/scale)),8, 1 );

cvCvtColor( img, gray, CV_BGR2GRAY );

 

    cvResize(gray, small_img, CV_INTER_LINEAR );

    cvEqualizeHist( small_img, small_img );

    cvClearMemStorage( storage );

cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );

    if( cascade )

    {

CvRect* r=0;

        CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,1.1, 2, 0,cvSize(30, 30) );

for(int i = 0; i < (faces ? faces->total : 0); i++ )

         r = (CvRect*)cvGetSeqElem( faces, i);

if(r==0)

return 0;

    r->width*=SCALE;

   r->height*=SCALE;

   r->x*=SCALE;

   r->y*=SCALE;

cvSetImageROI(img, *r);

     IplImage *smallface=cvCreateImage( cvSize(r->width,r->height), 8, 3 );

     cvCopy(img,smallface);

    cvResetImageROI(img);

return  smallface;

}

else

return 0;

}

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值