Working towards proper camera selection.
This commit is contained in:
parent
3b63728b9b
commit
20276a00b2
12 changed files with 539 additions and 166 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -86,3 +86,4 @@ matlab_runners/Demos/processed_features/
|
||||||
*.db
|
*.db
|
||||||
exe/releases/OpenFace_0.3.0_win_x64/
|
exe/releases/OpenFace_0.3.0_win_x64/
|
||||||
exe/releases/OpenFace_0.3.0_win_x86/
|
exe/releases/OpenFace_0.3.0_win_x86/
|
||||||
|
lib/3rdParty/CameraEnumerator/x64/
|
||||||
|
|
29
OpenFace.sln
29
OpenFace.sln
|
@ -41,6 +41,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeadPoseLive", "gui\HeadPos
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Utilities", "lib\local\Utilities\Utilities.vcxproj", "{8E741EA2-9386-4CF2-815E-6F9B08991EAC}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Utilities", "lib\local\Utilities\Utilities.vcxproj", "{8E741EA2-9386-4CF2-815E-6F9B08991EAC}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CameraEnumerator", "lib\3rdParty\CameraEnumerator\CameraEnumerator.vcxproj", "{50B7D4BF-E33B-41D0-AA89-76BBA57BF5CC}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Win32 = Debug|Win32
|
Debug|Win32 = Debug|Win32
|
||||||
|
@ -73,6 +75,14 @@ Global
|
||||||
{0E7FC556-0E80-45EA-A876-DDE4C2FEDCD7}.Release|Win32.Build.0 = Release|Win32
|
{0E7FC556-0E80-45EA-A876-DDE4C2FEDCD7}.Release|Win32.Build.0 = Release|Win32
|
||||||
{0E7FC556-0E80-45EA-A876-DDE4C2FEDCD7}.Release|x64.ActiveCfg = Release|x64
|
{0E7FC556-0E80-45EA-A876-DDE4C2FEDCD7}.Release|x64.ActiveCfg = Release|x64
|
||||||
{0E7FC556-0E80-45EA-A876-DDE4C2FEDCD7}.Release|x64.Build.0 = Release|x64
|
{0E7FC556-0E80-45EA-A876-DDE4C2FEDCD7}.Release|x64.Build.0 = Release|x64
|
||||||
|
{5F915541-F531-434F-9C81-79F5DB58012B}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{5F915541-F531-434F-9C81-79F5DB58012B}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{5F915541-F531-434F-9C81-79F5DB58012B}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{5F915541-F531-434F-9C81-79F5DB58012B}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{5F915541-F531-434F-9C81-79F5DB58012B}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{5F915541-F531-434F-9C81-79F5DB58012B}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{5F915541-F531-434F-9C81-79F5DB58012B}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{5F915541-F531-434F-9C81-79F5DB58012B}.Release|x64.Build.0 = Release|x64
|
||||||
{8A23C00D-767D-422D-89A3-CF225E3DAB4B}.Debug|Win32.ActiveCfg = Debug|Win32
|
{8A23C00D-767D-422D-89A3-CF225E3DAB4B}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
{8A23C00D-767D-422D-89A3-CF225E3DAB4B}.Debug|Win32.Build.0 = Debug|Win32
|
{8A23C00D-767D-422D-89A3-CF225E3DAB4B}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{8A23C00D-767D-422D-89A3-CF225E3DAB4B}.Debug|x64.ActiveCfg = Debug|x64
|
{8A23C00D-767D-422D-89A3-CF225E3DAB4B}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
@ -152,14 +162,6 @@ Global
|
||||||
{F396362D-821E-4EA6-9BBF-1F6050844118}.Release|Win32.Build.0 = Release|x86
|
{F396362D-821E-4EA6-9BBF-1F6050844118}.Release|Win32.Build.0 = Release|x86
|
||||||
{F396362D-821E-4EA6-9BBF-1F6050844118}.Release|x64.ActiveCfg = Release|Any CPU
|
{F396362D-821E-4EA6-9BBF-1F6050844118}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
{F396362D-821E-4EA6-9BBF-1F6050844118}.Release|x64.Build.0 = Release|Any CPU
|
{F396362D-821E-4EA6-9BBF-1F6050844118}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{5F915541-F531-434F-9C81-79F5DB58012B}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{5F915541-F531-434F-9C81-79F5DB58012B}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{5F915541-F531-434F-9C81-79F5DB58012B}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{5F915541-F531-434F-9C81-79F5DB58012B}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{5F915541-F531-434F-9C81-79F5DB58012B}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{5F915541-F531-434F-9C81-79F5DB58012B}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
{5F915541-F531-434F-9C81-79F5DB58012B}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{5F915541-F531-434F-9C81-79F5DB58012B}.Release|x64.Build.0 = Release|x64
|
|
||||||
{8E741EA2-9386-4CF2-815E-6F9B08991EAC}.Debug|Win32.ActiveCfg = Debug|Win32
|
{8E741EA2-9386-4CF2-815E-6F9B08991EAC}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
{8E741EA2-9386-4CF2-815E-6F9B08991EAC}.Debug|Win32.Build.0 = Debug|Win32
|
{8E741EA2-9386-4CF2-815E-6F9B08991EAC}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{8E741EA2-9386-4CF2-815E-6F9B08991EAC}.Debug|x64.ActiveCfg = Debug|x64
|
{8E741EA2-9386-4CF2-815E-6F9B08991EAC}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
@ -168,6 +170,14 @@ Global
|
||||||
{8E741EA2-9386-4CF2-815E-6F9B08991EAC}.Release|Win32.Build.0 = Release|Win32
|
{8E741EA2-9386-4CF2-815E-6F9B08991EAC}.Release|Win32.Build.0 = Release|Win32
|
||||||
{8E741EA2-9386-4CF2-815E-6F9B08991EAC}.Release|x64.ActiveCfg = Release|x64
|
{8E741EA2-9386-4CF2-815E-6F9B08991EAC}.Release|x64.ActiveCfg = Release|x64
|
||||||
{8E741EA2-9386-4CF2-815E-6F9B08991EAC}.Release|x64.Build.0 = Release|x64
|
{8E741EA2-9386-4CF2-815E-6F9B08991EAC}.Release|x64.Build.0 = Release|x64
|
||||||
|
{50B7D4BF-E33B-41D0-AA89-76BBA57BF5CC}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{50B7D4BF-E33B-41D0-AA89-76BBA57BF5CC}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{50B7D4BF-E33B-41D0-AA89-76BBA57BF5CC}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{50B7D4BF-E33B-41D0-AA89-76BBA57BF5CC}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{50B7D4BF-E33B-41D0-AA89-76BBA57BF5CC}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{50B7D4BF-E33B-41D0-AA89-76BBA57BF5CC}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{50B7D4BF-E33B-41D0-AA89-76BBA57BF5CC}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{50B7D4BF-E33B-41D0-AA89-76BBA57BF5CC}.Release|x64.Build.0 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -176,6 +186,7 @@ Global
|
||||||
{B47A5F12-2567-44E9-AE49-35763EC82149} = {D5F7B3E2-01FE-4F4A-8CE1-274D74D395D4}
|
{B47A5F12-2567-44E9-AE49-35763EC82149} = {D5F7B3E2-01FE-4F4A-8CE1-274D74D395D4}
|
||||||
{BDC1D107-DE17-4705-8E7B-CDDE8BFB2BF8} = {99FEBA13-BDDF-4076-B57E-D8EF4076E20D}
|
{BDC1D107-DE17-4705-8E7B-CDDE8BFB2BF8} = {99FEBA13-BDDF-4076-B57E-D8EF4076E20D}
|
||||||
{0E7FC556-0E80-45EA-A876-DDE4C2FEDCD7} = {99FEBA13-BDDF-4076-B57E-D8EF4076E20D}
|
{0E7FC556-0E80-45EA-A876-DDE4C2FEDCD7} = {99FEBA13-BDDF-4076-B57E-D8EF4076E20D}
|
||||||
|
{5F915541-F531-434F-9C81-79F5DB58012B} = {99FEBA13-BDDF-4076-B57E-D8EF4076E20D}
|
||||||
{8A23C00D-767D-422D-89A3-CF225E3DAB4B} = {9961DDAC-BE6E-4A6E-8EEF-FFC7D67BD631}
|
{8A23C00D-767D-422D-89A3-CF225E3DAB4B} = {9961DDAC-BE6E-4A6E-8EEF-FFC7D67BD631}
|
||||||
{C3FAF36F-44BC-4454-87C2-C5106575FE50} = {9961DDAC-BE6E-4A6E-8EEF-FFC7D67BD631}
|
{C3FAF36F-44BC-4454-87C2-C5106575FE50} = {9961DDAC-BE6E-4A6E-8EEF-FFC7D67BD631}
|
||||||
{2D80FA0B-2DE8-4475-BA5A-C08A9E1EDAAC} = {9961DDAC-BE6E-4A6E-8EEF-FFC7D67BD631}
|
{2D80FA0B-2DE8-4475-BA5A-C08A9E1EDAAC} = {9961DDAC-BE6E-4A6E-8EEF-FFC7D67BD631}
|
||||||
|
@ -186,7 +197,7 @@ Global
|
||||||
{A4760F41-2B1F-4144-B7B2-62785AFFE79B} = {C9D8D0B0-11EC-41CB-8524-2DDB5BE94297}
|
{A4760F41-2B1F-4144-B7B2-62785AFFE79B} = {C9D8D0B0-11EC-41CB-8524-2DDB5BE94297}
|
||||||
{E143A2AA-312E-4DFE-B61D-9A87CCBC8E90} = {C9D8D0B0-11EC-41CB-8524-2DDB5BE94297}
|
{E143A2AA-312E-4DFE-B61D-9A87CCBC8E90} = {C9D8D0B0-11EC-41CB-8524-2DDB5BE94297}
|
||||||
{F396362D-821E-4EA6-9BBF-1F6050844118} = {C9D8D0B0-11EC-41CB-8524-2DDB5BE94297}
|
{F396362D-821E-4EA6-9BBF-1F6050844118} = {C9D8D0B0-11EC-41CB-8524-2DDB5BE94297}
|
||||||
{5F915541-F531-434F-9C81-79F5DB58012B} = {99FEBA13-BDDF-4076-B57E-D8EF4076E20D}
|
|
||||||
{8E741EA2-9386-4CF2-815E-6F9B08991EAC} = {99FEBA13-BDDF-4076-B57E-D8EF4076E20D}
|
{8E741EA2-9386-4CF2-815E-6F9B08991EAC} = {99FEBA13-BDDF-4076-B57E-D8EF4076E20D}
|
||||||
|
{50B7D4BF-E33B-41D0-AA89-76BBA57BF5CC} = {D5F7B3E2-01FE-4F4A-8CE1-274D74D395D4}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem Header="Open image directory" Click="individualImageDirectoryOpenClick">
|
<MenuItem Header="Open image directory" Click="individualImageDirectoryOpenClick">
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
<MenuItem Header="Open webcam" Click="openWebcamClick">
|
||||||
|
</MenuItem>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem Name="RecordingMenu" Header="Record" >
|
<MenuItem Name="RecordingMenu" Header="Record" >
|
||||||
<MenuItem IsCheckable="True" Header="Record AUs" IsChecked="{Binding RecordAUs}"/>
|
<MenuItem IsCheckable="True" Header="Record AUs" IsChecked="{Binding RecordAUs}"/>
|
||||||
|
|
|
@ -96,6 +96,9 @@ namespace OpenFaceOffline
|
||||||
|
|
||||||
FpsTracker processing_fps = new FpsTracker();
|
FpsTracker processing_fps = new FpsTracker();
|
||||||
|
|
||||||
|
// For selecting webcams
|
||||||
|
CameraSelection cam_sec;
|
||||||
|
|
||||||
// For tracking
|
// For tracking
|
||||||
FaceDetector face_detector;
|
FaceDetector face_detector;
|
||||||
FaceModelParameters face_model_params;
|
FaceModelParameters face_model_params;
|
||||||
|
@ -753,6 +756,44 @@ namespace OpenFaceOffline
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void openWebcamClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
StopTracking();
|
||||||
|
|
||||||
|
Dispatcher.Invoke(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 2, 0), (Action)(() =>
|
||||||
|
{
|
||||||
|
|
||||||
|
if (cam_sec == null)
|
||||||
|
{
|
||||||
|
cam_sec = new CameraSelection();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cam_sec = new CameraSelection(cam_sec.cams);
|
||||||
|
cam_sec.Visibility = System.Windows.Visibility.Visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the icon
|
||||||
|
Uri iconUri = new Uri("logo1.ico", UriKind.RelativeOrAbsolute);
|
||||||
|
cam_sec.Icon = BitmapFrame.Create(iconUri);
|
||||||
|
|
||||||
|
if (!cam_sec.no_cameras_found)
|
||||||
|
cam_sec.ShowDialog();
|
||||||
|
|
||||||
|
if (cam_sec.camera_selected)
|
||||||
|
{
|
||||||
|
int cam_id = cam_sec.selected_camera.Item1;
|
||||||
|
int width = cam_sec.selected_camera.Item2;
|
||||||
|
int height = cam_sec.selected_camera.Item3;
|
||||||
|
|
||||||
|
// processing_thread = new Thread(() => ProcessingLoop(cam_id, width, height));
|
||||||
|
// processing_thread.Start();
|
||||||
|
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
// Button handling
|
// Button handling
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
|
|
|
@ -97,6 +97,9 @@
|
||||||
<Compile Include="UI_items\CameraParametersEntry.xaml.cs">
|
<Compile Include="UI_items\CameraParametersEntry.xaml.cs">
|
||||||
<DependentUpon>CameraParametersEntry.xaml</DependentUpon>
|
<DependentUpon>CameraParametersEntry.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="UI_items\CameraSelection.xaml.cs">
|
||||||
|
<DependentUpon>CameraSelection.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="UI_items\MultiBarGraph.xaml.cs">
|
<Compile Include="UI_items\MultiBarGraph.xaml.cs">
|
||||||
<DependentUpon>MultiBarGraph.xaml</DependentUpon>
|
<DependentUpon>MultiBarGraph.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
@ -136,6 +139,10 @@
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
|
<Page Include="UI_items\CameraSelection.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
<Page Include="UI_items\MultiBarGraph.xaml">
|
<Page Include="UI_items\MultiBarGraph.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
|
43
gui/OpenFaceOffline/UI_items/CameraSelection.xaml
Normal file
43
gui/OpenFaceOffline/UI_items/CameraSelection.xaml
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
<Window x:Class="OpenFaceOffline.CameraSelection"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:local="clr-namespace:OpenFaceOffline"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Title="Camera selection" Height="460" Width="600" ResizeMode="NoResize" WindowStartupLocation="CenterScreen" Closing="Window_Closing">
|
||||||
|
<Grid>
|
||||||
|
<Grid Name="camerasPanel" Visibility="Hidden">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="auto" />
|
||||||
|
<RowDefinition Height="320" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
<RowDefinition Height="40" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<Label Grid.Row="0" Grid.ColumnSpan="10" HorizontalContentAlignment="Center" FontSize="20">Choose Video Source</Label>
|
||||||
|
|
||||||
|
<Grid Grid.Row="1" Grid.Column="0" Name="ThumbnailPanel" HorizontalAlignment="Center">
|
||||||
|
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
<RowDefinition Height="25" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
<!-- Click="OpenFile_Click" -->
|
||||||
|
<Button Width="150" Grid.Row="3" Height="35" Grid.ColumnSpan="10" FontSize="20" Click="Button_Click">Select camera</Button>
|
||||||
|
</Grid>
|
||||||
|
<Grid Name="LoadingGrid" Visibility="Visible">
|
||||||
|
<StackPanel Grid.Row="1" Name="ProgressBar" Margin="20">
|
||||||
|
<Label HorizontalAlignment="Center" FontSize="18">Loading Webcams</Label>
|
||||||
|
<ProgressBar Height="20" Minimum="0" Maximum="100" Name="pbStatus" IsIndeterminate="True" />
|
||||||
|
<Label HorizontalAlignment="Center" FontSize="18">Might take some time the first time</Label>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</Window>
|
244
gui/OpenFaceOffline/UI_items/CameraSelection.xaml.cs
Normal file
244
gui/OpenFaceOffline/UI_items/CameraSelection.xaml.cs
Normal file
|
@ -0,0 +1,244 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
using CppInterop;
|
||||||
|
using System.Windows.Threading;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace OpenFaceOffline
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for CameraSelection.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class CameraSelection : Window
|
||||||
|
{
|
||||||
|
|
||||||
|
List<Border> sample_images;
|
||||||
|
List<ComboBox> combo_boxes;
|
||||||
|
|
||||||
|
// id, width, height
|
||||||
|
public Tuple<int, int, int> selected_camera;
|
||||||
|
|
||||||
|
List<List<Tuple<int, int>>> resolutions_all;
|
||||||
|
int selected_camera_idx = -1;
|
||||||
|
|
||||||
|
// indicate if user clicked on camera
|
||||||
|
public bool camera_selected = false;
|
||||||
|
|
||||||
|
public bool no_cameras_found = false;
|
||||||
|
|
||||||
|
public List<Tuple<int, String, List<Tuple<int, int>>, OpenCVWrappers.RawImage>> cams;
|
||||||
|
|
||||||
|
public void PopulateCameraSelections()
|
||||||
|
{
|
||||||
|
this.KeyDown += new KeyEventHandler(CameraSelection_KeyDown);
|
||||||
|
|
||||||
|
// Finding the cameras here
|
||||||
|
if (cams == null)
|
||||||
|
{
|
||||||
|
String root = AppDomain.CurrentDomain.BaseDirectory;
|
||||||
|
//cams = CameraInterop.Capture.GetCameras(root);
|
||||||
|
cams = UtilitiesOF.SequenceReader.GetCameras(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
sample_images = new List<Border>();
|
||||||
|
|
||||||
|
// Each cameras corresponding resolutions
|
||||||
|
resolutions_all = new List<List<Tuple<int, int>>>();
|
||||||
|
combo_boxes = new List<ComboBox>();
|
||||||
|
|
||||||
|
foreach (var s in cams)
|
||||||
|
{
|
||||||
|
|
||||||
|
var b = s.Item4.CreateWriteableBitmap();
|
||||||
|
s.Item4.UpdateWriteableBitmap(b);
|
||||||
|
b.Freeze();
|
||||||
|
|
||||||
|
Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
int idx = i;
|
||||||
|
Image img = new Image();
|
||||||
|
img.Source = b;
|
||||||
|
img.Margin = new Thickness(5);
|
||||||
|
|
||||||
|
ColumnDefinition col_def = new ColumnDefinition();
|
||||||
|
ThumbnailPanel.ColumnDefinitions.Add(col_def);
|
||||||
|
|
||||||
|
Border img_border = new Border();
|
||||||
|
img_border.SetValue(Grid.ColumnProperty, i);
|
||||||
|
img_border.SetValue(Grid.RowProperty, 0);
|
||||||
|
img_border.CornerRadius = new CornerRadius(5);
|
||||||
|
|
||||||
|
StackPanel img_panel = new StackPanel();
|
||||||
|
|
||||||
|
Label camera_name_label = new Label();
|
||||||
|
camera_name_label.Content = s.Item2;
|
||||||
|
camera_name_label.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
|
||||||
|
img_panel.Children.Add(camera_name_label);
|
||||||
|
img.Height = 200;
|
||||||
|
img_panel.Children.Add(img);
|
||||||
|
img_border.Child = img_panel;
|
||||||
|
|
||||||
|
sample_images.Add(img_border);
|
||||||
|
|
||||||
|
ThumbnailPanel.Children.Add(img_border);
|
||||||
|
|
||||||
|
ComboBox resolutions = new ComboBox();
|
||||||
|
resolutions.Width = 80;
|
||||||
|
combo_boxes.Add(resolutions);
|
||||||
|
|
||||||
|
resolutions_all.Add(new List<Tuple<int, int>>());
|
||||||
|
|
||||||
|
foreach (var r in s.Item3)
|
||||||
|
{
|
||||||
|
resolutions.Items.Add(r.Item1 + "x" + r.Item2);
|
||||||
|
resolutions_all[resolutions_all.Count - 1].Add(new Tuple<int, int>(r.Item1, r.Item2));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
resolutions.SelectedIndex = 0;
|
||||||
|
for (int res = 0; res < s.Item3.Count; ++res)
|
||||||
|
{
|
||||||
|
if (s.Item3[res].Item1 >= 640 && s.Item3[res].Item2 >= 480)
|
||||||
|
{
|
||||||
|
resolutions.SelectedIndex = res;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolutions.SetValue(Grid.ColumnProperty, i);
|
||||||
|
resolutions.SetValue(Grid.RowProperty, 2);
|
||||||
|
ThumbnailPanel.Children.Add(resolutions);
|
||||||
|
|
||||||
|
img_panel.MouseDown += (sender, e) =>
|
||||||
|
{
|
||||||
|
ChooseCamera(idx);
|
||||||
|
};
|
||||||
|
|
||||||
|
resolutions.DropDownOpened += (sender, e) =>
|
||||||
|
{
|
||||||
|
ChooseCamera(idx);
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
i++;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (cams.Count > 0)
|
||||||
|
{
|
||||||
|
no_cameras_found = false;
|
||||||
|
Dispatcher.Invoke(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 0, 200), (Action)(() =>
|
||||||
|
{
|
||||||
|
ChooseCamera(0);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string messageBoxText = "No cameras detected, please connect a webcam";
|
||||||
|
string caption = "Camera error!";
|
||||||
|
MessageBoxButton button = MessageBoxButton.OK;
|
||||||
|
MessageBoxImage icon = MessageBoxImage.Warning;
|
||||||
|
MessageBox.Show(messageBoxText, caption, button, icon);
|
||||||
|
selected_camera_idx = -1;
|
||||||
|
no_cameras_found = true;
|
||||||
|
Dispatcher.Invoke(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 0, 200), (Action)(() =>
|
||||||
|
{
|
||||||
|
this.Close();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CameraSelection()
|
||||||
|
{
|
||||||
|
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
// We want to display the loading screen first
|
||||||
|
Thread load_cameras = new Thread(LoadCameras);
|
||||||
|
load_cameras.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LoadCameras()
|
||||||
|
{
|
||||||
|
Thread.CurrentThread.IsBackground = true;
|
||||||
|
PopulateCameraSelections();
|
||||||
|
|
||||||
|
Dispatcher.Invoke(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 0, 200), (Action)(() =>
|
||||||
|
{
|
||||||
|
LoadingGrid.Visibility = System.Windows.Visibility.Hidden;
|
||||||
|
camerasPanel.Visibility = System.Windows.Visibility.Visible;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
public CameraSelection(List<Tuple<int, String, List<Tuple<int, int>>, OpenCVWrappers.RawImage>> cams)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
this.cams = cams;
|
||||||
|
PopulateCameraSelections();
|
||||||
|
|
||||||
|
Dispatcher.Invoke(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 0, 200), (Action)(() =>
|
||||||
|
{
|
||||||
|
LoadingGrid.Visibility = System.Windows.Visibility.Hidden;
|
||||||
|
camerasPanel.Visibility = System.Windows.Visibility.Visible;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ChooseCamera(int idx)
|
||||||
|
{
|
||||||
|
selected_camera_idx = idx;
|
||||||
|
|
||||||
|
foreach (var img in sample_images)
|
||||||
|
{
|
||||||
|
img.BorderThickness = new Thickness(1);
|
||||||
|
img.BorderBrush = Brushes.Gray;
|
||||||
|
}
|
||||||
|
sample_images[idx].BorderThickness = new Thickness(4);
|
||||||
|
sample_images[idx].BorderBrush = Brushes.Green;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Button_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
Select();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CameraSelection_KeyDown(object sender, KeyEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Key == Key.Enter)
|
||||||
|
{
|
||||||
|
Select();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Select()
|
||||||
|
{
|
||||||
|
camera_selected = true;
|
||||||
|
|
||||||
|
int selected_res = combo_boxes[selected_camera_idx].SelectedIndex;
|
||||||
|
Tuple<int, int> resolution_selected = resolutions_all[selected_camera_idx][selected_res];
|
||||||
|
|
||||||
|
selected_camera = new Tuple<int, int, int>(selected_camera_idx, resolution_selected.Item1, resolution_selected.Item2);
|
||||||
|
|
||||||
|
this.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not close it as user might want to open it again
|
||||||
|
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -127,7 +127,11 @@
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Text Include="ReadMe.txt" />
|
<ClInclude Include="DeviceEnumerator.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="DeviceEnumerator.cpp" />
|
||||||
|
<ClCompile Include="OpenCVDeviceEnumerator.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
|
|
@ -15,6 +15,16 @@
|
||||||
</Filter>
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Text Include="ReadMe.txt" />
|
<ClInclude Include="DeviceEnumerator.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="DeviceEnumerator.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="OpenCVDeviceEnumerator.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -1,4 +1,5 @@
|
||||||
#include "DeviceEnumerator.h"
|
#include "DeviceEnumerator.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
std::map<int, Device> DeviceEnumerator::getVideoDevicesMap() {
|
std::map<int, Device> DeviceEnumerator::getVideoDevicesMap() {
|
||||||
return getDevicesMap(CLSID_VideoInputDeviceCategory);
|
return getDevicesMap(CLSID_VideoInputDeviceCategory);
|
||||||
|
@ -13,14 +14,15 @@ std::map<int, Device> DeviceEnumerator::getDevicesMap(const GUID deviceClass)
|
||||||
{
|
{
|
||||||
std::map<int, Device> deviceMap;
|
std::map<int, Device> deviceMap;
|
||||||
|
|
||||||
HRESULT hr = CoInitialize(nullptr);
|
// TODO add back? Calling from C# seems to not need this
|
||||||
if (FAILED(hr)) {
|
//HRESULT hr = CoInitialize(nullptr);
|
||||||
return deviceMap; // Empty deviceMap as an error
|
//if (FAILED(hr)) {
|
||||||
}
|
// return deviceMap; // Empty deviceMap as an error
|
||||||
|
//}
|
||||||
|
|
||||||
// Create the System Device Enumerator
|
// Create the System Device Enumerator
|
||||||
ICreateDevEnum *pDevEnum;
|
ICreateDevEnum *pDevEnum;
|
||||||
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDevEnum));
|
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDevEnum));
|
||||||
|
|
||||||
// If succeeded, create an enumerator for the category
|
// If succeeded, create an enumerator for the category
|
||||||
IEnumMoniker *pEnum = NULL;
|
IEnumMoniker *pEnum = NULL;
|
||||||
|
|
|
@ -116,7 +116,7 @@
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CPPINEROP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CPPINEROP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<AdditionalIncludeDirectories>./;$(SolutionDir)lib\local\LandmarkDetector\include;$(SolutionDir)lib\local\FaceAnalyser\include;$(SolutionDir)lib\local\GazeAnalyser\include;$(SolutionDir)lib\local\Utilities\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>./;$(SolutionDir)lib\local\LandmarkDetector\include;$(SolutionDir)lib\local\FaceAnalyser\include;$(SolutionDir)lib\local\GazeAnalyser\include;$(SolutionDir)lib\local\Utilities\include;$(SolutionDir)lib\3rdParty\CameraEnumerator;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
|
@ -130,7 +130,7 @@
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;CPPINEROP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;CPPINEROP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<AdditionalIncludeDirectories>./;$(SolutionDir)lib\local\LandmarkDetector\include;$(SolutionDir)lib\local\FaceAnalyser\include;$(SolutionDir)lib\local\GazeAnalyser\include;$(SolutionDir)lib\local\Utilities\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>./;$(SolutionDir)lib\local\LandmarkDetector\include;$(SolutionDir)lib\local\FaceAnalyser\include;$(SolutionDir)lib\local\GazeAnalyser\include;$(SolutionDir)lib\local\Utilities\include;$(SolutionDir)lib\3rdParty\CameraEnumerator;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
|
@ -146,7 +146,7 @@
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CPPINEROP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CPPINEROP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<AdditionalIncludeDirectories>./;$(SolutionDir)lib\local\LandmarkDetector\include;$(SolutionDir)lib\local\FaceAnalyser\include;$(SolutionDir)lib\local\GazeAnalyser\include;$(SolutionDir)lib\local\Utilities\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>./;$(SolutionDir)lib\local\LandmarkDetector\include;$(SolutionDir)lib\local\FaceAnalyser\include;$(SolutionDir)lib\local\GazeAnalyser\include;$(SolutionDir)lib\local\Utilities\include;$(SolutionDir)lib\3rdParty\CameraEnumerator;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
|
@ -164,7 +164,7 @@
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;CPPINEROP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;CPPINEROP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<AdditionalIncludeDirectories>./;$(SolutionDir)lib\local\LandmarkDetector\include;$(SolutionDir)lib\local\FaceAnalyser\include;$(SolutionDir)lib\local\GazeAnalyser\include;$(SolutionDir)lib\local\Utilities\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>./;$(SolutionDir)lib\local\LandmarkDetector\include;$(SolutionDir)lib\local\FaceAnalyser\include;$(SolutionDir)lib\local\GazeAnalyser\include;$(SolutionDir)lib\local\Utilities\include;$(SolutionDir)lib\3rdParty\CameraEnumerator;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
|
@ -190,6 +190,9 @@
|
||||||
<ClInclude Include="VisualizerInterop.h" />
|
<ClInclude Include="VisualizerInterop.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\3rdParty\CameraEnumerator\CameraEnumerator.vcxproj">
|
||||||
|
<Project>{50b7d4bf-e33b-41d0-aa89-76bba57bf5cc}</Project>
|
||||||
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\..\3rdParty\dlib\dlib.vcxproj">
|
<ProjectReference Include="..\..\3rdParty\dlib\dlib.vcxproj">
|
||||||
<Project>{b47a5f12-2567-44e9-ae49-35763ec82149}</Project>
|
<Project>{b47a5f12-2567-44e9-ae49-35763ec82149}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
|
|
@ -211,181 +211,186 @@ namespace UtilitiesOF {
|
||||||
{
|
{
|
||||||
this->!SequenceReader();
|
this->!SequenceReader();
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
private:
|
||||||
static void split(const std::string &s, char delim, std::vector<string> &elems) {
|
// Static methods for listing cameras and their resolutions
|
||||||
std::stringstream ss;
|
static void split(const std::string &s, char delim, std::vector<string> &elems) {
|
||||||
ss.str(s);
|
std::stringstream ss;
|
||||||
std::string item;
|
ss.str(s);
|
||||||
while (std::getline(ss, item, delim)) {
|
std::string item;
|
||||||
elems.push_back(item);
|
while (std::getline(ss, item, delim)) {
|
||||||
}
|
elems.push_back(item);
|
||||||
}
|
|
||||||
|
|
||||||
// Camera listing is camera name and supported resolutions
|
|
||||||
static Dictionary<System::String^, List<System::Tuple<int, int>^>^>^ GetListingFromFile(std::string filename)
|
|
||||||
{
|
|
||||||
// Check what cameras have been written (using OpenCVs XML packages)
|
|
||||||
cv::FileStorage fs_read(filename, cv::FileStorage::READ);
|
|
||||||
|
|
||||||
auto managed_camera_list_initial = gcnew Dictionary<System::String^, List<System::Tuple<int, int>^>^>();
|
|
||||||
|
|
||||||
cv::FileNode camera_node_list = fs_read["cameras"];
|
|
||||||
|
|
||||||
// iterate through a sequence using FileNodeIterator
|
|
||||||
for (size_t idx = 0; idx < camera_node_list.size(); idx++)
|
|
||||||
{
|
|
||||||
std::string camera_name = (std::string)camera_node_list[idx]["name"];
|
|
||||||
|
|
||||||
cv::FileNode resolution_list = camera_node_list[idx]["resolutions"];
|
|
||||||
auto resolutions = gcnew System::Collections::Generic::List<System::Tuple<int, int>^>();
|
|
||||||
for (size_t r_idx = 0; r_idx < resolution_list.size(); r_idx++)
|
|
||||||
{
|
|
||||||
string res = resolution_list[r_idx]["res"];
|
|
||||||
|
|
||||||
std::vector<std::string> elems;
|
|
||||||
split(res, 'x', elems);
|
|
||||||
|
|
||||||
int x = stoi(elems[0]);
|
|
||||||
int y = stoi(elems[1]);
|
|
||||||
resolutions->Add(gcnew System::Tuple<int, int>(x, y));
|
|
||||||
}
|
}
|
||||||
managed_camera_list_initial[gcnew System::String(camera_name.c_str())] = resolutions;
|
|
||||||
}
|
}
|
||||||
fs_read.release();
|
|
||||||
return managed_camera_list_initial;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void WriteCameraListingToFile(System::Collections::Generic::Dictionary<System::String^, System::Collections::Generic::List<System::Tuple<int, int>^>^>^ camera_list, std::string filename)
|
// Camera listing is camera name and supported resolutions
|
||||||
{
|
static Dictionary<System::String^, List<System::Tuple<int, int>^>^>^ GetListingFromFile(std::string filename)
|
||||||
cv::FileStorage fs("camera_list.xml", cv::FileStorage::WRITE);
|
|
||||||
|
|
||||||
fs << "cameras" << "[";
|
|
||||||
for each(System::String^ name_m in camera_list->Keys)
|
|
||||||
{
|
{
|
||||||
|
// Check what cameras have been written (using OpenCVs XML packages)
|
||||||
|
cv::FileStorage fs_read(filename, cv::FileStorage::READ);
|
||||||
|
|
||||||
std::string name = msclr::interop::marshal_as<std::string>(name_m);
|
auto managed_camera_list_initial = gcnew Dictionary<System::String^, List<System::Tuple<int, int>^>^>();
|
||||||
|
|
||||||
fs << "{:" << "name" << name;
|
cv::FileNode camera_node_list = fs_read["cameras"];
|
||||||
fs << "resolutions" << "[";
|
|
||||||
auto resolutions = camera_list[name_m];
|
// iterate through a sequence using FileNodeIterator
|
||||||
for (int j = 0; j < resolutions->Count; j++)
|
for (size_t idx = 0; idx < camera_node_list.size(); idx++)
|
||||||
{
|
{
|
||||||
stringstream ss;
|
std::string camera_name = (std::string)camera_node_list[idx]["name"];
|
||||||
ss << resolutions[j]->Item1 << "x" << resolutions[j]->Item2;
|
|
||||||
|
|
||||||
fs << "{:" << "res" << ss.str();
|
cv::FileNode resolution_list = camera_node_list[idx]["resolutions"];
|
||||||
|
auto resolutions = gcnew System::Collections::Generic::List<System::Tuple<int, int>^>();
|
||||||
|
for (size_t r_idx = 0; r_idx < resolution_list.size(); r_idx++)
|
||||||
|
{
|
||||||
|
string res = resolution_list[r_idx]["res"];
|
||||||
|
|
||||||
|
std::vector<std::string> elems;
|
||||||
|
split(res, 'x', elems);
|
||||||
|
|
||||||
|
int x = stoi(elems[0]);
|
||||||
|
int y = stoi(elems[1]);
|
||||||
|
resolutions->Add(gcnew System::Tuple<int, int>(x, y));
|
||||||
|
}
|
||||||
|
managed_camera_list_initial[gcnew System::String(camera_name.c_str())] = resolutions;
|
||||||
|
}
|
||||||
|
fs_read.release();
|
||||||
|
return managed_camera_list_initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteCameraListingToFile(System::Collections::Generic::Dictionary<System::String^, System::Collections::Generic::List<System::Tuple<int, int>^>^>^ camera_list, std::string filename)
|
||||||
|
{
|
||||||
|
cv::FileStorage fs("camera_list.xml", cv::FileStorage::WRITE);
|
||||||
|
|
||||||
|
fs << "cameras" << "[";
|
||||||
|
for each(System::String^ name_m in camera_list->Keys)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string name = msclr::interop::marshal_as<std::string>(name_m);
|
||||||
|
|
||||||
|
fs << "{:" << "name" << name;
|
||||||
|
fs << "resolutions" << "[";
|
||||||
|
auto resolutions = camera_list[name_m];
|
||||||
|
for (int j = 0; j < resolutions->Count; j++)
|
||||||
|
{
|
||||||
|
stringstream ss;
|
||||||
|
ss << resolutions[j]->Item1 << "x" << resolutions[j]->Item2;
|
||||||
|
|
||||||
|
fs << "{:" << "res" << ss.str();
|
||||||
|
fs << "}";
|
||||||
|
}
|
||||||
|
fs << "]";
|
||||||
fs << "}";
|
fs << "}";
|
||||||
}
|
}
|
||||||
fs << "]";
|
fs << "]";
|
||||||
fs << "}";
|
fs.release();
|
||||||
}
|
|
||||||
fs << "]";
|
|
||||||
fs.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
// A utility for listing the currently connected cameras together with their ID, name, subset of supported resolutions and a thumbnail
|
|
||||||
static List<System::Tuple<int, System::String^, List<System::Tuple<int, int>^>^, OpenCVWrappers::RawImage^>^>^ GetCameras(System::String^ root_directory_m)
|
|
||||||
{
|
|
||||||
auto managed_camera_list = gcnew List<System::Tuple<int, System::String^, List<System::Tuple<int, int>^>^, OpenCVWrappers::RawImage^>^>();
|
|
||||||
|
|
||||||
DeviceEnumerator de;
|
|
||||||
|
|
||||||
// Get a listing of all connected video devices
|
|
||||||
std::map<int, Device> cameras = de.getVideoDevicesMap();
|
|
||||||
|
|
||||||
// Print information about the devices
|
|
||||||
for (auto const &device : cameras) {
|
|
||||||
std::cout << "== VIDEO DEVICE (id:" << device.first << ") ==" << std::endl;
|
|
||||||
std::cout << "Name: " << device.second.deviceName << std::endl;
|
|
||||||
std::cout << "Path: " << device.second.devicePath << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t num_cameras = cameras.size();
|
// A utility for listing the currently connected cameras together with their ID, name, subset of supported resolutions and a thumbnail
|
||||||
|
public:
|
||||||
// Pre-load supported camera resolutions if already computed
|
static List<System::Tuple<int, System::String^, List<System::Tuple<int, int>^>^, OpenCVWrappers::RawImage^>^>^ GetCameras(System::String^ root_directory_m)
|
||||||
std::string root_directory = msclr::interop::marshal_as<std::string>(root_directory_m);
|
|
||||||
auto camera_resolution_list = GetListingFromFile(root_directory + "camera_list.xml");
|
|
||||||
|
|
||||||
for (size_t i = 0; i < num_cameras; ++i)
|
|
||||||
{
|
{
|
||||||
// Thumbnail to help with camera selection
|
auto managed_camera_list = gcnew List<System::Tuple<int, System::String^, List<System::Tuple<int, int>^>^, OpenCVWrappers::RawImage^>^>();
|
||||||
cv::Mat sample_img;
|
|
||||||
OpenCVWrappers::RawImage^ sample_img_managed = gcnew OpenCVWrappers::RawImage();
|
|
||||||
|
|
||||||
auto resolutions = gcnew List<System::Tuple<int, int>^>();
|
DeviceEnumerator de;
|
||||||
|
|
||||||
// Before trying the resolutions, check if the resolutions have already been computed for the camera of interest
|
// Get a listing of all connected video devices
|
||||||
std::string device_name = cameras[i].deviceName;
|
std::map<int, Device> cameras = de.getVideoDevicesMap();
|
||||||
System::String^ device_name_m = gcnew System::String(device_name.c_str());
|
|
||||||
if (camera_resolution_list->ContainsKey(device_name_m))
|
//std::cout << "Number of cameras found: " << cameras.size() << std::endl;
|
||||||
|
//// Print information about the devices
|
||||||
|
//for (auto const &device : cameras) {
|
||||||
|
// std::cout << "== VIDEO DEVICE (id:" << device.first << ") ==" << std::endl;
|
||||||
|
// std::cout << "Name: " << device.second.deviceName << std::endl;
|
||||||
|
// std::cout << "Path: " << device.second.devicePath << std::endl;
|
||||||
|
//}
|
||||||
|
|
||||||
|
size_t num_cameras = cameras.size();
|
||||||
|
|
||||||
|
// Pre-load supported camera resolutions if already computed
|
||||||
|
std::string root_directory = msclr::interop::marshal_as<std::string>(root_directory_m);
|
||||||
|
auto camera_resolution_list = GetListingFromFile(root_directory + "camera_list.xml");
|
||||||
|
|
||||||
|
for (size_t i = 0; i < num_cameras; ++i)
|
||||||
{
|
{
|
||||||
resolutions = camera_resolution_list[device_name_m];
|
// Thumbnail to help with camera selection
|
||||||
|
cv::Mat sample_img;
|
||||||
|
OpenCVWrappers::RawImage^ sample_img_managed = gcnew OpenCVWrappers::RawImage();
|
||||||
|
|
||||||
// Grab a thumbnail from mid resolution
|
auto resolutions = gcnew List<System::Tuple<int, int>^>();
|
||||||
cv::VideoCapture cap1(i);
|
|
||||||
|
|
||||||
auto resolution = resolutions[(int)(resolutions->Count / 2)];
|
// Before trying the resolutions, check if the resolutions have already been computed for the camera of interest
|
||||||
cap1.set(CV_CAP_PROP_FRAME_WIDTH, resolution->Item1);
|
std::string device_name = cameras[i].deviceName;
|
||||||
cap1.set(CV_CAP_PROP_FRAME_HEIGHT, resolution->Item2);
|
System::String^ device_name_m = gcnew System::String(device_name.c_str());
|
||||||
|
if (camera_resolution_list->ContainsKey(device_name_m))
|
||||||
// Read several frames, as the first one often is over-exposed
|
|
||||||
for (int k = 0; k < 2; ++k)
|
|
||||||
cap1.read(sample_img);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
// A common set of resolutions for webcams
|
|
||||||
std::vector<std::pair<int, int>> common_resolutions;
|
|
||||||
common_resolutions.push_back(std::pair<int, int>(320, 240));
|
|
||||||
common_resolutions.push_back(std::pair<int, int>(640, 480));
|
|
||||||
common_resolutions.push_back(std::pair<int, int>(960, 720));
|
|
||||||
common_resolutions.push_back(std::pair<int, int>(1280, 720));
|
|
||||||
common_resolutions.push_back(std::pair<int, int>(1280, 960));
|
|
||||||
common_resolutions.push_back(std::pair<int, int>(1920, 1080));
|
|
||||||
|
|
||||||
// Grab some sample images and confirm the resolutions
|
|
||||||
cv::VideoCapture cap1(i);
|
|
||||||
|
|
||||||
// Go through resolutions if they have not been identified
|
|
||||||
for (size_t i = 0; i < common_resolutions.size(); ++i)
|
|
||||||
{
|
{
|
||||||
auto resolution = gcnew System::Tuple<int, int>(common_resolutions[i].first, common_resolutions[i].second);
|
resolutions = camera_resolution_list[device_name_m];
|
||||||
|
|
||||||
|
// Grab a thumbnail from mid resolution
|
||||||
|
cv::VideoCapture cap1(i);
|
||||||
|
|
||||||
|
auto resolution = resolutions[(int)(resolutions->Count / 2)];
|
||||||
cap1.set(CV_CAP_PROP_FRAME_WIDTH, resolution->Item1);
|
cap1.set(CV_CAP_PROP_FRAME_WIDTH, resolution->Item1);
|
||||||
cap1.set(CV_CAP_PROP_FRAME_HEIGHT, resolution->Item2);
|
cap1.set(CV_CAP_PROP_FRAME_HEIGHT, resolution->Item2);
|
||||||
|
|
||||||
// Add only valid resolutions as API sometimes provides wrong ones
|
// Read several frames, as the first one often is over-exposed
|
||||||
int set_width = cap1.get(CV_CAP_PROP_FRAME_WIDTH);
|
for (int k = 0; k < 2; ++k)
|
||||||
int set_height = cap1.get(CV_CAP_PROP_FRAME_HEIGHT);
|
cap1.read(sample_img);
|
||||||
|
|
||||||
// Grab a thumbnail from mid resolution
|
|
||||||
if(i == (int)common_resolutions.size()/2)
|
|
||||||
{
|
|
||||||
// Read several frames, as the first one often is over-exposed
|
|
||||||
for (int k = 0; k < 2; ++k)
|
|
||||||
cap1.read(sample_img);
|
|
||||||
}
|
|
||||||
|
|
||||||
resolution = gcnew System::Tuple<int, int>(set_width, set_height);
|
|
||||||
if (!resolutions->Contains(resolution))
|
|
||||||
{
|
|
||||||
resolutions->Add(resolution);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
cap1.~VideoCapture();
|
else
|
||||||
|
{
|
||||||
|
|
||||||
// Ass the resolutions were not on the list, add them now
|
// A common set of resolutions for webcams
|
||||||
camera_resolution_list[device_name_m] = resolutions;
|
std::vector<std::pair<int, int>> common_resolutions;
|
||||||
WriteCameraListingToFile(camera_resolution_list, root_directory + "camera_list.xml");
|
common_resolutions.push_back(std::pair<int, int>(320, 240));
|
||||||
|
common_resolutions.push_back(std::pair<int, int>(640, 480));
|
||||||
|
common_resolutions.push_back(std::pair<int, int>(960, 720));
|
||||||
|
common_resolutions.push_back(std::pair<int, int>(1280, 720));
|
||||||
|
common_resolutions.push_back(std::pair<int, int>(1280, 960));
|
||||||
|
common_resolutions.push_back(std::pair<int, int>(1920, 1080));
|
||||||
|
|
||||||
|
// Grab some sample images and confirm the resolutions
|
||||||
|
cv::VideoCapture cap1(i);
|
||||||
|
|
||||||
|
// Go through resolutions if they have not been identified
|
||||||
|
for (size_t i = 0; i < common_resolutions.size(); ++i)
|
||||||
|
{
|
||||||
|
auto resolution = gcnew System::Tuple<int, int>(common_resolutions[i].first, common_resolutions[i].second);
|
||||||
|
|
||||||
|
cap1.set(CV_CAP_PROP_FRAME_WIDTH, resolution->Item1);
|
||||||
|
cap1.set(CV_CAP_PROP_FRAME_HEIGHT, resolution->Item2);
|
||||||
|
|
||||||
|
// Add only valid resolutions as API sometimes provides wrong ones
|
||||||
|
int set_width = cap1.get(CV_CAP_PROP_FRAME_WIDTH);
|
||||||
|
int set_height = cap1.get(CV_CAP_PROP_FRAME_HEIGHT);
|
||||||
|
|
||||||
|
// Grab a thumbnail from mid resolution
|
||||||
|
if (i == (int)common_resolutions.size() / 2)
|
||||||
|
{
|
||||||
|
// Read several frames, as the first one often is over-exposed
|
||||||
|
for (int k = 0; k < 2; ++k)
|
||||||
|
cap1.read(sample_img);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolution = gcnew System::Tuple<int, int>(set_width, set_height);
|
||||||
|
if (!resolutions->Contains(resolution))
|
||||||
|
{
|
||||||
|
resolutions->Add(resolution);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cap1.~VideoCapture();
|
||||||
|
|
||||||
|
// Ass the resolutions were not on the list, add them now
|
||||||
|
camera_resolution_list[device_name_m] = resolutions;
|
||||||
|
WriteCameraListingToFile(camera_resolution_list, root_directory + "camera_list.xml");
|
||||||
|
}
|
||||||
|
sample_img.copyTo(sample_img_managed->Mat);
|
||||||
|
|
||||||
|
managed_camera_list->Add(gcnew System::Tuple<int, System::String^, List<System::Tuple<int, int>^>^, OpenCVWrappers::RawImage^>(i, device_name_m, resolutions, sample_img_managed));
|
||||||
}
|
}
|
||||||
sample_img.copyTo(sample_img_managed->Mat);
|
|
||||||
|
|
||||||
managed_camera_list->Add(gcnew System::Tuple<int, System::String^, List<System::Tuple<int, int>^>^, OpenCVWrappers::RawImage^>(i, device_name_m, resolutions, sample_img_managed));
|
return managed_camera_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
return managed_camera_list;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue