EmguCV学习笔记 C# 2.2 Matrix类

news2024/11/24 20:27:25

 版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。

EmguCV学习笔记目录 Vb.net

EmguCV学习笔记目录 C#

笔者的博客网址:VB.Net-CSDN博客

教程相关说明以及如何获得pdf教程和代码(博客上的教程内容会和pdf教程一致,教程中也会包含所有代码),请移步:EmguCV学习笔记

2.2 Matrix类

Matrix类是EmguCV中的一个矩阵类,它可以用来存储和处理矩阵数据,可以处理任意维度的矩阵。与Mat类相比,Matrix类提供了更多的矩阵运算方法,如矩阵加减、乘法、逆矩阵等,也更加灵活,而且底层实现也更加高效。

通常而言,Matrix类应为Matrix<数据类型> 的形式,其中数据类型指明了该矩阵中元素的存储类型,包括byteintfloat等。

2.2.1 构造函数

为了显示Matrix结果,请在窗体上放置一个MatrixBox控件。该控件位于【工具箱】|【Emgu.CV】下面。另外,

1、使用一维数组初始化Matrix

【代码位置:frmChapter2_1】Button1_Click

        //Matrix构造函数:一维数组初始化Matrix

        private void Button1_Click(object sender, EventArgs e)

        {

            byte[] inputBytes = new Byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            Matrix<byte> matr = new Matrix<byte>(inputBytes);

            MatrixBox1.Matrix = matr;

        }

显示结果如下:

 

图2-2 一维数组初始化Matrix

2、使用二维数组初始化Matrix

【代码位置:frmChapter2_1】Button2_Click

        //Matrix构造函数:二维数组初始化Matrix

        private void Button2_Click(object sender, EventArgs e)

        {

            byte[,] inputBytes = new byte[,] { { 1, 2, 3 }, { 3, 4, 5 }, { 5, 6, 7 }, { 7, 8, 9 } };

            Matrix<byte> matr = new Matrix<byte>(inputBytes);

            MatrixBox1.Matrix = matr;

        }

显示结果如下:

 

图2-3 二维数组初始化Matrix

3、指定大小初始化Matrix,然后写入值:

【代码位置:frmChapter2_1】Button3_Click

        //Matrix构造函数:初始化矩阵的大小(Size

        //注意使用size的话,width是列,height是行,列在前,行灾后

        //以下创建的是一个24行的矩阵

        private void Button3_Click(object sender, EventArgs e)

        {

            byte[] inputBytes = new Byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

            Matrix<byte> matr = new Matrix<byte>(new Size(2, 4));

            for (int i = 0; i <= 1; i++)

                for (int j = 0; j <= 3; j++)

                    matr[j, i] = inputBytes[i * 4 + j];

            MatrixBox1.Matrix = matr;

        }

先是初始化一个2列(Width)4行(Height)的矩阵,然后使用循环,将数组的数据写入矩阵。

显示结果如下:

 

图2-4 指定大小初始化Matrix

也可以通过SetValue方法设置相同的值:

【代码位置:frmChapter2_1】Button4_Click

        //Matrix构造函数:初始化矩阵的大小(Size

        private void Button4_Click(object sender, EventArgs e)

        {

            Matrix<byte> matr = new Matrix<byte>(new Size(2, 4));

            //将所有元素 设置相同的指定值

            matr.SetValue(new MCvScalar(20));

            MatrixBox1.Matrix = matr;

        }

显示结果如下:

 

图2-5 对Matrix的元素设置相同的值

4、指定行、列、通道初始化Matrix,并将向每个通道写入相同的值:

【代码位置:frmChapter2_1】Button5_Click

        //Matrix构造函数:行、列、通道初始化矩阵

        private void Button5_Click(object sender, EventArgs e)

        {

            //row是行,col是列,行在前,列在后

            //以下创建的是一个243通道的矩阵

            Matrix<byte> matr = new Matrix<byte>(4, 3, 3);

            //设置各个通道的元素的值

            matr.SetValue(new MCvScalar(20, 30, 40));

            MatrixBox1.Matrix = matr;

     }

显示结果如下:

 

图2-6 对多通道Matrix的元素设置相同的值

