这是我的Matlab大作业,实时人脸识别与追踪,主要运用了Matlab计算机视觉工具箱,维奥拉-琼斯算法,KTL算法。 直接运行代码会出现”错误使用webcam,尚未安装MATLAB Support Package for USB Webcams。打开Support Package Installer即可安装Webcam Support Package”这个错误。 [

](http://www.wjgbaby.com/wp-content/uploads/2018/01/18010403-300x21.png)
](http://www.wjgbaby.com/wp-content/uploads/2018/01/18010403-300x21.png)
这是因为我们实时的调取笔记本上的摄像头来进行每一帧图像的检测,所以需要用到webcam摄像头。 首先点击Support Package Installer安装Webcam Support Package,然后会有几个选项都选Next,最后有个Log In,登陆你的Matlab账号,然后直接运行就行了。 完整代码以及注释:

%使用KLT算法的3个前提假设:
%亮度恒定
%时间连续或者是运动是“小运动”
%空间一致,临近点有相似运动,保持相邻

clc,clear,close all;
%创建人脸检测对象,后面捕捉我英俊的脸庞,调用CascadeObjectDetector.m,使用了维奥拉-琼斯算法
faceDetector = vision.CascadeObjectDetector();

%使用点跟踪器进行视频稳定、摄像机运动估计和目标跟踪,它特别适合跟踪不改变形状的对象和显示视觉纹理的对象
%2表示对可能出现的错误进行双向限制,即使存在噪声也能正确显示
pointTracker = vision.PointTracker(‘MaxBidirectionalError’, 2);

%创建摄像头对象
cam = webcam();

%获取当前图像帧和其大小,如果一直执行,则每次返回最新的一帧
videoFrame = snapshot(cam);
frameSize = size(videoFrame);

%创建播放视频对象
videoPlayer = vision.VideoPlayer(‘Position’, [100 100 [frameSize(2), frameSize(1)]+30]);

runLoop = true; %默认开启循环
numPts = 0; %特征点初始为0
frameCount = 0; %帧数初始为0

%当runLoop为真并且帧数小于1000时,开启循环
while runLoop && frameCount < 1000

%获取当前图像帧,如果一直执行,则每次返回最新的一帧
videoFrame = snapshot(cam);
%处理成灰度图像
videoFrameGray = rgb2gray(videoFrame);
%每循环一次帧数就加1
frameCount = frameCount + 1;    

if numPts < 10
    %检测方式,bbox是1\*4向量,分布表示\[x y width height\],即边界框的左上角像素点坐标和边界框的size
    bbox = faceDetector.step(videoFrameGray);    

    if ~isempty(bbox)
        %在脸部区域识别特征点,指定被保留特征值的最小值,一般为1 
        points = detectMinEigenFeatures(videoFrameGray, 'ROI', bbox(1, :));       

        %用初始化框架的点的位置初始化踪迹
        xyPoints = points.Location;

        numPts = size(xyPoints,1);

        release(pointTracker);
        initialize(pointTracker, xyPoints, videoFrameGray);

        %复制点用于之前的点和现在的框架之间进行几何转换
        oldPoints = xyPoints;      

        %将框架转化为一系列的4个点\[x1 y1 x2 y2 x3 y3 x4 y4\] ,即使被识别的脸发生旋转也能够被看到 
        bboxPoints = bbox2points(bbox(1, :));    

        %reshape表示重新调整矩阵的行数、列数、维数
        bboxPolygon = reshape(bboxPoints', 1, \[\]);    

        % 在被检测的脸的周围插入边界框
        videoFrame = insertShape(videoFrame, 'Polygon', bboxPolygon, 'LineWidth', 3);

        % 显示被追随的点,在图像或视频中插入标记符号
        videoFrame = insertMarker(videoFrame, xyPoints, '+', 'Color', 'white');
    end

else
    %检测点的踪迹,注意有一些点可能丢失
    %xyPoints是xx \* 2数组,xx表示特征点数目,xyPoints是所有特征的的坐标
    %isFound是xx \* 1数组,表示特征点是否有track ok。ok是1,否则为0
    \[xyPoints, isFound\] = step(pointTracker, videoFrameGray);
    visiblePoints = xyPoints(isFound, :);
    oldInliers = oldPoints(isFound, :);

    numPts = size(visiblePoints, 1);       

    if numPts >= 10
        %在之前的点和新的点之间进行几何转换并建立边界线 
        \[xform, oldInliers, visiblePoints\] = estimateGeometricTransform(...
            oldInliers, visiblePoints, 'similarity', 'MaxDistance', 4);            

        %运行边界点的转换
        bboxPoints = transformPointsForward(xform, bboxPoints);

        %reshape表示重新调整矩阵的行数、列数、维数
        bboxPolygon = reshape(bboxPoints', 1, \[\]); 

         % 在被追随的物体周围插入边界框
        videoFrame = insertShape(videoFrame, 'Polygon', bboxPolygon, 'LineWidth', 3);

         % 显示被追随的点,在图像或视频中插入标记
        videoFrame = insertMarker(videoFrame, visiblePoints, '+', 'Color', 'green');

        %重置点
        oldPoints = visiblePoints;
        %设置跟随点,很多点在跟踪过程中丢失后,用于点的重新检测
        setPoints(pointTracker, oldPoints);
    end

end

%使用视频播放器对象显示被注释的视频帧
step(videoPlayer, videoFrame);
%检测视频播放窗口是否已经关闭
runLoop = isOpen(videoPlayer);

end

%清空
clear cam;
release(videoPlayer);
release(pointTracker);
release(faceDetector);

运行效果如下,这只是一张截图,没有录屏,建议自己动手实现一下啊。 [

](http://www.wjgbaby.com/wp-content/uploads/2018/01/18010402-300x229.jpg)
](http://www.wjgbaby.com/wp-content/uploads/2018/01/18010402-300x229.jpg)
在项目运行中,你可以对着笔记本的摄像头扭动你的头部和大幅度移动,以及改变你身边的灯光环境,观察其它效果。