自学内容网 自学内容网

数字图像处理-人脸识别

人脸检测

代码

//FaceDetection.cpp

#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#include <iostream>

static CvHaarClassifierCascade* cascade = 0;
//CvHaarClassifierCascade是OpenCV库中的一个结构,用于表示Haar特征分类器级联,常用于物体检测,如人脸检测。
static CvMemStorage* storage = 0;
//CvMemStorage在OpenCV中用于管理算法运行过程中生成的数据结构的内存,它提供了灵活的内存管理机制,允许动态添加、删除节点,而不必关心底层内存的细节。
//CvMemStorage 是一个用于管理动态数据结构(如链表、树和其他计算机视觉算法中常见的数据结构)的内存存储器类。static CvMemStorage* storage = 0; 这行代码声明了一个指向CvMemStorage对象的静态指针,并将其初始化为0,这里的0通常被解释为NULL指针。
void detect_and_draw( IplImage* image );
const char* cascade_name ="haarcascade_frontalface_alt.xml";//人脸检测要用到的分类器

int main(int argc, char* argv[])
{
     //加载人脸检测所用的分类器
     cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );// 加载Haar分类器级联文件
     if( !cascade )
     {
        fprintf( stderr, "ERROR: Could not load classifier cascade\n" );
        return -1;
     }
     //动态存储结构,用来存储人脸在图像中的位置
     storage = cvCreateMemStorage(0);
 //storage指针通常会被分配一个CvMemStorage对象,例如通过调用cvCreateMemStorage()函数创建
     cvNamedWindow( "result", 1 );
     const char* filename = "Lena.jpg"; //待检测图像
     IplImage* image = cvLoadImage( filename, 1 );                     //加载图像
 //在OpenCV中用于从磁盘加载一幅图像到内存中
 //IplImage 是OpenCV 2.x版本中用于表示图像的结构体。它包含了图像的数据、尺寸、深度、通道数等信息。在OpenCV 3.x及以后的版本中,IplImage已被cv::Mat类所取代,后者提供了更多功能和更好的性能。

     //对加载的图像进行检测
     detect_and_draw( image );                                 
     cvWaitKey(0);//使用cvWaitKey函数等待用户按键,以便控制程序的流程或退出。
     cvReleaseImage( &image );
     cvDestroyWindow("result");
     return 0;
}
void detect_and_draw( IplImage* img )
{
    static CvScalar colors[] = 
    {
        {0,0,255},//纯蓝色(BGR格式)
        {0,128,255},//蓝绿色
        {0,255,255},//青色(Cyan)
        {0,255,0},//纯绿色
        {255,128,0},//橙黄色
        {255,255,0},//黄色
        {255,0,0},//纯红色
        {255,0,255}//洋红色(Magenta)
    };//这样的数组通常用于需要固定颜色集的情况,比如在图像中标记不同的对象或区域,或者在绘制图形时使用不同的颜色。
    double scale = 1.3;
    IplImage* gray = cvCreateImage( cvSize(img->width,img->height), 8, 1 );
//这行代码创建了一个与img具有相同宽度和高度的灰度图像gray
    IplImage* small_img = cvCreateImage( cvSize( cvRound (img->width/scale),
                         cvRound (img->height/scale)), 8, 1 );
//行代码创建了一个新的灰度图像small_img,它的宽度和高度分别是原图像img的宽度和高度除以scale后的值(四舍五入到最近的整数),每个像素是8位深度的灰度值
//这种缩放操作通常在图像预处理阶段进行,以减少计算量,加快算法执行速度,或适应不同的分辨率需求。在创建了缩小版的图像后,通常还需要对原图像进行某种形式的降采样或重采样,以填充新创建的较小图像的像素。这可以通过使用如cvResize函数完成。
    cvCvtColor( img, gray, CV_BGR2GRAY );//可以使用 cvCvtColor 函数将 img 转换为灰度图 gray
    cvResize( gray, small_img, CV_INTER_LINEAR );
//使用OpenCV库中的cvResize函数来改变图像的尺寸
//从gray图像创建一个缩小版的图像small_img,并且使用双线性插值方法来调整像素值,以确保图像缩小时看起来尽可能平滑和自然
    cvEqualizeHist( small_img, small_img );
//使用了OpenCV库中的cvEqualizeHist函数,该函数用于对灰度图像进行直方图均衡化
    cvClearMemStorage( storage );
//这行代码在OpenCV中用于清空一个CvMemStorage对象,storage是一个指向CvMemStorage类型的指针。CvMemStorage在OpenCV中用于动态数据结构的内存管理,比如链表、树、轮廓(CvSeq)等。当调用cvClearMemStorage函数时,它会释放CvMemStorage中所有已分配的块,但不会释放CvMemStorage自身所占用的内存。
    if( cascade )
    {
        //函数cvHaarDetectObjects检测图像中的目标,由OpenCV提供。
        CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage, 1.1, 2, 0, cvSize(30, 30) );
//penCV库中的cvHaarDetectObjects函数,该函数用于在图像中检测特定类型的对象,如人脸、眼睛等。这里,函数被用来检测small_img图像中的对象,使用的是Haar分类器级联cascade
//函数返回一个CvSeq类型的指针faces,它是一个序列,包含了所有检测到的对象的信息。每个对象的信息存储在一个CvRect结构中,CvRect包含了对象在图像中的位置和大小。在CvSeq中,你可以遍历这个序列来获取每个检测到的对象的坐标和大小,从而在图像中标注或进一步处理这些对象
        for( int i = 0; i < (faces ? faces->total : 0); i++ )
//for( int i = 0; i < (faces ? faces->total : 0); i++ ):这段代码首先检查faces指针是否非空,如果是,它将循环faces->total次,faces->total表示检测到的对象总数。如果faces为空,循环将不会执行,这是因为没有检测到任何对象。
        {
            CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
//这一行从CvSeq类型的faces序列中获取第i个元素,该元素是一个CvRect结构,包含了检测到的对象的位置和大小信息。
           
//计算中心点和半径
CvPoint center;
            int radius;
            center.x = cvRound((r->x + r->width*0.5)*scale);
//这两行代码计算检测到的对象的中心点坐标。r->x和r->y是对象的左上角坐标,r->width和r->height是对象的宽度和高度。scale变量通常用于补偿图像缩放,如果检测是在缩小的图像上进行的,那么需要将坐标和尺寸放大回原始图像的大小。
            center.y = cvRound((r->y + r->height*0.5)*scale);
            radius = cvRound((r->width + r->height)*0.25*scale);
//这行代码计算一个圆形标注的半径,通常是为了在图像中标注检测到的对象。这里,半径大约是对象宽度和高度平均值的四分之一,同样乘以scale进行缩放补偿。
            cvCircle( img, center, radius, colors[i%8], 3, 8, 0 );
//cvCircle( img, center, radius, colors[i%8], 3, 8, 0 );:这行代码使用cvCircle函数在原始图像img上绘制一个圆形,其中心点是center,半径是radius。颜色由colors数组的第i%8个元素决定,这里i%8保证了即使检测到的对象超过8个,颜色也会循环使用。3是线条的厚度,8表示抗锯齿(使用八邻域进行边缘平滑),0是连接方式,通常设置为0表示实线。
        }
//这段代码最终的效果是在原始图像img上为每一个检测到的对象绘制一个彩色的圆形标注,以直观地显示对象的位置和大致大小
    }
    cvShowImage( "result", img );
    cvReleaseImage( &gray );
    cvReleaseImage( &small_img );
}

【免费】数字图像处理-人脸识别,在VS2013中编译C++的.cpp源文件,调取opencv图形处理库,对lena照片进行人脸识别资源-CSDN文库


原文地址:https://blog.csdn.net/weixin_45794330/article/details/140589147

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!