agrobot_base/AgroBase/AgroBase/Forms/Movimentacao/frmMovCamera.cs

322 lines
12 KiB
C#
Raw Normal View History

using AgroBase.Models;
using AgroBase.Services;
using CefSharp.WinForms;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AgroBase.Forms.Movimentacao
{
public partial class frmMovCamera : Form
{
private List<CameraDeepLabV3PlusModel> Leituras;
private Dictionary<string, Color> ClassMap = new Dictionary<string, Color>()
{
{ "background", Color.Black },
{ "rua", Color.DarkRed },
{ "cana", Color.DarkGreen },
{ "ceu", Color.Gold },
};
private CameraService cameraService = new CameraService();
private ChromiumWebBrowser chromiumWebBrowser = null;
private Timer tmrLeitura;
private int MaxLeituras = 1;
private string VideoPorta = VariaveisPortas.CameraCaminho.ToString();
private string VideoUrl = "street_detector";
private string SocketPorta = VariaveisPortas.SocketCaminho.ToString();
private bool MostrarDebug = true;
private string ArquivoLeitura = "leitura_solo.json";
public frmMovCamera()
{
InitializeComponent();
// Ativa o double buffering
this.DoubleBuffered = true;
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
pnlContornos.GetType().GetMethod("SetStyle", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).Invoke(pnlContornos, new object[] { ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true });
}
private void frmMovCamera_Load(object sender, EventArgs e)
{
AtualizaListaCameras();
cmbClasse.Items.Clear();
cmbClasse.Items.AddRange(ClassMap.Keys.ToArray());
cmbClasse.SelectedIndex = 0;
}
private void frmMovCamera_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
tmrLeitura.Stop();
Variaveis.MqttService.UnsubscribeAsync(cameraService._mqttTopico).GetAwaiter().GetResult();
cameraService.pythonProcess.Kill();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private void TmrLeitura_Tick(object sender, EventArgs e)
{
DesenharContornos();
}
private void pnlContornos_Paint(object sender, PaintEventArgs e)
{
if (Leituras == null || Leituras.Count == 0) return;
Graphics graphics = e.Graphics;
graphics.Clear(pnlContornos.BackColor); // Limpa o fundo
// Determina as dimensões máximas dos contornos
float larguraMaxContornos = 512; // Substitua pelo valor real
float alturaMaxContornos = 512; // Substitua pelo valor real
// Proporção de escala baseada no tamanho do Panel e nas dimensões dos contornos
float proporcaoX = pnlContornos.Width / larguraMaxContornos;
float proporcaoY = pnlContornos.Height / alturaMaxContornos;
float escala = Math.Min(proporcaoX, proporcaoY); // Mantém a proporção sem distorcer
// Calcula o novo tamanho dos contornos após o redimensionamento
float novaLargura = larguraMaxContornos * escala;
float novaAltura = alturaMaxContornos * escala;
// Calcula o deslocamento para centralizar os contornos no Panel
float deslocamentoX = (pnlContornos.Width - novaLargura) / 2;
float deslocamentoY = (pnlContornos.Height - novaAltura) / 2;
List<Point> pontosCamera = new List<Point>();
var Classe = ClassMap.FirstOrDefault(x => x.Key == cmbClasse.Text);
foreach (var Leitura in Leituras.OrderByDescending(x => x.timestamp))
{
foreach (var cameraClass in Leitura.Classes.Where(x => x.Classe == Classe.Key))
{
if (cameraClass.Contornos == null || cameraClass.Contornos.Length == 0) continue;
using (Pen pen = new Pen(Color.Blue, 2))
{
for (int i = 0; i < cameraClass.Contornos.Length - 1; i++)
{
Point contorno = new Point() { X = cameraClass.Contornos[i][0], Y = cameraClass.Contornos[i][1] };
Point contornoP = new Point() { X = cameraClass.Contornos[i + 1][0], Y = cameraClass.Contornos[i + 1][1] };
// Aplica a escala e o deslocamento às coordenadas
Point start = new Point((int)(contorno.X * escala + deslocamentoX), (int)(contorno.Y * escala + deslocamentoY));
Point end = new Point((int)(contornoP.X * escala + deslocamentoX), (int)(contornoP.Y * escala + deslocamentoY));
graphics.DrawLine(pen, start, end);
pontosCamera.Add(contorno);
}
// Se necessário, fechar o contorno conectando o último ponto ao primeiro
if (cameraClass.Contornos.Length > 1)
{
var primeiro = cameraClass.Contornos.First();
var ultimo = cameraClass.Contornos.Last();
Point start = new Point((int)(ultimo[0] * escala + deslocamentoX), (int)(ultimo[1] * escala + deslocamentoY));
Point end = new Point((int)(primeiro[0] * escala + deslocamentoX), (int)(primeiro[1] * escala + deslocamentoY));
graphics.DrawLine(pen, start, end);
}
}
}
// Plotar apenas a ultima leitura do json
break;
}
using (Pen pen = new Pen(Classe.Value, 2))
{
var PontosExtremos = DefinirPontosExtremos(pontosCamera);
for (int i = 0; i < PontosExtremos.Count - 1; i++)
{
// Aplica a escala e o deslocamento às coordenadas
Point start = new Point((int)(PontosExtremos[i].X * escala + deslocamentoX), (int)(PontosExtremos[i].Y * escala + deslocamentoY));
Point end = new Point((int)(PontosExtremos[i + 1].X * escala + deslocamentoX), (int)(PontosExtremos[i + 1].Y * escala + deslocamentoY));
graphics.DrawLine(pen, start, end);
}
}
}
private 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;
}
private void btnDesenhar_Click(object sender, EventArgs e)
{
DesenharContornos();
}
private void DesenharContornos()
{
if (chromiumWebBrowser == null)
{
chromiumWebBrowser = new ChromiumWebBrowser(cameraService.URLcamera);
this.pnlCamera.Controls.Add(chromiumWebBrowser);
chromiumWebBrowser.Dock = DockStyle.Fill;
}
try
{
var contornosJson = File.ReadAllText("Python/Output/" + ArquivoLeitura);
Leituras = JsonConvert.DeserializeObject<CameraDeepLabV3PlusModel[]>(contornosJson).ToList();
//Leituras = cameraService.socket.DadosRecebidos;
pnlContornos.Invalidate();
}
catch
{
}
}
private void btnAtualizar_Click(object sender, EventArgs e)
{
AtualizaListaCameras();
}
private void btnSalvar_Click(object sender, EventArgs e)
{
if (btnSalvar.Text == "Editar")
{
btnSalvar.Text = "Salvar";
}
else
{
btnSalvar.Text = "Editar";
cameraService.selectedCamera = cmbCameras.SelectedIndex;
}
btnIniciar.Enabled = btnSalvar.Text == "Editar" && cmbCameras.SelectedIndex > 0;
cmbCameras.Enabled = btnSalvar.Text == "Salvar";
}
private void btnIniciar_Click(object sender, EventArgs e)
{
cameraService.ArquivoLeitura = ArquivoLeitura;
cameraService.IniciarCamera(
PythonService.ScriptStreetDetector,
2024-03-01 19:49:20 +00:00
new string[] {
MaxLeituras.ToString(),
VideoPorta,
VideoUrl,
ArquivoLeitura,
MostrarDebug ? "1" : "0",
VideoUrl
2024-03-01 19:49:20 +00:00
},
VideoPorta,
VideoUrl,
VideoUrl,
new Timer()
);
tmrLeitura = new Timer() { Interval = 200 };
tmrLeitura.Tick += TmrLeitura_Tick;
tmrLeitura.Start();
}
private void AtualizaListaCameras()
{
cameraService.selectedCamera = cmbCameras.SelectedIndex > 0 ? cmbCameras.SelectedIndex : 0;
cmbCameras.Items.Clear();
cmbCameras.Items.AddRange(CameraService.AtualizaListaCameras().Keys.ToArray());
if (cmbCameras.Items.Count == 1)
{
cameraService.selectedCamera = 0;
}
cmbCameras.SelectedIndex = cameraService.selectedCamera;
}
}
}