注意:这个构造函数和通过Size方式初始化Matrix的构造函数有所区别的是,行和列出现的先后不同。Size(列,行),而这个是行、列、通道。

这里对Matrix元素的每个通道设置了值,在MatrixBox控件中可以在channel处下拉选择查看不同通道的值。

5、指定行、列、通道初始化Matrix,并将每个通道的值设置为0:

【代码位置:frmChapter2_1】Button6_Click

        //Matrix元素的值全部设置为0(多通道设置每个通道为0

        private void Button6_Click(object sender, EventArgs e)

        {

            Matrix<byte> matr = new Matrix<byte>(4, 3, 3);

            matr.SetZero();

            MatrixBox1.Matrix = matr;

     }

显示结果如下:

 

图2-7 设置多通道Matrix的元素的值为0

2.2.2 获取Matrix元素的值

在以下代码中提供了3种方法来获取Matrix指定位置(,)的值。

【代码位置:frmChapter2_1】Button7_Click

        private void Button7_Click(object sender, EventArgs e)

        {

            byte[,] inputBytes = new byte[,] { { 1, 2, 3 }, { 3, 4, 5 }, { 5, 6, 7 }, { 7, 8, 9 } };

            Matrix<byte> matr = new Matrix<byte>(inputBytes);

            MatrixBox1.Matrix = matr;

            //方法1:直接使用Matrix(,)进行输出,使用时需要注意行列的顺序

            for(int i= 0;i< matr.Rows;i++)

            {

                for (int j = 0; j < matr.Cols; j++)

                    //通过matr[i,j]获得值的方式只适用于单通道矩阵

                    TextBox1.Text += matr[i, j] + " ";

                TextBox1.Text += "\r\n";

            }

            TextBox1.Text += "====================" + "\r\n";

            //方法2:先读取到一维数组,再输出

            byte[] outputBytes1;

            outputBytes1 = matr.Bytes;

            int height = matr.Rows;

            int width = matr.Cols;

            for (int i = 0; i < height; i++)

            {

                for (int j = 0; j < width; j++)

                    TextBox1.Text += outputBytes1[i * width + j] + " ";

                TextBox1.Text += "\r\n";

            }

            TextBox1.Text += "====================" + "\r\n";

            //方法3:先读取到二维数组,再输出

            byte[,] outputBytes2;

            outputBytes2 = matr.Data;

            //这里是二维数组,所以返回2

            int outputBytesRank = outputBytes2.Rank;

            for (int i = 0; i < outputBytes2.GetLength(0); i++)

            {

                for (int j = 0; j < outputBytes2.GetLength(1); j++)

                    TextBox1.Text += outputBytes2[i, j] + " ";

                TextBox1.Text += "\r\n";

            }

    }

注意:只适合单通道Matrix。对于多通道Matrix需要将其分解成多个单通道Matrix再进行处理。

显示结果如下:

 

图2-8 读取单通道矩阵元素的值

2.2.3 Matrix的拆分

使用MatrixSplit方法将多通道矩阵拆分为单通道矩阵。

【代码位置:frmChapter2_1】Button8_Click

        //将多通道Matrix拆分为多个单通道Matrix

        private void Button8_Click(object sender, EventArgs e)

        {

            Matrix<byte> matr = new Matrix<byte>(4, 2, 3);

            matr.SetValue(new MCvScalar(20, 30, 40));

            Matrix<byte>[] arrMatr;

            //使用Split方法拆分多通道矩阵到矩阵数组。

            arrMatr = matr.Split();

            //显示第一个通道的值

            MatrixBox1.Matrix = arrMatr[0];

        }

显示结果如下:

 

图2-9 Matrix第一个通道的值

2.2.4 Matrix的运算

2.2.4.1 加法

1、加一个数值

【代码位置:frmChapter2_1】Button9_Click

        //Matrix的加法1:增加一个固定值

        private void Button9_Click(object sender, EventArgs e)

        {

            byte[,] inputBytes = new byte[,] { { 1, 2, 3 }, { 3, 4, 5 }, { 5, 6, 7 }, { 7, 8, 9 } };

            Matrix<byte> matr1 = new Matrix<byte>(inputBytes);

            Matrix<byte> matr2;

            //方法1

            matr2 = matr1 + 30;

            //方法2

            //matr2 = matr1.Add(30);

            MatrixBox1.Matrix = matr2;

     }

