[我分享] 分享一个基于特征点的人脸检测跟踪程序吧

[复制链接]
荒草 发表于 2014-3-27 19:09:53
最近一直在看computer vison toolbox。里面有个例子是讲基于点跟踪的PointTracker类。稍微改写了一下这个例子,可以直接在摄像头里来跟踪。这个程序只适合单个人脸的跟。出现跟丢的情况的话,程序会自动进行检测,直到检测出人脸后,才开始继续跟踪。
  1. function PointBasedTrackFace()
  2. %% 摄像头格式,根据实际情况自行设定
  3. Format =  'YUY2_320x240';
  4. %==========================================================================
  5. %% 创建窗口.
  6. figure_handle = figure('Name', 'Camera Demo',...
  7.     'MenuBar', 'none',...
  8.     'NumberTitle', 'off',...
  9.     'ToolBar', 'none',...
  10.     'Tag', 'camera_demo',...
  11.     'Units', 'pixels');
  12. myhandles.figure_handle = figure_handle;
  13. %==========================================================================
  14. %% 设置参数
  15. myhandles.vid = videoinput('winvideo', 1, Format);
  16. vidRes = get(myhandles.vid, 'VideoResolution');
  17. set(myhandles.vid, 'ReturnedColorSpace', 'rgb',...
  18.     'TimerPeriod', 0.1);
  19. triggerconfig(myhandles.vid, 'manual');
  20. set(figure_handle, 'Position', [500 300 vidRes(1)+10 vidRes(2)+100]);

  21. %==========================================================================
  22. %% 界面设计
  23. myhandles.axes = axes('Parent', figure_handle,...
  24.     'Tag', 'image',...
  25.     'Units', 'pixels',...
  26.     'Position',[0 100 vidRes(1) vidRes(2)],...
  27.     'Color', [0 0 0],...
  28.     'XTick',[],...
  29.     'YTick',[]);
  30. myhandles.button_startStop = uicontrol('Parent', figure_handle,...
  31.     'Style', 'pushbutton',...
  32.     'Units', 'pixels',...
  33.     'String', 'Start',...
  34.     'Position', [20 30 60 30],...
  35.     'CallBack',{@startStop_callback, myhandles});
  36. myhandles.button_close = uicontrol('Parent', figure_handle,...
  37.     'Style', 'pushbutton',...
  38.     'Units', 'pixels',...
  39.     'String', 'Close',...
  40.     'Position', [230 30 60 30],...
  41.     'CallBack', {@close_callback, myhandles});
  42. %==========================================================================
  43. %% 设置videoinput对象的定时器回调函数
  44. set(myhandles.vid, 'TimerFcn', {@camera_TimerFcn, myhandles});
  45. %% 将界面移到屏幕中心
  46. movegui(figure_handle, 'center');
  47. end

  48. %==========================================================================
  49. %% callback函数
  50. %--------------------------------------------------------------------------
  51. % 摄像头的定时器callback函数
  52. function camera_TimerFcn(hObject, eventdata, varargin)
  53. global start_flag pointTracker oldPoints flag
  54. if start_flag
  55.     frame = getsnapshot(hObject);
  56.     if ~flag
  57.         [pointTracker, oldPoints] = face_points_detect(frame);
  58.     end
  59.     if ~isempty(oldPoints)
  60.         flag = true;
  61.     end
  62.     if flag
  63.         %disp('tracking...');
  64.         [points, isFound] = step(pointTracker, rgb2gray(frame));
  65.         visiblePoints = points(isFound, :);
  66.         oldInliers = oldPoints(isFound, :);
  67.         
  68.         if size(visiblePoints, 1) >= 2 % need at least 2 points
  69.             % Estimate the geometric transformation between the old points
  70.             % and the new points and eliminate outliers
  71.             [~, ~, visiblePoints] = estimateGeometricTransform(...
  72.                 oldInliers, visiblePoints, 'similarity', 'MaxDistance', 4);
  73.             % Display tracked points
  74.             frame = insertMarker(frame, visiblePoints, 'plus', ...
  75.                 'Color', 'red');
  76.             
  77.             % Reset the points
  78.             oldPoints= visiblePoints;
  79.             setPoints(pointTracker, oldPoints);
  80.         else
  81.             flag = false;
  82.         end
  83.     end
  84.     if ~flag
  85.         frame = insertText(frame, [10 10], 'detecting...', 'FontSize', 18);
  86.     else
  87.         frame = insertText(frame, [10 10], 'tracking...', 'FontSize', 18);
  88.     end
  89.     imshow(frame);
  90. end
  91. end
  92. %--------------------------------------------------------------------------
  93. % 开始停止按钮的callback函数
  94. function startStop_callback(hObject,eventdata, varargin)
  95. global start_flag flag
  96. myhandles = varargin{1};
  97. vid = myhandles.vid;
  98. if strcmp('Stop', get(hObject, 'String'))
  99.     stop(vid);
  100.     set(hObject, 'String', 'Start');
  101.     start_flag = false;
  102. elseif strcmp('Start', get(hObject, 'String'))
  103.     start(vid);
  104.     start_flag = true;
  105.     flag = false;
  106.     set(hObject, 'String', 'Stop');
  107. end
  108. end
  109. %--------------------------------------------------------------------------

  110. %--------------------------------------------------------------------------
  111. % 关闭按钮的callback函数
  112. function close_callback(hObject,eventdata, varargin)
  113. global start_flag
  114. start_flag = false;
  115. myhandles = varargin{1};
  116. vid = myhandles.vid;

  117. choice = questdlg('Would you want to exit?', 'warning','Yes','No','No');
  118. switch choice
  119.     case 'Yes'
  120.         stop(vid);
  121.         delete(vid)
  122.         close;
  123.     case 'No'
  124.         start_flag = true;
  125.         return;
  126. end
  127. end
  128. %--------------------------------------------------------------------------

  129. %--------------------------------------------------------------------------
  130. % 检测人脸的函数
  131. function [pointTracker, oldPoints] = face_points_detect(frame)
  132. oldPoints = [];
  133. pointTracker = [];
  134. faceDetector = vision.CascadeObjectDetector();
  135. bbox = step(faceDetector, frame);

  136. if ~isempty(bbox)
  137.     max_area = 0;
  138.     for i = 1: size(bbox, 1)
  139.         if bbox(i,3)*bbox(i,4) > max_area
  140.             max_area = bbox(i,3)*bbox(i,4);
  141.             max_idx = i;
  142.         end
  143.     end
  144.     % Detect feature points in the face region.
  145.     points = detectMinEigenFeatures(rgb2gray(frame), 'ROI', bbox(max_idx,:));
  146.     if ~isempty(points)
  147.         oldPoints= points.Location;
  148.         pointTracker = vision.PointTracker('MaxBidirectionalError', 2);
  149.         initialize(pointTracker, oldPoints, rgb2gray(frame));
  150.     end
  151. end
  152. end
复制代码

29 条回复


HerT 发表于 2014-4-20 19:33:01
参数设置这部分可否将下,我联想笔记本电脑,怎么设置

荒草 发表于 2014-4-22 09:18:57
HerT 发表于 2014-4-20 19:33
参数设置这部分可否将下,我联想笔记本电脑,怎么设置

什么参数?

HerT 发表于 2014-4-22 12:54:58

设置电脑摄像头参数这部分语句不太懂

HerT 发表于 2014-4-22 13:07:50

myhandles.vid = videoinput('winvideo', 1, Format);
这句出错,错误如下
>> PointBasedTrackFace
Undefined function 'videoinput' for input arguments of type 'char'.

Error in PointBasedTrackFace (line 15)
myhandles.vid = videoinput('winvideo', 1, Format);

荒草 发表于 2014-4-22 14:28:31
HerT 发表于 2014-4-22 12:54
设置电脑摄像头参数这部分语句不太懂

这个你得去看帮助文档啊。你先查看自己的摄像头支持的格式,然后把Format换成需要格式

HerT 发表于 2014-4-22 18:33:32
荒草 发表于 2014-4-22 14:28
这个你得去看帮助文档啊。你先查看自己的摄像头支持的格式,然后把Format换成需要格式 ...

不是啊,Format我电脑和你一样,Undefined function 'videoinput' for input arguments of type 'char'.这句错误是什么问题啊

bertcool 发表于 2014-4-22 22:39:50
HerT 发表于 2014-4-22 18:33
不是啊,Format我电脑和你一样,Undefined function 'videoinput' for input arguments of type 'char'. ...

你可能没有image acquisition toolbox, 所以找不到videoinput这个function.

荒草 发表于 2014-4-22 23:38:50
HerT 发表于 2014-4-22 18:33
不是啊,Format我电脑和你一样,Undefined function 'videoinput' for input arguments of type 'char'. ...

你matlab是哪个版本啊?还是没有安装相应的工具箱?

HerT 发表于 2014-4-23 12:52:43
bertcool 发表于 2014-4-22 22:39
你可能没有image acquisition toolbox, 所以找不到videoinput这个function.

有可能!

