c# - Trabajar con la matriz en emgu cv
matrix emgucv (2)
// Rectangle''s parameters
static int x = 3;
static int y = 3;
static int width = 2;
static int height = 2;
Rectangle specificArea = new Rectangle(x, y, width, height);
// Your image matrix; 20x20 just a sample
Matrix<int> imageMatrix = new Matrix<int>(20, 20);
public Matrix<int> cropMatrix()
{
// Crop a specific area from image matrix
Matrix<int> specificMatrix = imageMatrix.GetSubRect(specificArea);
// Matrix with full of zeros and same size with imageMatrix
Matrix<int> croppedMatrix = imageMatrix.CopyBlank();
for (int i = x; i < x+width; i++)
{
for (int j = y; j < y+height; j++)
{
// Set croppedMatrix with saved values
croppedMatrix[i, j] = specificMatrix[i-x, j-y];
}
}
return croppedMatrix;
}
Tengo una matriz (2D) de una imagen en EMGU cv, ¿cómo puedo llenar el resto de la matriz con ceros, pero mantener un área determinada (rectángulo) con los datos originales?
Método 1
Una forma de lograr lo que desea es acceder directamente a los Datos de la Matriz y establecer los valores en ''0'', el siguiente código establecerá el cuarto inferior de ''Mi_Matriz'' en 0, donde los demás valores permanecerán en 20.
Matrix<double> My_Matrix_Image = new Matrix<double>(8,10);
My_Matrix_Image.SetValue(20); //set all values of Matrix to 20
for(int i = 4; i< My_Matrix_Image.Height; i++)
{
for (int j = 5; j < My_Matrix_Image.Width; j++)
{
My_Matrix_Image.Data[i,j] = 0;
}
}
Para lograr lo que quería de su comentario, debe seguir el mismo enfoque. My_Matrix_Image contendrá sus valores de datos de imagen de 0 a 255. Proporcionaré soluciones para las imágenes en escala de grises y en color. Mantendré las primeras 30 filas de la imagen y estableceré el resto en cero; la imagen tendrá un tamaño de 100x100 píxeles . Cambie j = 30 para alterar la cantidad de filas.
La primera matriz de imágenes en color habrá 3 canales rojo , verde y azul :
for(int i = 0; i< My_Matrix_Image.Height; i++)
{
for (int j = 30; j < My_Matrix_Image.Width; j++)
{
My_Matrix_Image.Data[i,j,0] = 0; //RED
My_Matrix_Image.Data[i,j,1] = 0; //GREEN
My_Matrix_Image.Data[i,j,2] = 0; //BLUE
}
}
Las matrices de imagen en escala de grises son más fáciles ya que habrá 1 canal:
for(int i = 0; i< My_Matrix_Image.Height; i++)
{
for (int j = 30; j < My_Matrix_Image.Width; j++)
{
My_Matrix_Image.Data[i,j,0] = 0;
}
}
Ahora supongamos que quiere mantener las filas del Medio 40 , tendrá que agregar un bucle adicional. Recuerde que esta es la única forma con una matriz. Solo he proporcionado el ejemplo de la imagen en color, ya que puede ver que empieza a ponerse un poco complicado y el Método 2 puede ser mejor:
for(int i = 0; i< My_Matrix_Image.Height; i++)
{
//LOOP 1 SET THE FRONT ROWS
for (int j = 0; j<40; j++)
{
My_Matrix_Image.Data[i,j,0] = 0; //RED
My_Matrix_Image.Data[i,j,1] = 0; //GREEN
My_Matrix_Image.Data[i,j,2] = 0; //BLUE
}
// LOOP 2 SET THE BACK ROWS
for (int j = 60; j < My_Matrix_Image.Width; j++)
{
My_Matrix_Image.Data[i,j,0] = 0; //RED
My_Matrix_Image.Data[i,j,1] = 0; //GREEN
My_Matrix_Image.Data[i,j,2] = 0; //BLUE
}
}
Método 2
Ahora supongamos que desea mantener un rectángulo de datos. Crear 6 Loops es complejo e ineficiente, así que esto es lo que podrías hacer.
//Make a Blank Copy of your Image this will be automatically full of zeros
Matrix<double> My_Image_Copy = My_Image_Matrix.CopyBlank();
//Now copy the data you want to keep from your original image into you blank copy
for(int i = 40; i< 60; i++)
{
for (int j = 40; j < 60; j++)
{
My_Image_Copy.Data[i,j,0] = My_Matrix_Image.Data[i,j,0]; //RED
My_Image_Copy.Data[i,j,1] = My_Matrix_Image.Data[i,j,1]; //GREEN
My_Image_Copy.Data[i,j,2] = My_Matrix_Image.Data[i,j,2]; //BLUE
}
}
El código anterior copiará el centro de 20x20 píxeles de una imagen, obviamente puede cambiar esto para copiar filas enteras usando for (int i = 0; i <My_Matrix_Image.Height; i ++)
Mucho mejor, estoy seguro de que estarás de acuerdo.
Alternativa
Ahora, mientras usa Matrix para almacenar sus datos usando una construcción de imagen, la codificación es un poco más simple. Si bien esto puede no ser relevante para usted, puede ser para otros.
Si usa Image o alternative para almacenar sus datos de Imagen, esto se puede lograr:
Image<Gray, Byte> My_Image = new Image<Gray, byte>(openfile.FileName);
Image<Gray, Byte> My_Image_Copy = My_Image.CopyBlank();
Rectangle Store_ROI = my_image.ROI; //Only need one as both images same size
My_Image.ROI = new Rectangle(50, 50, 100, 100);
My_Image_Copy.ROI = new Rectangle(50, 50, 100, 100);
My_Image_Copy = My_Image.Copy(); //This will only copy the Region Of Interest
//Reset the Regions Of Interest so you will now operate on the whole image
My_Image.ROI = Store_ROI;
My_Image_Copy.ROI = Store_ROI;
Ahora esto es lo mismo que el Método 2, pero no es necesario clasificar los bucles de escritura donde pueden ocurrir errores.
Espero que esta corrección responda tu pregunta,
Aclamaciones
Chris