【问题标题】:Work with matrix in emgu cv在 emgu cv 中使用矩阵
【发布时间】:2011-11-04 01:24:48
【问题描述】:

我在 EMGU cv 中有一个图像的矩阵 (2D),我怎样才能用零填充矩阵的其余部分,但保留原始数据的某个区域(矩形)?

【问题讨论】:

    标签: c# matrix emgucv


    【解决方案1】:

    方法一

    实现您的目标的一种方法是直接访问矩阵的数据并将值设置为“0”以下代码会将“My_Matrix”的下四分之一设置为 0,其中所有其他值将保持 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; 
        }
    }
    

    要从评论中实现您想要的,您仍然必须采用相同的方法 My_Matrix_Image 将包含 0-255 的图像数据值我将为灰度和彩色图像提供解决方案。我将保留图像的前 30 行,并将其余的设置为零,图像的大小将是 100x100 像素。更改 j = 30 以更改行数。

    第一个彩色图像矩阵将有 3 个通道 RedGreenBlue

    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
    
        }
    }
    

    灰度图像矩阵更容易,因为只有 1 个通道:

    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; 
        }
    }
    

    现在假设您想保留 Middle 40 Rows,您必须添加一个额外的循环,记住这是使用 Matrix 的唯一方法,我只提供了如您所见,彩色图像示例开始变得有些混乱,方法 2 可能会更好:

    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
        }
    }
    

    方法二

    现在假设您确实想要保留一个矩形数据。创建 6 个循环既复杂又低效,因此您可以这样做。

    //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
    
        }
    }
    

    上面的代码将从图像中复制中心 20x20 像素,您显然可以使用 for(int i = 0; i

    好多了,我相信你会同意的。

    替代方案

    现在,当您使用 Matrix 来存储数据时,使用 Image 构造可以使编码更简单一些。虽然这可能与您无关,但可能与其他人有关。

    如果您使用 Image 或替代方法来存储您的 Image 数据,则可以通过以下方式实现:

    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;
    

    现在这与方法 2 相同,但您不需要对可能发生错误的循环进行排序。

    希望这个更正回答你的问题,

    干杯

    克里斯

    【讨论】:

    • 亲爱的克里斯,这与我想要的相反!!!我有一个图像矩阵,所以我希望保留一些行(相邻的)并用零填充。
    • 嗨,Reza,我已经更正了答案,给出了所有可能的方法来实现我认为你想要的。我还编辑了您的问题,以使您的问题更加清楚,希望您不介意。方法 2 是我添加的最简单的彩色图像,我假设您可以将矩阵维度 [i,j,n] 更改为您的数据。我希望这个答案更适合你在欢呼之后的样子
    • 我正在尝试使用 My_Image_Copy.Data[i,j,0] 但在 c# 中,它给我的错误是它不支持超过 2 个索引。任何帮助
    【解决方案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;
        }
    

    【讨论】:

      猜你喜欢
      • 2016-11-16
      • 1970-01-01
      • 1970-01-01
      • 2015-06-18
      • 2011-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多