显示结果如下:

 

图2-10 Matrix增加一个固定值

2、两个单通道矩阵相加

【代码位置:frmChapter2_1】Button10_Click

        //Matrix的加法2:两个单通道矩阵相加

        private void Button10_Click(object sender, EventArgs e)

        {

            byte[,] inputBytes1 = new byte[,] { { 1, 2, 3 }, { 3, 4, 5 }, { 5, 6, 7 }, { 7, 8, 9 } };

            byte[,] inputBytes2 = new byte[,] { { 3, 4, 5 }, { 5, 6, 7 }, { 7, 8, 9 }, { 9, 10, 11 } };

            Matrix<byte> matr1=new Matrix<byte>(inputBytes1);

            Matrix<byte> matr2 = new Matrix<byte>(inputBytes2);

            Matrix<byte> matr3 = new Matrix<byte>(4, 3, 1);

            //方法1

            matr3 = matr1 + matr2;

            //方法2

            //matr3 = matr1.Add(matr2);

            //方法3

            //CvInvoke.Add(matr1, matr2, matr3);

            MatrixBox1.Matrix = matr3;

     }

显示结果如下:

 

图2-11 两个单通道矩阵相加

注意:如果使用方法3,那么必须初始化matr3,否则可以不用初始化,即:

Matrix<byte> matr3

下同。

3、两个多通道矩阵相加

【代码位置:frmChapter2_1】Button11_Click

        //Matrix的加法3:两个多通道矩阵相加

        private void Button11_Click(object sender, EventArgs e)

        {

            Matrix<byte> matr1 = new Matrix<byte>(4, 3, 3);

            matr1.SetValue(new MCvScalar(20, 30, 40));

            Matrix<byte> matr2 = new Matrix<byte>(4, 3, 3);

            matr2.SetValue(new MCvScalar(50, 20, 240));

            Matrix<byte> matr3 = new Matrix<byte>(4, 3, 3);

            //方法1

            matr3 = matr1 + matr2;

            //方法2

            ///matr3 = matr1.Add(matr2);

            //方法3

            //CvInvoke.Add(matr1, matr2, matr3);

            MatrixBox1.Matrix = matr3;

        }

显示结果如下:

 

图2-12 两个多通道矩阵相加

2.2.4.2 减法

1、减一个数值

【代码位置:frmChapter2_1】Button12_Click

        //Matrix的减法1:减去一个固定值

        private void Button12_Click(object sender, EventArgs e)

        {

            byte[,] inputBytes= new byte[,] { { 1, 2, 3 }, { 3, 4, 5 }, { 5, 6, 7 }, { 7, 8, 9 } };

            Matrix<byte> matr1 = new Matrix<byte>(inputBytes);

            Matrix<byte> matr2;

            //方法1

            matr2 = matr1-3;

            //方法2

            //matr2 = matr1.Sub(3);

            MatrixBox1.Matrix = matr2;

        }

显示结果如下:

 

图2-13 Matrix减去一个固定值

还有一个反向减法的方法,读者可以测试将以上代码中的

matr2 = matr1.Sub(3);

替换为:

matr2 = matr1.SubR(30);

进行测试。

2、两个单通道矩阵相减

【代码位置:frmChapter2_1】Button13_Click

        //Matrix的减法2:两个单通道矩阵相减

        private void Button13_Click(object sender, EventArgs e)

        {

            byte[,] inputBytes1 = new byte[,] { { 1, 2, 3 }, { 3, 4, 5 }, { 5, 6, 7 }, { 7, 8, 9 } };

            byte[,] inputBytes2 = new byte[,] { { 3, 4, 5 }, { 5, 6, 7 }, { 7, 8, 9 }, { 9, 10, 21 } };

            Matrix<byte> matr1 = new Matrix<byte>(inputBytes1);

            Matrix<byte> matr2 = new Matrix<byte>(inputBytes2);

            Matrix<byte> matr3 = new Matrix<byte>(4, 3, 1);

            //方法1

            matr3 = matr2 - matr1;

            //方法2

            //matr3 = matr2.Sub(matr1);

            //方法3

            //CvInvoke.Subtract(matr2, matr1, matr3);

            MatrixBox1.Matrix = matr3;

        }

