using System; using System.IO; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; using System.Drawing; using System.Drawing.Imaging; using Newtonsoft.Json; using Microsoft.Extensions.Configuration; using TesteImagemCaminhao; namespace VehicleDetectionAPI { public class WheelsDetectionService : IWheelsDetectionService { private readonly HttpClient _httpClient; private readonly string _apiUrl; private readonly string _apiKey; public WheelsDetectionService(IConfiguration configuration) { _httpClient = new HttpClient(); _apiUrl = configuration["ComputerVision:ApiUrl"]; _apiKey = configuration["ComputerVision:ApiKey"]; } public async Task DetectWheelsCount(string imagePath) { try { // Método 1: Usar detecção de objetos para identificar rodas diretamente // (método mais preciso se tivermos um modelo treinado para isso) int wheelsCount = await DetectWheelsUsingObjectDetection(imagePath); // Se o método anterior não detectar rodas, usar método alternativo if (wheelsCount == 0) { // Método 2: Estimar com base em detecção de contornos e recursos geométricos wheelsCount = DetectWheelsUsingContours(imagePath); } return wheelsCount; } catch (Exception ex) { Console.WriteLine($"Erro na detecção de rodas: {ex.Message}"); return EstimateDefaultWheelsCount(imagePath); // Fallback para estimativa padrão } } public async Task DetectWheelsCountOld(string imagePath) { try { // Método 1: Usar detecção de objetos para identificar rodas diretamente // (método mais preciso se tivermos um modelo treinado para isso) int wheelsCount = await DetectWheelsUsingObjectDetection(imagePath); // Se o método anterior não detectar rodas, usar método alternativo if (wheelsCount == 0) { // Método 2: Estimar com base em detecção de contornos e recursos geométricos wheelsCount = DetectWheelsUsingContours(imagePath); } return wheelsCount; } catch (Exception ex) { Console.WriteLine($"Erro na detecção de rodas: {ex.Message}"); return EstimateDefaultWheelsCount(imagePath); // Fallback para estimativa padrão } } private async Task DetectWheelsUsingObjectDetection(string imagePath) { // Esta função envia a imagem para um serviço de detecção de objetos // como Azure Custom Vision, Yolo ou um modelo ML personalizado // Exemplo de integração com o Azure Custom Vision: try { using var fileStream = new FileStream(imagePath, FileMode.Open); using var content = new StreamContent(fileStream); content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); // Adicionar a chave de API ao cabeçalho _httpClient.DefaultRequestHeaders.Add("Prediction-Key", _apiKey); // Enviar a imagem para o serviço var response = await _httpClient.PostAsync(_apiUrl, content); response.EnsureSuccessStatusCode(); // Analisar a resposta var result = await response.Content.ReadAsStringAsync(); var detectionResult = JsonConvert.DeserializeObject(result); // Contar apenas objetos detectados como "roda" com confiança > 0.5 int wheelsCount = detectionResult.Predictions .Count(p => p.TagName.ToLower() == "roda" && p.Probability > 0.5); return wheelsCount; } catch { // Se falhar, retornar 0 para que o método alternativo seja usado return 0; } } private int DetectWheelsUsingContours(string imagePath) { // Implementação simplificada usando processamento de imagem básico // Em um ambiente real, usaríamos uma biblioteca de visão computacional como OpenCV // Esta é uma implementação simulada // Em produção, usaríamos algoritmos para: // 1. Converter para escala de cinza // 2. Aplicar detecção de bordas (Canny) // 3. Encontrar contornos circulares (HoughCircles) // 4. Filtrar por tamanho e posição para identificar rodas // Como exemplo, retornamos um valor baseado no tipo de veículo detectado using (var bitmap = new Bitmap(imagePath)) { // Análise básica da imagem para simular processamento // Em um sistema real, este seria um algoritmo complexo // Se a imagem for larga (proporção > 2:1), provavelmente é um caminhão if (bitmap.Width > bitmap.Height * 2) { return 6; // Estimar rodas para um caminhão } // Se for mais alta que larga, pode ser uma moto else if (bitmap.Height > bitmap.Width) { return 2; // Estimar rodas para uma moto } else { return 4; // Estimar rodas para um carro } } } private int EstimateDefaultWheelsCount(string imagePath) { // Análise simples da imagem para fazer uma estimativa padrão using (var bitmap = new Bitmap(imagePath)) { // Detectar cor predominante para estimar o tipo de veículo Color predominantColor = GetPredominantColor(bitmap); // Tamanho da imagem var size = bitmap.Width * bitmap.Height; // Estimativa baseada na cor e tamanho if (size < 100000) // Imagem pequena return 2; // Possivelmente uma moto else if (size > 500000) // Imagem grande return 6; // Possivelmente um caminhão else return 4; // Padrão para carros } } private Color GetPredominantColor(Bitmap bitmap) { // Método simplificado para obter cor predominante int r = 0, g = 0, b = 0; int total = 0; // Amostragem de pixels for (int x = 0; x < bitmap.Width; x += 10) { for (int y = 0; y < bitmap.Height; y += 10) { var pixel = bitmap.GetPixel(x, y); r += pixel.R; g += pixel.G; b += pixel.B; total++; } } // Calcular média return Color.FromArgb(r / total, g / total, b / total); } } // Classe para deserializar a resposta da API de detecção de objetos public class DetectionResult { public string Id { get; set; } public string Project { get; set; } public string Iteration { get; set; } public DateTime Created { get; set; } public Prediction[] Predictions { get; set; } } public class Prediction { public float Probability { get; set; } public string TagId { get; set; } public string TagName { get; set; } public BoundingBox BoundingBox { get; set; } } public class BoundingBox { public float Left { get; set; } public float Top { get; set; } public float Width { get; set; } public float Height { get; set; } } }