function PointBasedTrackFace()
%% 摄像头格式,根据实际情况自行设定
Format = 'YUY2_320x240';
%==========================================================================
%% 创建窗口.
figure_handle = figure('Name', 'Camera Demo',...
'MenuBar', 'none',...
'NumberTitle', 'off',...
'ToolBar', 'none',...
'Tag', 'camera_demo',...
'Units', 'pixels');
myhandles.figure_handle = figure_handle;
%==========================================================================
%% 设置参数
myhandles.vid = videoinput('winvideo', 1, Format);
vidRes = get(myhandles.vid, 'VideoResolution');
set(myhandles.vid, 'ReturnedColorSpace', 'rgb',...
'TimerPeriod', 0.1);
triggerconfig(myhandles.vid, 'manual');
set(figure_handle, 'Position', [500 300 vidRes(1)+10 vidRes(2)+100]);
%==========================================================================
%% 界面设计
myhandles.axes = axes('Parent', figure_handle,...
'Tag', 'image',...
'Units', 'pixels',...
'Position',[0 100 vidRes(1) vidRes(2)],...
'Color', [0 0 0],...
'XTick',[],...
'YTick',[]);
myhandles.button_startStop = uicontrol('Parent', figure_handle,...
'Style', 'pushbutton',...
'Units', 'pixels',...
'String', 'Start',...
'Position', [20 30 60 30],...
'CallBack',{@startStop_callback, myhandles});
myhandles.button_close = uicontrol('Parent', figure_handle,...
'Style', 'pushbutton',...
'Units', 'pixels',...
'String', 'Close',...
'Position', [230 30 60 30],...
'CallBack', {@close_callback, myhandles});
%==========================================================================
%% 设置videoinput对象的定时器回调函数
set(myhandles.vid, 'TimerFcn', {@camera_TimerFcn, myhandles});
%% 将界面移到屏幕中心
movegui(figure_handle, 'center');
end
%==========================================================================
%% callback函数
%--------------------------------------------------------------------------
% 摄像头的定时器callback函数
function camera_TimerFcn(hObject, eventdata, varargin)
global start_flag pointTracker oldPoints flag
if start_flag
frame = getsnapshot(hObject);
if ~flag
[pointTracker, oldPoints] = face_points_detect(frame);
end
if ~isempty(oldPoints)
flag = true;
end
if flag
%disp('tracking...');
[points, isFound] = step(pointTracker, rgb2gray(frame));
visiblePoints = points(isFound, :);
oldInliers = oldPoints(isFound, :);
if size(visiblePoints, 1) >= 2 % need at least 2 points
% Estimate the geometric transformation between the old points
% and the new points and eliminate outliers
[~, ~, visiblePoints] = estimateGeometricTransform(...
oldInliers, visiblePoints, 'similarity', 'MaxDistance', 4);
% Display tracked points
frame = insertMarker(frame, visiblePoints, 'plus', ...
'Color', 'red');
% Reset the points
oldPoints= visiblePoints;
setPoints(pointTracker, oldPoints);
else
flag = false;
end
end
if ~flag
frame = insertText(frame, [10 10], 'detecting...', 'FontSize', 18);
else
frame = insertText(frame, [10 10], 'tracking...', 'FontSize', 18);
end
imshow(frame);
end
end
%--------------------------------------------------------------------------
% 开始停止按钮的callback函数
function startStop_callback(hObject,eventdata, varargin)
global start_flag flag
myhandles = varargin{1};
vid = myhandles.vid;
if strcmp('Stop', get(hObject, 'String'))
stop(vid);
set(hObject, 'String', 'Start');
start_flag = false;
elseif strcmp('Start', get(hObject, 'String'))
start(vid);
start_flag = true;
flag = false;
set(hObject, 'String', 'Stop');
end
end
%--------------------------------------------------------------------------
%--------------------------------------------------------------------------
% 关闭按钮的callback函数
function close_callback(hObject,eventdata, varargin)
global start_flag
start_flag = false;
myhandles = varargin{1};
vid = myhandles.vid;
choice = questdlg('Would you want to exit?', 'warning','Yes','No','No');
switch choice
case 'Yes'
stop(vid);
delete(vid)
close;
case 'No'
start_flag = true;
return;
end
end
%--------------------------------------------------------------------------
%--------------------------------------------------------------------------
% 检测人脸的函数
function [pointTracker, oldPoints] = face_points_detect(frame)
oldPoints = [];
pointTracker = [];
faceDetector = vision.CascadeObjectDetector();
bbox = step(faceDetector, frame);
if ~isempty(bbox)
max_area = 0;
for i = 1: size(bbox, 1)
if bbox(i,3)*bbox(i,4) > max_area
max_area = bbox(i,3)*bbox(i,4);
max_idx = i;
end
end
% Detect feature points in the face region.
points = detectMinEigenFeatures(rgb2gray(frame), 'ROI', bbox(max_idx,:));
if ~isempty(points)
oldPoints= points.Location;
pointTracker = vision.PointTracker('MaxBidirectionalError', 2);
initialize(pointTracker, oldPoints, rgb2gray(frame));
end
end
end