显示结果如下:

 

图2-14 两个单通道矩阵相减

3、两个多通道矩阵相减

【代码位置:frmChapter2_1】Button14_Click

        //Matrix的减法3:两个多通道矩阵相减

        private void Button14_Click(object sender, EventArgs e)

        {

            Matrix<byte> matr1 = new Matrix<byte>(4, 3, 3);

            matr1.SetValue(new MCvScalar(20, 30, 40));

            Matrix<byte> matr2 = new Matrix<byte>(4, 3, 3);

            matr2.SetValue(new MCvScalar(50, 20, 240));

            Matrix<byte> matr3 = new Matrix<byte>(4, 3, 3);

            //方法1

            matr3 = matr2 - matr1;

            //方法2

            //matr3 = matr2.Sub(matr1);

            //方法3

            //CvInvoke.Subtract(matr2, matr1, matr3);

            MatrixBox1.Matrix = matr3;

        }

显示结果如下:

 

图2-15 两个多通道矩阵相减

2.2.4.3 乘法

1、乘以一个数值

【代码位置:frmChapter2_1】Button15_Click

        //Matrix的乘法1:乘以一个固定值

        private void Button15_Click(object sender, EventArgs e)

        {

            byte[,] inputBytes = new byte[,] { { 1, 2, 3 }, { 3, 4, 5 }, { 5, 6, 7 }, { 7, 8, 9 } };

            Matrix<byte> matr1 = new Matrix<byte>(inputBytes);

            Matrix<byte> matr2 ;

            //方法1

            matr2 = matr1 * 3;

            //方法2

            //matr2 = matr1.Mul(3);

            MatrixBox1.Matrix = matr2;

        }

显示结果如下:

 

图2-16 Matrix乘以一个数值

2、两个单通道矩阵相乘

注意:两个矩阵相乘必须满足一定条件

1、第一个Matrix的列数应等于第二个Matrix的行数,生成结果为

列数=第二个Matrix的列数

行数=第一个Matrix的行数

2、数据类型要一致,整数型数据(包括byteintLongInt16Int32Int64等)不能进行乘法运算,浮点型数据(SinglefloatDouble)可以参与运算。

【代码位置:frmChapter2_1】Button16_Click

        //Matrix的乘法2:两个单通道矩阵相乘

        private void Button16_Click(object sender, EventArgs e)

        {

            //42

            Single[,] inputBytes1 = new Single[,] { { 1, 2, 3, 4 }, { 3, 4, 5, 6 } };     

            //34

            Single[,] inputBytes2 = new Single[,]{ { 1, 2, 3 }, { 3, 4, 5 }, { 5, 6, 7 }, { 7, 8, 9 } };

            Matrix<Single> matr1 = new Matrix<Single>(inputBytes1);

            Matrix<Single> matr2 = new Matrix<Single>(inputBytes2);

            //生成32

            Matrix<Single> matr3;

            //方法1

            matr3 = matr1 * matr2;

            //方法2

            //matr3 = matr1.Mul(matr2);

            MatrixBox1.Matrix = matr3;

        }

显示结果如下:

 

图2-17 两个单通道矩阵相乘

3、两个多通道矩阵相乘

两个多通道矩阵似乎不能直接相乘

4、两个矩阵对应元素相乘

这个方法将两个矩阵对应坐标位置的元素相乘,有别于标准的矩阵乘法。

【代码位置:frmChapter2_1】Button17_Click

        //Matrix的乘法3:行列对应元素相乘,不同于普通的矩阵乘法

        private void Button17_Click(object sender, EventArgs e)

        {

            byte[,] inputBytes1 = new byte[,] { { 1, 2, 3 }, { 3, 4, 5 }, { 5, 6, 7 }, { 7, 8, 9 } };

            byte[,] inputBytes2 = new byte[,] { { 3, 4, 5 }, { 5, 6, 7 }, { 7, 8, 9 }, { 9, 10, 11 } };

            Matrix<byte> matr1 = new Matrix<byte>(inputBytes1);

            Matrix<byte> matr2 = new Matrix<byte>(inputBytes2);

            matr1._Mul(matr2);

            MatrixBox1.Matrix = matr1;

        }

