Cambiado funcionamiento de BuscarCoincidencias para guardar el clip original.
This commit is contained in:
parent
3fe845b02f
commit
b6b078f8ce
|
@ -95,6 +95,33 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
|||
Search_templates = false;
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
[property: Category("Tag Extraction:")]
|
||||
bool tomarClip;
|
||||
|
||||
// En lugar de almacenar Mat directamente, guardaremos una representación serializable
|
||||
[ObservableProperty]
|
||||
[property: Category("Tag Extraction:")]
|
||||
byte[] capturedRegionData;
|
||||
|
||||
[ObservableProperty]
|
||||
[property: Category("Tag Extraction:")]
|
||||
[property: ReadOnly(true)]
|
||||
bool regionCapturada;
|
||||
|
||||
// Para uso interno (no serializado)
|
||||
[JsonIgnore]
|
||||
private Mat _capturedRegion;
|
||||
|
||||
// Propiedades para almacenar las dimensiones de la captura
|
||||
[ObservableProperty]
|
||||
[property: Category("Tag Extraction:")]
|
||||
int capturedWidth;
|
||||
|
||||
[ObservableProperty]
|
||||
[property: Category("Tag Extraction:")]
|
||||
int capturedHeight;
|
||||
|
||||
[ObservableProperty]
|
||||
[property: Category("Tag Extraction:")]
|
||||
bool export_ocr;
|
||||
|
@ -103,6 +130,200 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
|||
[property: Category("Tag Extraction:")]
|
||||
string text_export_ocr;
|
||||
|
||||
|
||||
// Esta propiedad manejará la conversión entre Mat y datos serializables
|
||||
[JsonIgnore]
|
||||
public Mat CapturedRegion
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_capturedRegion == null && CapturedRegionData != null && CapturedRegionData.Length > 0)
|
||||
{
|
||||
// Recrear Mat desde los datos almacenados
|
||||
_capturedRegion = BytesToMat(CapturedRegionData, CapturedWidth, CapturedHeight);
|
||||
}
|
||||
return _capturedRegion;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
// Convertir Mat a bytes para serialización
|
||||
CapturedRegionData = MatToBytes(value);
|
||||
CapturedWidth = value.Width;
|
||||
CapturedHeight = value.Height;
|
||||
_capturedRegion = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
CapturedRegionData = null;
|
||||
CapturedWidth = 0;
|
||||
CapturedHeight = 0;
|
||||
_capturedRegion = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
partial void OnTomarClipChanged(bool oldValue, bool newValue)
|
||||
{
|
||||
if (tomarClip)
|
||||
{
|
||||
CapturarRegionActual();
|
||||
TomarClip = false; // Resetear el flag después de la captura
|
||||
}
|
||||
}
|
||||
|
||||
// Método para capturar la región actual
|
||||
private void CapturarRegionActual()
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
if (_mainViewModel?.MainCanvas.Children[0] is Image imagenDeFondo)
|
||||
{
|
||||
if (imagenDeFondo.Source is BitmapSource bitmapSource)
|
||||
{
|
||||
// Obtener los DPI de la imagen original
|
||||
float originalDpiX = (float)bitmapSource.DpiX;
|
||||
float originalDpiY = (float)bitmapSource.DpiY;
|
||||
|
||||
// Estándar DPI en el que el Canvas renderiza la imagen
|
||||
float canvasDpiX = 96;
|
||||
float canvasDpiY = 96;
|
||||
|
||||
// Calcular el ratio de escala entre el Canvas y la imagen original
|
||||
float scaleFactorX = originalDpiX / canvasDpiX;
|
||||
float scaleFactorY = originalDpiY / canvasDpiY;
|
||||
|
||||
// Ajustar las coordenadas de recorte en función del ratio de escala
|
||||
int x = (int)MeterToPixels(Left * scaleFactorX);
|
||||
int y = (int)MeterToPixels(Top * scaleFactorY);
|
||||
int width = (int)MeterToPixels(Ancho * scaleFactorX);
|
||||
int height = (int)MeterToPixels(Alto * scaleFactorY);
|
||||
|
||||
// Validar y ajustar el tamaño del recorte para que se mantenga dentro de los límites de la imagen
|
||||
if (x < 0) x = 0;
|
||||
if (y < 0) y = 0;
|
||||
if (x + width > bitmapSource.PixelWidth) width = bitmapSource.PixelWidth - x;
|
||||
if (y + height > bitmapSource.PixelHeight) height = bitmapSource.PixelHeight - y;
|
||||
|
||||
// Recortar el área deseada utilizando las coordenadas ajustadas
|
||||
CroppedBitmap croppedBitmap = new CroppedBitmap(bitmapSource, new Int32Rect(x, y, width, height));
|
||||
|
||||
// Capturar la región y almacenarla
|
||||
if (_capturedRegion != null)
|
||||
{
|
||||
_capturedRegion.Dispose(); // Liberar recursos previos
|
||||
}
|
||||
|
||||
// Usar la propiedad que maneja la serialización
|
||||
CapturedRegion = BitmapSourceToMat(croppedBitmap);
|
||||
|
||||
// Actualizar el estado
|
||||
RegionCapturada = true;
|
||||
MessageBox.Show("Región capturada correctamente.", "Información", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Métodos para convertir entre Mat y bytes
|
||||
private byte[] MatToBytes(Mat mat)
|
||||
{
|
||||
if (mat == null)
|
||||
return null;
|
||||
|
||||
// Asegurar que tenemos un formato consistente para serialización
|
||||
Mat bgr = new Mat();
|
||||
if (mat.NumberOfChannels != 3)
|
||||
{
|
||||
CvInvoke.CvtColor(mat, bgr, mat.NumberOfChannels == 1 ?
|
||||
ColorConversion.Gray2Bgr : ColorConversion.Bgra2Bgr);
|
||||
}
|
||||
else
|
||||
{
|
||||
bgr = mat.Clone();
|
||||
}
|
||||
|
||||
// Convertir a un formato que pueda ser serializado
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
// Convertir Mat a Bitmap
|
||||
Bitmap bitmap = bgr.ToBitmap();
|
||||
|
||||
// Guardar como PNG (sin pérdida de calidad)
|
||||
bitmap.Save(ms, ImageFormat.Png);
|
||||
|
||||
// Liberar recursos
|
||||
bitmap.Dispose();
|
||||
if (bgr != mat)
|
||||
bgr.Dispose();
|
||||
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
private Mat BytesToMat(byte[] bytes, int width, int height)
|
||||
{
|
||||
if (bytes == null || bytes.Length == 0)
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
using (MemoryStream ms = new MemoryStream(bytes))
|
||||
{
|
||||
// Cargar imagen desde bytes
|
||||
Bitmap bitmap = (Bitmap)System.Drawing.Image.FromStream(ms);
|
||||
|
||||
// Convertir Bitmap a Mat
|
||||
Image<Bgr, byte> img = bitmap.ToImage<Bgr, byte>();
|
||||
|
||||
// Liberar recursos
|
||||
bitmap.Dispose();
|
||||
|
||||
// Si las dimensiones no coinciden, redimensionar
|
||||
if (img.Width != width || img.Height != height)
|
||||
{
|
||||
CvInvoke.Resize(img.Mat, img.Mat, new Size(width, height));
|
||||
}
|
||||
|
||||
return img.Mat;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"Error al reconstruir Mat: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Sobrescribir los métodos de cambio de tamaño para limpiar la región capturada
|
||||
public override void AnchoChanged(float newValue)
|
||||
{
|
||||
base.AnchoChanged(newValue);
|
||||
//LimpiarRegionCapturada();
|
||||
}
|
||||
|
||||
public override void AltoChanged(float newValue)
|
||||
{
|
||||
base.AnchoChanged(newValue);
|
||||
// LimpiarRegionCapturada();
|
||||
}
|
||||
|
||||
private void LimpiarRegionCapturada()
|
||||
{
|
||||
if (_capturedRegion != null)
|
||||
{
|
||||
_capturedRegion.Dispose();
|
||||
_capturedRegion = null;
|
||||
}
|
||||
|
||||
// Usar la propiedad para manejar la serialización
|
||||
CapturedRegion = null;
|
||||
RegionCapturada = false;
|
||||
}
|
||||
|
||||
|
||||
partial void OnExport_ocrChanged(bool value)
|
||||
{
|
||||
if (Export_ocr)
|
||||
|
@ -211,6 +432,7 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
|||
progressDialog.Show();
|
||||
}
|
||||
|
||||
// Modificar el método BuscarCoincidenciasAsync para usar la región capturada si está disponible
|
||||
private void BuscarCoincidenciasAsync(ProgressDialog progressDialog)
|
||||
{
|
||||
// Reset the Canvas children
|
||||
|
@ -221,41 +443,69 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
|||
{
|
||||
_mainViewModel.MainCanvas.Children.Remove(shape);
|
||||
}
|
||||
|
||||
if (_mainViewModel?.MainCanvas.Children[0] is Image imagenDeFondo)
|
||||
{
|
||||
// Asegurarse de que la imagen origen está disponible
|
||||
if (imagenDeFondo.Source is BitmapSource bitmapSource)
|
||||
{
|
||||
progressDialog.ReportProgress(10);
|
||||
// Obtener los DPI de la imagen original
|
||||
float originalDpiX = (float)bitmapSource.DpiX;
|
||||
float originalDpiY = (float)bitmapSource.DpiY;
|
||||
|
||||
// Estándar DPI en el que el Canvas renderiza la imagen
|
||||
float canvasDpiX = 96; // WPF usually renders at 96 DPI
|
||||
float canvasDpiY = 96;
|
||||
Mat templateMat;
|
||||
int width, height;
|
||||
float scaleFactorX, scaleFactorY;
|
||||
bool deleteTemplateMat = false;
|
||||
|
||||
// Calcular el ratio de escala entre el Canvas y la imagen original
|
||||
float scaleFactorX = originalDpiX / canvasDpiX;
|
||||
float scaleFactorY = originalDpiY / canvasDpiY;
|
||||
// Usar la región capturada si existe, de lo contrario capturar la región actual
|
||||
if (CapturedRegion != null && RegionCapturada)
|
||||
{
|
||||
// Usar la región almacenada (ya deserializada)
|
||||
templateMat = CapturedRegion.Clone();
|
||||
deleteTemplateMat = true;
|
||||
width = templateMat.Width;
|
||||
height = templateMat.Height;
|
||||
|
||||
// Ajustar las coordenadas de recorte en función del ratio de escala
|
||||
int x = (int)MeterToPixels(Left * scaleFactorX);
|
||||
int y = (int)MeterToPixels(Top * scaleFactorY);
|
||||
int width = (int)MeterToPixels(Ancho * scaleFactorX);
|
||||
int height = (int)MeterToPixels(Alto * scaleFactorY);
|
||||
// Para mantener la relación con la imagen original
|
||||
float originalDpiX = (float)bitmapSource.DpiX;
|
||||
float originalDpiY = (float)bitmapSource.DpiY;
|
||||
float canvasDpiX = 96;
|
||||
float canvasDpiY = 96;
|
||||
scaleFactorX = originalDpiX / canvasDpiX;
|
||||
scaleFactorY = originalDpiY / canvasDpiY;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Obtener los DPI de la imagen original
|
||||
float originalDpiX = (float)bitmapSource.DpiX;
|
||||
float originalDpiY = (float)bitmapSource.DpiY;
|
||||
|
||||
// Validar y ajustar el tamaño del recorte para que se mantenga dentro de los límites de la imagen
|
||||
if (x < 0) x = 0;
|
||||
if (y < 0) y = 0;
|
||||
if (x + width > bitmapSource.PixelWidth) width = bitmapSource.PixelWidth - x;
|
||||
if (y + height > bitmapSource.PixelHeight) height = bitmapSource.PixelHeight - y;
|
||||
// Estándar DPI en el que el Canvas renderiza la imagen
|
||||
float canvasDpiX = 96;
|
||||
float canvasDpiY = 96;
|
||||
|
||||
// Recortar el área deseada utilizando las coordenadas ajustadas
|
||||
CroppedBitmap croppedBitmap = new CroppedBitmap(bitmapSource, new Int32Rect(x, y, width, height));
|
||||
// Calcular el ratio de escala entre el Canvas y la imagen original
|
||||
scaleFactorX = originalDpiX / canvasDpiX;
|
||||
scaleFactorY = originalDpiY / canvasDpiY;
|
||||
|
||||
// Convertir CroppedBitmap a Mat directamente
|
||||
Mat templateMat = BitmapSourceToMat(croppedBitmap);
|
||||
// Ajustar las coordenadas de recorte en función del ratio de escala
|
||||
int x = (int)MeterToPixels(Left * scaleFactorX);
|
||||
int y = (int)MeterToPixels(Top * scaleFactorY);
|
||||
width = (int)MeterToPixels(Ancho * scaleFactorX);
|
||||
height = (int)MeterToPixels(Alto * scaleFactorY);
|
||||
|
||||
// Validar y ajustar el tamaño del recorte para que se mantenga dentro de los límites de la imagen
|
||||
if (x < 0) x = 0;
|
||||
if (y < 0) y = 0;
|
||||
if (x + width > bitmapSource.PixelWidth) width = bitmapSource.PixelWidth - x;
|
||||
if (y + height > bitmapSource.PixelHeight) height = bitmapSource.PixelHeight - y;
|
||||
|
||||
// Recortar el área deseada utilizando las coordenadas ajustadas
|
||||
CroppedBitmap croppedBitmap = new CroppedBitmap(bitmapSource, new Int32Rect(x, y, width, height));
|
||||
|
||||
// Convertir CroppedBitmap a Mat directamente
|
||||
templateMat = BitmapSourceToMat(croppedBitmap);
|
||||
deleteTemplateMat = true;
|
||||
}
|
||||
|
||||
int scale = 4;
|
||||
|
||||
|
@ -265,6 +515,9 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
|||
Mat templateGrayResized = new Mat();
|
||||
CvInvoke.Resize(templateGray, templateGrayResized, new Size(templateGray.Width / scale, templateGray.Height / scale), 0, 0, Inter.Linear);
|
||||
progressDialog.ReportProgress(20);
|
||||
|
||||
// El resto del código permanece igual...
|
||||
|
||||
// Cargar la imagen principal completa en un Mat
|
||||
Mat mainImageMat = BitmapSourceToMat(bitmapSource);
|
||||
|
||||
|
@ -293,9 +546,6 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
|||
else
|
||||
search_rectangles = new List<Rect>();
|
||||
|
||||
// Añadir el rectángulo usado por croppedBitmap a search_rectangles
|
||||
//search_rectangles.Add(new Rect(x / scaleFactorX, y / scaleFactorY, width / scaleFactorX, height / scaleFactorY));
|
||||
|
||||
// Obtener los puntos que superan el umbral
|
||||
float[] resultArray = result.GetData(false) as float[];
|
||||
if (resultArray != null)
|
||||
|
@ -342,18 +592,36 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
|||
Coincidencias = ConteoPositivos;
|
||||
progressDialog.ReportProgress(90);
|
||||
if (ConteoPositivos > 20)
|
||||
{
|
||||
// Liberar recursos antes de salir
|
||||
if (deleteTemplateMat) templateMat.Dispose();
|
||||
templateGray.Dispose();
|
||||
templateGrayResized.Dispose();
|
||||
mainImageMat.Dispose();
|
||||
mainImageGray.Dispose();
|
||||
mainImageGrayResized.Dispose();
|
||||
result.Dispose();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PopularTagExtraction();
|
||||
}
|
||||
|
||||
// Limpiar recursos
|
||||
if (deleteTemplateMat) templateMat.Dispose();
|
||||
templateGray.Dispose();
|
||||
templateGrayResized.Dispose();
|
||||
mainImageMat.Dispose();
|
||||
mainImageGray.Dispose();
|
||||
mainImageGrayResized.Dispose();
|
||||
result.Dispose();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void PopularTagExtraction()
|
||||
{
|
||||
var objetosSimulablesCopy = new List<osBase>(_mainViewModel.ObjetosSimulables);
|
||||
|
|
Loading…
Reference in New Issue