zoukankan      html  css  js  c++  java
  • 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 <opencv2opencv.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
    " ); 
            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
    ", 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函数来实现人脸的检测。

  • 相关阅读:
    select,epoll,poll比较(网络资源总结)
    c++(重载、覆盖、隐藏)
    TCP状态转换图
    TCP心跳 | TCP keepAlive
    回车、换行、空格的ASCII码值—(附ASCII码表)
    C++ dlopen mini HOWTO 一篇非常好的介绍
    shell十三问
    linux IPC消息队列 的内核限制
    C++ string 类常用函数
    const用法的解惑
  • 原文地址:https://www.cnblogs.com/betterwgo/p/6561446.html
Copyright © 2011-2022 走看看