显示结果如下:

 

图2-18 两矩阵对应元素相乘

2.2.4.4 除法

【代码位置:frmChapter2_1】Button18_Click

        //Matrix的除法

        private void Button18_Click(object sender, EventArgs e)

        {

            Single[,] inputBytes = new Single[,] { { 1, 2, 3 }, { 3, 4, 5 }, { 5, 6, 7 }, { 7, 8, 9 } };

            Matrix<Single> matr1 = new Matrix<Single>(inputBytes);

            Matrix<Single> matr2;

            matr2 = matr1 / 3;

            MatrixBox1.Matrix = matr2;

        }

显示结果如下:

 

图2-19 Matrix除以一个数值

2.2.4.5 Not运算

【代码位置:frmChapter2_1】Button19_Click

        //矩阵的Not

        private void Button19_Click(object sender, EventArgs e)

        {

            byte[,] inputBytes1 = new byte[,] { { 1, 2, 3 }, { 3, 4, 5 }, { 5, 6, 7 }, { 7, 8, 9 } };

            Matrix<byte> matr1 = new Matrix<byte>(inputBytes1);

            matr1._Not();

            MatrixBox1.Matrix = matr1;

        }

显示结果如下:

 

图2-20 Matrix的Not运算

读者可自行对比byte数据类型和short、int等类型生成的结果。

2.2.5 Matrix拼接

Matrix提供了ConcateHorizontalConcateVertical方法将两个矩阵拼接为一个矩阵。

  1. ConcateHorizontal:水平方向拼接,必须具备相同行数。
  2. ConcateVertical垂直方向拼接,必须具备相同列数

【代码位置:frmChapter2_1】Button20_Click

        //矩阵的水平方向拼接,必须具备相同行数

        private void Button20_Click(object sender, EventArgs e)

        {

            byte[,] inputBytes1 = new byte[,] { { 1, 2, 3 }, { 3, 4, 5 }, { 5, 6, 7 }, { 7, 8, 9 } };

            byte[,] inputBytes2 = new byte[,] { { 3, 4 }, { 5, 6 }, { 7, 8 }, { 9, 10 } };

            Matrix<byte> matr1 = new Matrix<byte>(inputBytes1);

            Matrix<byte> matr2 = new Matrix<byte>(inputBytes2);

            Matrix<byte> matr3;

            matr3 = matr1.ConcateHorizontal(matr2);

            MatrixBox1.Matrix = matr3;

        }

显示结果如下:

 

图2-21 Matrix水平方向拼接

【代码位置:frmChapter2_1】Button21_Click

        //矩阵的垂直方向拼接,必须具备相同列数

        private void Button21_Click(object sender, EventArgs e)

        {

            byte[,] inputBytes1 = new byte[,] { { 1, 2, 3 }, { 3, 4, 5 }, { 5, 6, 7 }, { 7, 8, 9 } };

            byte[,] inputBytes2 = new byte[,] { { 3, 4, 5 }, { 5, 6, 7 }, { 7, 8, 9 } };

            Matrix<byte> matr1 = new Matrix<byte>(inputBytes1);

            Matrix<byte> matr2 = new Matrix<byte>(inputBytes2);

            Matrix<byte> matr3;

            matr3 = matr1.ConcateVertical(matr2);

            MatrixBox1.Matrix = matr3;

        }

显示结果如下:

 

图2-22 Matrix垂直方向拼接

2.2.6 随机矩阵

Matrix类提供了SetRandNormal方法来生成指定大小、类型和均值方差的随机矩阵。该方法声明如下:

public void SetRandNormal(MCvScalar mean, MCvScalar std)

其中参数:

  1. mean:均值,表示随机矩阵的平均值。在正态分布中,均值是分布的中心位置。均值越大,生成的随机矩阵的像素值越偏向于均值。
  2. std:标准差,表示随机矩阵的离散程度。在正态分布中,标准差越大,生成的随机矩阵的像素值越分散。标准差越小,生成的随机矩阵的像素值越接近于均值。

