agrobot_base/AgroBase/AgroBase/Models/CameraCaminhoModel.cs

257 lines
8.6 KiB
C#

using AgroBase.Services;
using CefSharp.WinForms;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AgroBase.Models
{
public class CameraCaminhoModel
{
public AsyncTaskTimerModel tmrLeitura;
public Bitmap bitmapSegmentado;
public string ID { get; set; }
public string Nome { get; set; }
public int Posicao { get; set; }
public bool Iniciada { get; set; } = false;
public CameraService camera { get; set; }
public ChromiumWebBrowser browser { get; set; }
public Panel panel { get; set; }
public ComboBox combo { get; set; }
public string ArquivoLeitura { get; set; }
public int MaxLeituras { get; set; }
public string VideoPorta { get; set; }
public string VideoUrl { get; set; }
public string CameraSelecionada { get; set; }
public Dictionary<string, Color> ClassMap = new Dictionary<string, Color>()
{
{ "background", Color.Black },
{ "rua", Color.DarkRed },
{ "cana", Color.DarkGreen },
{ "ceu", Color.Gold },
};
public CameraDeepLabV3PlusModel Leitura { get; set; } = new CameraDeepLabV3PlusModel();
public List<Point> PontosExtremos { get; set; } = new List<Point>();
public double Angulo { get; set; }
public double AnguloEsquerdo { get; set; }
public double AnguloDireito { get; set; }
public DateTime UltimoEnvio { get; set; } = DateTime.MinValue;
private int DelayEnvio { get; set; } = 500;
public CameraCaminhoModel()
{
}
public void InicializarCamera()
{
List<AsyncTaskTimerModel> timers = new List<AsyncTaskTimerModel>();
tmrLeitura?.Dispose();
tmrLeitura = new AsyncTaskTimerModel("tmrLeitura_" + ID, tmrLeitura_Tick, 100);
tmrLeitura.Start();
}
public void DesligarCamera()
{
try
{
tmrLeitura?.Dispose();
Iniciada = false;
Variaveis.MqttService.Topicos.Remove(camera._mqttTopico);
if (panel != null)
{
panel.Controls.Remove(browser);
}
browser = null;
Task.Run(async () => await Variaveis.MqttService.UnsubscribeAsync(camera._mqttTopico));
if (camera.pythonProcess != null)
{
camera.pythonProcess.Kill();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private async Task tmrLeitura_Tick()
{
if (Iniciada)
{
DateTime Agora = DateTime.Now;
// Se ja passou 5 segundos sem ter enviado uma mensagem
if (UltimoEnvio.AddMilliseconds(5000) < Agora)
{
//await Variaveis.MqttService.AdicionarNovoTopico(CamerasVaraiveisModel.TopicoRecebimentoBitmap, true);
await EnviarBitmapParaProcessamento();
}
}
}
public async Task EnviarBitmapParaProcessamento()
{
Bitmap bitmap = null;
lock (KinectService._lockBitmapRGB)
{
bitmap = (Bitmap)KinectService.bitmapRGB.Clone();
}
//Console.WriteLine("Enviando bitmap para segmentacao...");
// Converta o Bitmap para um array de bytes no formato JPEG
byte[] bitmapBytes;
using (var ms = new MemoryStream())
{
bitmap.Save(ms, ImageFormat.Jpeg);
bitmapBytes = ms.ToArray();
}
var topico = Variaveis.MqttService.Topicos.FirstOrDefault(x => x.Topico == CamerasVaraiveisModel.TopicoEnvioBitmap);
if (topico != null)
{
// Publique o array de bytes via MQTT
await Variaveis.MqttService.PublishAsync(
topico,
bitmapBytes
);
UltimoEnvio = DateTime.Now;
}
}
public Bitmap ExtraiImagemDaMensagem(string message)
{
// Decodificar o payload JSON
dynamic jsonData = JsonConvert.DeserializeObject(message);
// Extrair a imagem base64 do JSON
string imageBase64 = jsonData.segmented_image;
// Converter a string base64 de volta para um array de bytes
byte[] imageBytes = Convert.FromBase64String(imageBase64);
// Converter o array de bytes em um Bitmap
using (var ms = new MemoryStream(imageBytes))
{
Bitmap bitmap = new Bitmap(ms);
return bitmap;
}
}
public async Task AtualizarBitmapTela(Bitmap bitmap)
{
//Console.WriteLine("Recebido bitmap segmentado");
await FuncoesGlobais.ExecutarMetodoComVerificacaoCrossThreadAsync(panel, async () =>
{
bitmapSegmentado = bitmap;
if (panel != null)
{
panel.BackgroundImage = bitmapSegmentado;
panel.Refresh();
}
});
await Task.Delay(DelayEnvio);
await EnviarBitmapParaProcessamento();
}
public static List<Point> DefinirPontosExtremos(List<Point> PontosCamera)
{
if (!PontosCamera.Any())
{
return new List<Point>();
}
List<Point> Pontos = new List<Point>()
{
new Point(9999, -1), // Ponto 0 - Mais a esquerda e abaixo
new Point(9999, -1), // Ponto 1 - Mais a esquerda e abaixo, e esquerda > Ponto0.X
new Point(9999, 9999), // Ponto 2 - Mais a esquerda e acima
new Point(-1, 9999), // Ponto 3 - Mais a direita e acima
new Point(-1, -1), // Ponto 4 - Mais a direita e abaixo, e direita < Ponto5.X
new Point(-1, -1), // Ponto 5 - Mais a direita e abaixo
};
foreach (var Ponto in PontosCamera)
{
// Ponto 0 - Mais a esquerda e abaixo
if (Ponto.X < Pontos[0].X)
{
Pontos[0] = new Point() { X = Ponto.X, Y = Ponto.Y };
}
// Ponto 5 - Mais a direita e abaixo
if (Ponto.X > Pontos[5].X)
{
Pontos[5] = new Point() { X = Ponto.X, Y = Ponto.Y };
}
}
var Ponto0 = PontosCamera.Where(Ponto => Ponto.X == Pontos[0].X).OrderByDescending(Ponto => Ponto.Y).First();
Pontos[0] = Ponto0;
var Ponto5 = PontosCamera.Where(Ponto => Ponto.X == Pontos[5].X).OrderByDescending(Ponto => Ponto.Y).First();
Pontos[5] = Ponto5;
foreach (var Ponto in PontosCamera)
{
// Ponto 1 - Mais a esquerda e abaixo, e esquerda > Ponto0.X
if (Ponto.X < Pontos[1].X && Ponto.X > Ponto0.X)
{
Pontos[1] = new Point() { X = Ponto.X, Y = Ponto.Y };
}
// Ponto 4 Mais a direita e abaixo, e direita < Ponto5.X
if (Ponto.X > Pontos[4].X && Ponto.X < Ponto5.X)
{
Pontos[4] = new Point() { X = Ponto.X, Y = Ponto.Y };
}
}
var Ponto1 = PontosCamera.Where(Ponto => Ponto.X == Pontos[1].X).OrderByDescending(Ponto => Ponto.Y).First();
Pontos[1] = Ponto1;
var Ponto4 = PontosCamera.Where(Ponto => Ponto.X == Pontos[4].X).OrderByDescending(Ponto => Ponto.Y).First();
Pontos[4] = Ponto4;
int Y_min = PontosCamera.OrderBy(Ponto => Ponto.Y).First().Y;
foreach (var Ponto in PontosCamera.Where(x => x.Y == Y_min))
{
// Ponto 2 - Mais a esquerda e acima
if (Ponto.X < Pontos[2].X)
{
Pontos[2] = new Point() { X = Ponto.X, Y = Ponto.Y };
}
// Ponto 3 - Mais a direita e acima
if (Ponto.X > Pontos[3].X)
{
Pontos[3] = new Point() { X = Ponto.X, Y = Ponto.Y };
}
}
return Pontos;
}
}
}