facial_recognition_photobooth/CrestronOpenCvSharp/Capture/MjpegCapture.cs

138 lines
No EOL
5.2 KiB
C#

using Crestron.SimplSharp;
using PhotoBooth;
using RandomNameGeneratorLibrary;
using Timeout = System.Threading.Timeout;
namespace CrestronOpenCvSharp.Capture;
public class MjpegCapture
{
private readonly HttpClient _client = new HttpClient();
private readonly string? _mjpegUrl;
private readonly string? _directory;
private readonly FacialRecognition? _facialRecognition;
private Timer? _timer;
private readonly PersonNameGenerator _personNameGenerator;
private Contract _contract;
public bool CaptureRunning { get; private set; }
private const string BaseUrl = "https://ise2025.local.staal.one/VirtualControl/MA/Rooms/MYFIRSTAI/Html/";
public MjpegCapture(string? url, string? directory, FacialRecognition? facialRecognition, Contract contract)
{
_mjpegUrl = url;
_directory = Path.Combine(directory!, "captures");
_facialRecognition = facialRecognition;
_contract = contract;
_personNameGenerator = new PersonNameGenerator();
}
public void StartCapture(int timeout)
{
if (string.IsNullOrEmpty(_directory))
{
Console.WriteLine("Directory variable was null or empty.");
CaptureRunning = false;
return;
}
CheckIfDirectoryExists(_directory);
// Only create if it's null
_timer = new Timer(CaptureImage, null, 0, timeout);
CaptureRunning = true;
}
public void StopCapture()
{
if (_timer is not null)
{
// Stop the timer
_timer.Change(Timeout.Infinite, Timeout.Infinite);
// Dispose it
_timer.Dispose();
}
CaptureRunning = false;
}
private void CheckIfDirectoryExists(string directory)
{
Console.WriteLine($"Checking if directory {directory} exists.");
if (Directory.Exists(directory))
{
// Remove the directory and all its contents
Directory.Delete(directory, true);
Console.WriteLine($"Directory '{directory}' and all its contents have been removed.");
Directory.CreateDirectory(directory);
Console.WriteLine($"Directory '{directory}' has been created.");
}
else
{
// Create the directory
Directory.CreateDirectory(directory);
Console.WriteLine($"Directory '{directory}' has been created.");
}
}
private async void CaptureImage(object? state)
{
try
{
CaptureRunning = true;
var uniqueName = $"frame_{DateTime.Now:yyyyMMdd_HHmmss}.jpg";
var fileName = Path.Combine(_directory!, uniqueName);
try
{
HttpResponseMessage response = await _client.GetAsync(_mjpegUrl, HttpCompletionOption.ResponseHeadersRead);
response.EnsureSuccessStatusCode();
await using (var stream = await response.Content.ReadAsStreamAsync())
await using (var fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
{
await stream.CopyToAsync(fileStream);
}
Console.WriteLine($"Saved frame to {fileName}");
_contract.Main.ImagePreview_Url(string.Format($"{BaseUrl}/captures/{uniqueName}"));
Console.WriteLine($"Sending URL {string.Format($"{BaseUrl}/captures/{uniqueName}")}");
if (_facialRecognition!.CheckForFace(fileName))
{
StopCapture();
_contract.Main.ImagePreview_Url(string.Empty);
Thread.Sleep(1000);
Console.WriteLine("Face detected, stopping capture");
Console.WriteLine("Comparing captured face against database");
var result = await _facialRecognition.CompareFaces();
if (result is not null)
{
Console.WriteLine($"We have found a match! The person in front of the camera is: {result}");
_contract.Main.txtFeedback_Indirect($"{result} detected!");
}
else
{
Console.WriteLine("No match was found in our database, let's add this person!");
var randomFullName = _personNameGenerator.GenerateRandomFirstAndLastName();
_facialRecognition.AddPersonToDatabase(randomFullName);
Console.WriteLine("Person added to database");
_contract.Main.txtFeedback_Indirect($"{randomFullName} added to database");
}
}
else
{
Console.WriteLine("No face detected, carrying on!");
_contract.Main.txtFeedback_Indirect($"No face detected!");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error capturing image: {ex.Message}");
}
}
catch (Exception e)
{
Console.WriteLine($"Error capturing image: {e}");
}
}
}