可以通过调整均值和标准差的值来控制生成的随机矩阵的像素值分布。例如,当均值为0,标准差为1时,生成的随机矩阵的像素值符合标准正态分布。当均值为0,标准差为0.5时,生成的随机矩阵的像素值分布更加集中,更接近于均值。

使用SetRandNormal方法生成随机矩阵:

【代码位置:frmChapter2_1】Button22_Click

        //随机矩阵

        private void Button22_Click(object sender, EventArgs e)

        {

            Matrix<byte> matr = new Matrix<byte>(2, 4, 3);

            matr.SetRandNormal(new MCvScalar(12, 33, 123), new MCvScalar(134, 12, 222));

            MatrixBox1.Matrix = matr;

        }

显示结果如下:

 

图2-23 随机矩阵

注意:SetRandNormal方法只能生成正态分布的随机矩阵,不能生成其他分布的随机矩阵。

2.2.7 最大值和最小值

Matrix类提供了MinMax方法获得矩阵内最大值、最小值以及对应的坐标位置。

【代码位置:frmChapter2_1】Button23_Click

        //最大最小值

        private void Button23_Click(object sender, EventArgs e)

        {

            byte[,] inputBytes1 = new byte[,] { { 1, 2, 3 }, { 3, 4, 9 }, { 5, 6, 7 }, { 7, 8, 9 } };

            Matrix<byte> matr1 = new Matrix<byte>(inputBytes1);

            MatrixBox1.Matrix = matr1;

            //最小值

            Double minValue;

            //最大值

            Double maxValue;

            //最小值坐标:有多个最小值时,只返回第一个的坐标

            Point minPoint;

            //最大值坐标:有多个最大值时,只返回第一个的坐标

            Point maxPoint;

            matr1.MinMax(out minValue, out maxValue, out minPoint, out maxPoint);

            TextBox1.Text += minValue + "\r\n";

            TextBox1.Text += maxValue + "\r\n";

            TextBox1.Text += minPoint.X + " " + minPoint.Y + "\r\n";

            TextBox1.Text += maxPoint.X + " " + maxPoint.Y;

        }

显示结果如下:

 

图2-24 最大值最小值以及对应坐标

2.2.8 类型转换

Matrix类提供了Convert方法实现矩阵类型的转换。

【代码位置:frmChapter2_1】Button24_Click

        //类型转换

        private void Button24_Click(object sender, EventArgs e)

        {

            Double[,] inputBytes1 = new Double[,] { { 1.2, 2.2, 3.3 }, { 3.3, 4.4, 5.5 }, { 5.5, 6.6, 7.7 }, { 7.7, 8.8, 9.9 } };

            Matrix<Double> matr1 = new Matrix<Double>(inputBytes1);

            Matrix<byte> matr2 = new Matrix<byte>(matr1.Size);

            //小数转整数会四舍五入

            matr2 = matr1.Convert<byte>();

            MatrixBox1.Matrix = matr2;

        }

显示结果如下:

 

图2-25 从Double转Byte

2.2.9 获得指定范围的子矩阵

Matrix类提供了Convert方法实现获得指定范围的子矩阵。其中参数是一个Rectangle类型,指定了子矩阵的开始位置、列数、行数。

【代码位置:frmChapter2_1】Button25_Click

       //获得子矩阵

        private void Button25_Click(object sender, EventArgs e)

        {

            byte[,] inputBytes1 = new byte[,] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }, { 10, 11, 12 } };

            Matrix<byte> matr1 = new Matrix<byte>(inputBytes1);

            Matrix<byte> matr2 = new Matrix<byte>(3, 2);

            //获得从指定位置(1,1)开始,列数为2,行数为3的子矩阵

            matr2 = matr1.GetSubRect(new Rectangle(1, 1, 2, 3));

            MatrixBox1.Matrix = matr2;

        }

显示结果如下:

 

图2-26 获得指定范围的子矩阵

2.2.10 其他方法

Matrix类还提供了以下常用方法,由于比较简单,不再这里赘述:

  1. Clone:复制Matrix,目标矩阵和源矩阵具有相同的行、列和通道数,元素的值也相同。
  2. CopyBlank:复制Matrix,目标矩阵和源矩阵具有相同的行、列和通道数,但里面元素的值都为0。
  3. GetCol:从源矩阵得到其中一列,并生成新的子矩阵。
  4. GetCols:从源矩阵得到几列的子矩阵。
  5. GetRow:从源矩阵得到其中一行,并生成新的子矩阵。
  6. GetRows:从源矩阵得到几行的子矩阵。
  7. RemoveCols:删除几列的后生成子矩阵。
  8. RemoveRows:删除几行的后生成子矩阵。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2045847.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

