ROI reinitialization, preference for large faces.
This commit is contained in:
parent
f153e5c255
commit
99cc06631f
4 changed files with 61 additions and 15 deletions
|
@ -6,7 +6,7 @@
|
||||||
xmlns:local="clr-namespace:OpenFaceDemo"
|
xmlns:local="clr-namespace:OpenFaceDemo"
|
||||||
xmlns:of="clr-namespace:OpenFaceOffline;assembly=OpenFaceOffline"
|
xmlns:of="clr-namespace:OpenFaceOffline;assembly=OpenFaceOffline"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="OpenFace Analyser" Height="800" Width="1300" MinWidth="700" MinHeight="450" Closing="Window_Closing" WindowStartupLocation="CenterScreen">
|
Title="OpenFace Analyser" Height="800" Width="1300" MinWidth="700" MinHeight="450" Closing="Window_Closing" WindowStartupLocation="CenterScreen" KeyDown="Window_KeyDown">
|
||||||
<Grid Name="MainGrid" Margin="-1,1,1.333,-1.333">
|
<Grid Name="MainGrid" Margin="-1,1,1.333,-1.333">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="1.8*"/>
|
<ColumnDefinition Width="1.8*"/>
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</Menu>
|
</Menu>
|
||||||
<Border Name="VideoBorder" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Grid.RowSpan="3" BorderBrush="Black" BorderThickness="1" Background="LightGray" Margin="5,5,0,0" >
|
<Border Name="VideoBorder" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Grid.RowSpan="3" BorderBrush="Black" BorderThickness="1" Background="LightGray" Margin="5,5,0,0" >
|
||||||
<of:OverlayImage x:Name="video" />
|
<of:OverlayImage x:Name="video" MouseDown="video_MouseDown" />
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<local:AxesTimeSeriesPlot NumVertGrid="5" x:Name="headPosePlot" ShowLegend="True" MinVal="-1" MaxVal="1" MinHeight="180" Grid.Row="4" Grid.Column="0" Padding="60 20 30 40" RangeLabel="Head pose" Orientation="Horizontal">
|
<local:AxesTimeSeriesPlot NumVertGrid="5" x:Name="headPosePlot" ShowLegend="True" MinVal="-1" MaxVal="1" MinHeight="180" Grid.Row="4" Grid.Column="0" Padding="60 20 30 40" RangeLabel="Head pose" Orientation="Horizontal">
|
||||||
|
|
|
@ -62,8 +62,10 @@ namespace OpenFaceDemo
|
||||||
|
|
||||||
FpsTracker processing_fps = new FpsTracker();
|
FpsTracker processing_fps = new FpsTracker();
|
||||||
|
|
||||||
|
// Controlling the model reset
|
||||||
volatile bool detectionSucceeding = false;
|
volatile bool detectionSucceeding = false;
|
||||||
volatile bool reset = false;
|
volatile bool reset = false;
|
||||||
|
Point? resetPoint = null;
|
||||||
|
|
||||||
// For selecting webcams
|
// For selecting webcams
|
||||||
CameraSelection cam_sec;
|
CameraSelection cam_sec;
|
||||||
|
@ -73,6 +75,7 @@ namespace OpenFaceDemo
|
||||||
CLNF clnf_model;
|
CLNF clnf_model;
|
||||||
FaceAnalyserManaged face_analyser;
|
FaceAnalyserManaged face_analyser;
|
||||||
|
|
||||||
|
|
||||||
public MainWindow()
|
public MainWindow()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
@ -383,8 +386,17 @@ namespace OpenFaceDemo
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (reset)
|
if (reset)
|
||||||
|
{
|
||||||
|
if (resetPoint.HasValue)
|
||||||
|
{
|
||||||
|
clnf_model.Reset(resetPoint.Value.X, resetPoint.Value.Y);
|
||||||
|
resetPoint = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
clnf_model.Reset();
|
clnf_model.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
face_analyser.Reset();
|
face_analyser.Reset();
|
||||||
reset = false;
|
reset = false;
|
||||||
|
|
||||||
|
@ -477,13 +489,32 @@ namespace OpenFaceDemo
|
||||||
thread_running = false;
|
thread_running = false;
|
||||||
processing_thread.Join();
|
processing_thread.Join();
|
||||||
|
|
||||||
|
if (capture != null)
|
||||||
capture.Dispose();
|
capture.Dispose();
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
if (face_analyser != null)
|
||||||
face_analyser.Dispose();
|
face_analyser.Dispose();
|
||||||
|
if(clnf_model != null)
|
||||||
clnf_model.Dispose();
|
clnf_model.Dispose();
|
||||||
this.Close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Window_KeyDown(object sender, KeyEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Key == Key.R)
|
||||||
|
{
|
||||||
|
reset = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void video_MouseDown(object sender, MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
var clickPos = e.GetPosition(video);
|
||||||
|
resetPoint = new Point(clickPos.X / video.ActualWidth, clickPos.Y / video.ActualHeight);
|
||||||
|
reset = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -548,6 +548,9 @@ void CLNF::Read(string main_location)
|
||||||
|
|
||||||
failures_in_a_row = -1;
|
failures_in_a_row = -1;
|
||||||
|
|
||||||
|
preference_det.x = -1;
|
||||||
|
preference_det.y = -1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resetting the model (for a new video, or complet reinitialisation
|
// Resetting the model (for a new video, or complet reinitialisation
|
||||||
|
|
|
@ -1452,9 +1452,11 @@ bool DetectSingleFaceHOG(cv::Rect_<double>& o_region, const cv::Mat_<uchar>& int
|
||||||
// The tracker can return multiple faces
|
// The tracker can return multiple faces
|
||||||
vector<cv::Rect_<double> > face_detections;
|
vector<cv::Rect_<double> > face_detections;
|
||||||
vector<double> confidences;
|
vector<double> confidences;
|
||||||
|
|
||||||
bool detect_success = LandmarkDetector::DetectFacesHOG(face_detections, intensity_img, detector, confidences);
|
bool detect_success = LandmarkDetector::DetectFacesHOG(face_detections, intensity_img, detector, confidences);
|
||||||
|
|
||||||
|
// In case of multiple faces pick the biggest one
|
||||||
|
bool use_size = true;
|
||||||
|
|
||||||
if(detect_success)
|
if(detect_success)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -1467,6 +1469,10 @@ bool DetectSingleFaceHOG(cv::Rect_<double>& o_region, const cv::Mat_<uchar>& int
|
||||||
best_so_far = sqrt((preference.x - (face_detections[0].width/2 + face_detections[0].x)) * (preference.x - (face_detections[0].width/2 + face_detections[0].x)) +
|
best_so_far = sqrt((preference.x - (face_detections[0].width/2 + face_detections[0].x)) * (preference.x - (face_detections[0].width/2 + face_detections[0].x)) +
|
||||||
(preference.y - (face_detections[0].height/2 + face_detections[0].y)) * (preference.y - (face_detections[0].height/2 + face_detections[0].y)));
|
(preference.y - (face_detections[0].height/2 + face_detections[0].y)) * (preference.y - (face_detections[0].height/2 + face_detections[0].y)));
|
||||||
}
|
}
|
||||||
|
else if (use_size)
|
||||||
|
{
|
||||||
|
best_so_far = (face_detections[0].width + face_detections[0].height) / 2.0;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
best_so_far = confidences[0];
|
best_so_far = confidences[0];
|
||||||
|
@ -1481,10 +1487,16 @@ bool DetectSingleFaceHOG(cv::Rect_<double>& o_region, const cv::Mat_<uchar>& int
|
||||||
|
|
||||||
if(use_preferred)
|
if(use_preferred)
|
||||||
{
|
{
|
||||||
dist = sqrt((preference.x - (face_detections[0].width/2 + face_detections[0].x)) * (preference.x - (face_detections[0].width/2 + face_detections[0].x)) +
|
dist = sqrt((preference.x - (face_detections[i].width/2 + face_detections[i].x)) * (preference.x - (face_detections[i].width/2 + face_detections[i].x)) +
|
||||||
(preference.y - (face_detections[0].height/2 + face_detections[0].y)) * (preference.y - (face_detections[0].height/2 + face_detections[0].y)));
|
(preference.y - (face_detections[i].height/2 + face_detections[i].y)) * (preference.y - (face_detections[i].height/2 + face_detections[i].y)));
|
||||||
|
|
||||||
better = dist < best_so_far;
|
better = dist < best_so_far;
|
||||||
}
|
}
|
||||||
|
else if (use_size)
|
||||||
|
{
|
||||||
|
dist = (face_detections[i].width + face_detections[i].height) / 2.0;
|
||||||
|
better = dist > best_so_far;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dist = confidences[i];
|
dist = confidences[i];
|
||||||
|
|
Loading…
Reference in a new issue