HerT 发表于 2014-4-23 12:53:07
荒草 发表于 2014-4-22 23:38
你matlab是哪个版本啊?还是没有安装相应的工具箱?

MATLAB2012B

东方不败1990 发表于 2014-5-15 09:55:09
请问大神:Error using load
               Unable to read file orldata.mat: No such file or directory.
是怎么回事?我是初学者。
请大神赐教。

荒草 发表于 2014-5-15 11:21:37
东方不败1990 发表于 2014-5-15 09:55
请问大神:Error using load
               Unable to read file orldata.mat: No such file or directory ...

跟我这个程序没什么关系吧。你这个问题就是没有orldata.mat这个文件,你仔细看看orldata.mat在当前路径下没?

东方不败1990 发表于 2014-5-15 11:29:29
请问大神:这个orldata.mat文件是MATLAB自带的还是您自己定义的文件啊?
              如果是您自己定义的文件,那我就知道为什么不行了。:)

荒草 发表于 2014-5-15 11:41:23
东方不败1990 发表于 2014-5-15 11:29
请问大神:这个orldata.mat文件是MATLAB自带的还是您自己定义的文件啊?
              如果是您自己定义的 ...

我程序中没有这个啊

东方不败1990 发表于 2014-5-16 17:11:05
Undefined function 'insertText' for input
arguments of type 'uint8'.

Error in PointBasedTrackFace>camera_TimerFcn (line
87)
        frame = insertText(frame, [10 10],
        'detecting...', 'FontSize', 18);

Warning: The TimerFcn callback is being disabled.
To enable the callback, set the TimerFcn property.
大神这个事怎么回事???是不是我的MATLAB版本过低,我的是2010a

荒草 发表于 2014-5-16 18:44:00
东方不败1990 发表于 2014-5-16 17:11
Undefined function 'insertText' for input
arguments of type 'uint8'.

版本太低了

ncepuzjk 发表于 2014-5-16 21:43:11
大神  问一下:  一直以为只有定义了timer后 才有定时器回答函数,原来videoinput对象也可以定义定时器回调函数,这样就有个问题 了。。 什么时候打开了这个定时器回答函数  看程序里面没有打开  ??是不是定义后自动打开并运行?   这个videoinput对象的定时器回调函数和timer的回调函数有什么区别?   谢谢了。

ncepuzjk 发表于 2014-5-16 21:47:59
我现在在做双目立体视觉  我想同时调用两个摄像头  现在可以实现分别拍照 分别录像 同时拍照 同时采集一帧一帧的图像并保存  但是不能实现同时录像。     因为MATLAB是单线程吗?  我前面实现的同时拍照其实也是第一个拍了 在第二个拍 也有先后顺序 只是时间极短 相当于同时拍了   现在我要同时录像?该如何实现呢  看你的这个程序受到了启发。 是不是 两个摄像头分别建立定时器回调函数 然后在两个回调函数里面分别录像就可以了呢? 打算试试 期待相互交流!

荒草 发表于 2014-5-16 23:09:45
ncepuzjk 发表于 2014-5-16 21:43
大神  问一下:  一直以为只有定义了timer后 才有定时器回答函数,原来videoinput对象也可以定义定时器回调 ...

start(videoObj)就可以了。感觉没啥区别

荒草 发表于 2014-5-16 23:10:13
ncepuzjk 发表于 2014-5-16 21:47
我现在在做双目立体视觉  我想同时调用两个摄像头  现在可以实现分别拍照 分别录像 同时拍照 同时采集一帧 ...

我就是这么干的。左右两个摄像头设置两个定时器

ncepuzjk 发表于 2014-5-18 22:00:38
荒草 发表于 2014-5-16 23:09
start(videoObj)就可以了。感觉没啥区别

start(vid1)
start(vid2)

然后  我
stop(vid1)
stop(vid2)   
这样的话 vid2 无法停止  第二个视频无法成功保存  
而且这两个视频的长度也不一样  是不是stop过程比较耗时。  求教。

荒草 发表于 2014-5-18 23:50:23
ncepuzjk 发表于 2014-5-18 22:00
start(vid1)
start(vid2)

不是吧,怎么会停止不了呢??你看看我这个帖子吧https://www.ilovematlab.cn/thread-268455-1-1.html

migua 发表于 2014-12-24 16:15:36
今天第二次向楼主学习了!

Adolph_CQ 发表于 2015-3-18 11:40:26
考来学习一下:kiss:
您需要登录后才可以回帖 登录 | 注册

本版积分规则

相关帖子
相关文章
热门教程
站长推荐
快速回复 返回顶部 返回列表