全面解析Gerapy分布式部署:从环境搭建到定时任务,避开Crawlab的坑

Gerapy分布式部署 搭建远程服务器的环境 装好带docker服务的系统 Docker:容器可生成镜像&#xff0c;也可拉去镜像生成容器 示例&#xff1a;将一个环境打包上传到云端(远程服务器)&#xff0c;其他8个服务器需要这个环境直接向云端拉取镜像生成容器,进而使用该环境,比如有MYS…

ElasticSearch读写性能调优

文章目录 ES写入数据过程ES读取数据的过程写数据底层原理提升集群读取性能数据建模优化分片 提升写入性能的方法服务器端优化写入性能建模时的优化降低Translog写磁盘的频率&#xff0c;但是会降低容灾能力分片设定调整Bulk 线程池和队列 ES写入数据过程 客户端选择一个node发…

Linux系统编程:进程间通信 1:管道

1.进程间的互相通信的方式 进程间互相通信的方式共有7种&#xff1a; &#xff08;1&#xff09;无名管道&#xff08;同主机&#xff09; &#xff08;2&#xff09;有名管道&#xff08;同主机&#xff09; &#xff08;3&#xff09;信号&#xff08;同主机&#xff09;…

大语言模型(LLM)构建产品的一年经验总结【干货长文】

这是一份涵盖战术、运营和战略方面的大语言模型产品成功建设的实用指南。 现在是构建大型语言模型&#xff08;LLM&#xff09;的激动人心的时刻。在过去的一年里&#xff0c;LLM已经变得足够好&#xff0c;可以用于实际应用。而且它们每年都在变得更好更便宜。伴随着社交媒体上…

成功转行软件测试工程师,年薪30W+,经验总结都在这!

这是给转行做软件测试的小白的参考&#xff0c;无论是从零开始&#xff0c;或者是转行的朋友来说&#xff0c;这都是值得一看的&#xff0c;也是可以作为一种借鉴吧。 而且我决定转行IT&#xff08;互联网&#xff09;行业&#xff0c;其实理由也很简单&#xff0c;不用动体力…

全网爆火的从零到一落地接口自动化测试

前段时间写了一系列自动化测试相关的文章&#xff0c;当然更多的是方法和解决问题的思路角度去阐述我的一些观点。结合我自己实践自动化测试的一些经验以及个人理解&#xff0c;这篇文章来聊聊新手如何从零到一落地实践接口自动化测试。 为什么要做接口测试 测试理念的演变 早…

awesome-react-native 收集最好的React Native库,工具,教程,文章(上篇)

image 分类 分类 会议 连锁反应 - 波特兰&#xff0c;或者美国React Native EU - 弗罗茨瓦夫&#xff0c;波兰React Alicante - 西班牙阿利坎特ReactNext - 以色列特拉维夫React Berlin - 柏林&#xff0c;德国 用品 参考HOWTO文档什持续集成内幕 组件 UI 导航 导航/路由文章…

Aerospike学习笔记

1 概述 Aerospike 是一个分布式、可扩展的数据库。该架构具有三个关键目标&#xff1a; 为网络规模的应用程序创建灵活、可扩展的平台。提供传统数据库所期望的稳健性和可靠性&#xff08;如 ACID&#xff09;。以最少的人工参与提供运营效率。 文档链接&#xff1a;https://d…

【Linux —— 理解pthread库和底层逻辑】

Linux —— 理解pthread库和pthread_t 理解pthread库pthread库是一个动态库底层逻辑 LWPpthread_tpthread_t的概念pthread_t 的实现pthread_t 与 LWP 的关系 独立的栈空间管理 理解pthread库 pthread库是一个动态库 使用下面指令可以查找的系统目录下的库信息 ls /lib/x86_6…

海康VisionMaster使用学习笔记2-相机取图及参数设置

