cvSmooth函数 和 OpenCV自带的人脸检测

   记录cvSmooth函数的用法和 OpenCV自带的人脸检测。

(1)cvSmooth函数
void cvSmooth( const CvArr* src, CvArr* dst,int smoothtype=CV_GAUSSIAN,int param1, int param2, double param3, double param4 );
src:输入图像.
dst:输出图像.
smoothtype平滑方法
  CV_BLUR_NO_SCALE(简单不带尺度变换的模糊),对每个象素的 param1×param2 领域求和。如果邻域大小是变化的,可以事先利用函数 cvIntegral 计算积分图像。
   CV_BLUR (simple blur)- -对每个象素param1×param2邻域求和并做尺度变换 1/(param1×param2)。
   CV_GAUSSIAN(gaussian blur) - -对图像进行核大小为 param1×param2 的高斯卷积。
   CV_MEDIAN(median blur) - -对图像进行核大小为param1×param1 的中值滤波 (邻域是方的)。
   CV_BILATERAL(双向滤波) - -应用双向 3x3 滤波,彩色 sigma=param1,空间 sigma=param2.。

param1:平滑操作的第一个参数.
param2:平滑操作的第二个参数. 对于简单/非尺度变换的高斯模糊的情况,如果param2的值为零,则表示其被设定为param1。
param3
  对应高斯参数的 Gaussian sigma (标准差). 如果为零,则标准差由下面的核尺寸计算:
  sigma = (n/2 - 1)*0.3 + 0.8,
其中 n=param1 对应水平核,n=param2 对应垂直核.
  对小的卷积核 (3×3 to 7×7) 使用如上公式所示的标准 sigma 速度会快。如果 param3 不为零,而 param1 和 param2 为零,则核大小由sigma 计算 (以保证足够精确的操作)。

  没有缩放的图像平滑仅支持单通道图像,并且支持8位到16位的转换(与cvSobel和cvaplace相似)和32位浮点数到32位浮点数的变换格式。
  简单模糊和高斯模糊支持 1- 或 3-通道, 8-比特 和 32-比特 浮点图像。这两种方法可以(in-place)方式处理图像。
  中值和双向滤波工作于 1- 或 3-通道, 8-位图像,但是不能以 in-place 方式处理图像。

从别处抄来的核心代码:

//邻域平均滤波
cvSmooth(pImg,pImg,CV_BLUR,3,3,0,0);        //3x3
cvSmooth(pImg,pImg,CV_BLUR,5,5,0,0);        //5x5
//中值滤波 
cvSmooth(pImg,pImg,CV_MEDIAN,3,3,0,0);      //3x3
cvSmooth(pImg,pImg,CV_MEDIAN,5,5,0,0);      //5x5
//高斯滤波
cvSmooth(pImg,pImg,CV_GAUSSIAN,3,3,0,0);    //3x3
cvSmooth(pImg,pImg,CV_GAUSSIAN,5,5,0,0);    //5x5

我自己抄来的一个简单例子:

#include "stdafx.h"
#include <iostream>

#pragma comment(lib,"../OpenCV-2.4.8/lib/opencv_core248d.lib")
#pragma comment(lib,"../OpenCV-2.4.8/lib/opencv_highgui248d.lib")
#pragma comment(lib,"../OpenCV-2.4.8/lib/opencv_imgproc248d.lib")

#include "../OpenCV-2.4.8/include/highgui.h"
#include "../OpenCV-2.4.8/include/cv.h"

using namespace std;
using namespace cv;


int _tmain(int argc, char *argv[]) 
{
   IplImage* img = cvLoadImage("3.jpg") ;
   cvNamedWindow("DEMO-in") ;
   cvNamedWindow("DEMO-out") ;
   cvShowImage("DEMO-in",img) ;

   IplImage* out = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 3) ;

   cvSmooth(img, out, CV_MEDIAN, 3, 3) ;

   cvShowImage("DEMO-out", out);

   cvReleaseImage( &out ) ;

   cvWaitKey( 0 ) ;
   cvDestroyWindow("DEMO-in") ;
   cvDestroyWindow("DEMO-out") ;

   return 0;
}

(2)OpenCV自带的人脸检测
代码:

#include "stdafx.h"
#include <stdio.h> 
#include <stdlib.h> 
#include <assert.h> 
#include <math.h> 
#include <float.h> 
#include <limits.h> 
#include <time.h> 
#include <ctype.h>

#include <opencv2\opencv.hpp>
#include <iostream>
#include <string>
using namespace cv;
using namespace std;

#ifdef _EiC 
#define WIN32 
#endif

static CvMemStorage* storage = 0; 
static CvHaarClassifierCascade* cascade = 0;

void detect_and_draw( IplImage* image );

const char* cascade_name = 
"haarcascade_frontalface_alt.xml"; 
/*    "haarcascade_profileface.xml";*/

int main( int argc, char** argv ) 
{ 
    cascade_name = "haarcascade_frontalface_alt.xml"; 
    cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 ); 

    if( !cascade ) 
    { 
        fprintf( stderr, "ERROR: Could not load classifier cascade\n" ); 
        return -1; 
    } 
    storage = cvCreateMemStorage(0); 
    cvNamedWindow( "result", 0 ); 

    const char* filename = "2.jpg"; 
    IplImage* image = cvLoadImage( filename, 1 );

    if( image ) 
    { 
        detect_and_draw( image ); 
        cvWaitKey(0); 
        cvReleaseImage( &image );   
    }

    cvDestroyWindow("result"); 

    return 0; 
}


void detect_and_draw(IplImage* img ) 
{ 
    double scale=1.2; 
    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}} 
    };//Just some pretty colors to draw with

    //Image Preparation 
    // 
    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); //直方图均衡

    //Detect objects if any 
    // 
    cvClearMemStorage(storage); 
    double t = (double)cvGetTickCount(); 
    CvSeq* objects = cvHaarDetectObjects(small_img, 
        cascade, 
        storage, 
        1.1, 
        2, 
        0/*CV_HAAR_DO_CANNY_PRUNING*/, 
        cvSize(30,30));

    t = (double)cvGetTickCount() - t; 
    printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );

    //Loop through found objects and draw boxes around them 
    for(int i=0;i<(objects? objects->total:0);++i) 
    { 
        CvRect* r=(CvRect*)cvGetSeqElem(objects,i); 
        cvRectangle(img, cvPoint(r->x*scale,r->y*scale), cvPoint((r->x+r->width)*scale,(r->y+r->height)*scale), colors[i%8]); 
    } 
    for( int i = 0; i < (objects? objects->total : 0); i++ ) 
    { 
        CvRect* r = (CvRect*)cvGetSeqElem( objects, i ); 
        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); 
}

   这其实是个Haar特征的级联分类器,haarcascade_frontalface_alt.xml这个文件存的应该是正脸的Haar特征数据(猜测的,没有深究过,欢迎拍砖指正),这个文件是OpenCV自带的,使用的时候拷贝到自己的工程面即可。该数据被加载到static CvHaarClassifierCascade* cascade变量,由detect_and_draw(IplImage* img ) 函数里面的cvHaarDetectObjects函数来实现人脸的检测。

posted @ 2016-10-24 21:21  yeren2046  阅读(633)  评论(0编辑  收藏  举报