相机取图及参数设置 1. 关联相机-相机管理界面 除了以上两类外,第三方相机都可以通过全局相机进行连接 2. 相机参数设置 相机连接 跨网段IP,枚举 图像缓存数量 实时取流,断线重连 只有支持组播的相机才可以实时取流 触发设置 触发源 LINE0 可以保护电路 LINE2 可配置输入输出…

笔记(day21) 多线程以及锁的概念(超级完整版)

一、 多线程 1.1 程序,进程,线程 程序:一堆命令的集合,完成某个特定任务,是静态的,保存在硬盘中 进程:是程序的一次执行过程,就是把程序载入内存中执行,就是进程,是动态的 线程:是进程进一步细化,是程序内部的一条执行分支 如果一个进程同一时间执行多个线程,就是支持多线程 我…

简单测试AOP五种增强执行时机

1. 目标方法类&#xff0c;spring代理bean Component public class Test {public void test(){System.out.println("test 目标方法");}public void testException(){throw new RuntimeException();} } 2. 配置类 Configuration ComponentScan EnableAspectJAutoPr…

查询满足连续任意30天的全量交易的多个商户

需求说明&#xff1a; 先说表结构把&#xff0c;就是一张订单表存了商户号和其他相关信息&#xff0c;现在要查询这个订单表中以商户为主体的连续交易&#xff0c;也就是每天产生至少一笔订单的商户才算连续&#xff0c;不知道看到的小伙伴有没有什么想法和头绪&#xff0c;在一…

【C++进阶】map与set的封装实践

文章目录 map和setmapmap的框架迭代器operator()operator--()operator()和operator!()operator*()operator->() insertbegin()end()operator[] ()map的所有代码&#xff1a; set的封装迭代器的封装总结 map和set 通过观察stl的底层我们可以看见&#xff0c;map和set是通过红…

ubuntu16.04安装ibus拼音 输入法

前言 开始尝试搜狗输入&#xff0c;发现问题很多&#xff0c;放弃。网上说ibus比较稳定&#xff0c;决定安装ibus输入法。 步骤 安装ibus&#xff0c;使用如下命令, 安装完重启系统&#xff0c;使ibus生效&#xff1b; sudo apt install ibus ibus-pinyin ibus-table ibus-…

maven项目删除pom文件的依赖仍存留在项目中的解决方案【已解决】

前言 使用了pagehelper和mybatisplus的分页插件&#xff0c;起冲突了&#xff0c;想着注释掉pagehelper然后刷新maven&#xff0c;发现一直存留 mlgbz的 试了好多方法&#xff0c;什么缓存乱七八糟的&#xff0c;我以为出bug了 解决

Fiddle抓手机app的包

前言 本次文章讲述的是&#xff0c;fiddle获取手机代理&#xff0c;从而获取手机app的http、https请求&#xff01; 一.下载安装汉化Fiddle 1.点击Fiddler官网下载链接&#xff1a;Download Fiddler Web Debugging Tool for Free by Telerik 2.直接运行&#xff0c;选择自己需…

CUDA C++ 编程指南学习

CUDA C 编程指南 (nvidia.com)https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html 2. 编程模型 2.1. 内核 CUDA C 扩展了 C&#xff0c;允许程序员定义 C 函数&#xff0c;称为内核&#xff0c;当被调用时&#xff0c;N 个不同的 CUDA 线程并行执行 N 次&am…

2023卫星视频综述论文Recent Advances in Intelligent Processing of Satellite Video

2023卫星视频综述论文Recent Advances in Intelligent Processing of Satellite Video 1.摘要2.引言3. 文章的定量分析4 难点与挑战5 方法论系统A. 卫星视频观察的特点B. 卫星视频目标跟踪与运动估计C. 卫星视频目标检测D. 卫星视频超分辨率 (VSR)E. 卫星视频目标分割&#xff…

Idea新建Spring Initializr项目文件哪些可删

​ .gitignore 用git做版本控制时 用这个文件控制那些文件或文件夹 不被提交&#xff08;不用git的话可删除 没影响&#xff09;HELP.md md是一种文档格式 这个就是你项目的帮助文档&#xff08;可删除 没影响&#xff09; mvnw linux上处理mevan版本兼容问题的脚本&#xff0…