当前位置: 首页 > news >正文

EmguCV学习笔记 C# 2.2 Matrix类

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

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:删除几行的后生成子矩阵。

相关文章:

EmguCV学习笔记 C# 2.2 Matrix类

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 EmguCV学习笔记目录 Vb.net EmguCV学习笔记目录 C# 笔者的博客网址&#xff1a;VB.Net-CSDN博客 教程相关说明以及如何获得pdf教…...

[Windows CMD] 查看网络连接状态 netstat -na | findstr “TCP“

在 Windows 系统中&#xff0c;我们可以使用 netstat 命令来查看网络连接状态&#xff0c;并使用 findstr 命令来过滤出 TCP 和 UDP 的连接。 查看所有网络连接的状态 netstat -na netstat -na: 显示所有网络连接的状态&#xff0c;-n 表示显示数字地址而非域名&#xff0c;…...

「OC」视图控制器的懒加载策略

「OC」视图控制器的懒加载策略 文章目录 「OC」视图控制器的懒加载策略懒加载懒加载的优点常见的懒加载实现方法使用懒加载的注意事项 控制器的懒加载参考资料 懒加载 懒加载&#xff08;Lazy Loading&#xff09;是一种设计模式&#xff0c;其核心思想是在需要时才进行对象的…...

android studio 中 .gitignore 文件改动后 忽略的文件夹或文件无效

问题原因&#xff1a;已跟踪文件的缓存问题&#xff1a; 如果之前已经跟踪了这些文件&#xff08;即它们已经被 Git 加入到版本控制中&#xff09;&#xff0c;即使你在 .gitignore 文件中添加了忽略规则&#xff0c;Git 仍然会显示这些文件。你需要先从 Git 中移除这些文件&am…...

鸿蒙 next 实现摄像头视频预览编码(一)

鸿蒙 next 即将发布&#xff0c;让我们先喊3遍 遥遥领先~ 遥遥领先~ 遥遥领先~ 作为一门新的系统&#xff0c;本人也是刚入门学习中&#xff0c;如果对于一些理解有问题的&#xff0c;欢迎即使指出哈 首先这里要讲一下&#xff0c;在鸿蒙 next 中&#xff0c;要实现摄像头预览…...

YOLO-V3

一、概述 最大的改进就是网络结构&#xff0c;使其更适合小目标检测特征做的更细致&#xff0c;融入多持续特征图信息来预测不同规格物体先验框更丰富了&#xff0c;3种scale&#xff0c;每种3个规格&#xff0c;一共9种softmax改进&#xff0c;预测多标签任务 先验框&#xf…...

golang提案,内置 Go 错误检查函数

先来狠狠吐个槽 要吐槽 Go1 的 error &#xff0c;那咱得先整明白大家为啥都猛喷它的错误处理做得不咋地。在 Go 语言里头&#xff0c;error 本质上其实就是个 Error 的接口&#xff1a; type error interface {Error() string }实际的应用场景如下&#xff1a; func main()…...

零售业务产品系统应用架构设计(三)

智慧物业依据《住房和城乡建设部等部门关于推动物业服务企业加快发展线上线下生活服务的意见建房〔2020〕99号》,推动物业管理公司广泛运用5G、互联网、物联网、云计算、大数据、区块链和人工智能等技术,建设智慧物业管理服务平台,对接城市信息模型(CIM)和城市运行管理服务…...

【GD32】从零开始学GD32单片机 | PMU电源管理单元+深度睡眠和待机例程(GD32F470ZGT6)

1. 简介 PMU电源管理单元通俗讲就是用来管理MCU的电源域的&#xff0c;它主要有两个功能——电压监测和低功耗管理。在GD32中一共有3个电源域——VDD/VDDA域、1.2V域和备份域。 VDD/VDDA域主要供PMU控制器、ADC、DAC等外设使用&#xff1b;1.2V域就是大部分外设都会使用的电源域…...

公司员工电脑桌面太乱如何解决?桌面管理软件一招解决!

“工欲善其事&#xff0c;必先利其器。” 在数字化管理的时代背景下&#xff0c;选择合适的桌面管理软件就如同为企业网络管理装上了一双慧眼。 员工的电脑桌面往往因为长时间的使用而变得杂乱无章&#xff0c;这不仅影响了工作效率&#xff0c;还可能给企业信息安全带来隐患。…...

leetcode:2119. 反转两次的数字(python3解法)

难度&#xff1a;简单 反转 一个整数意味着倒置它的所有位。 例如&#xff0c;反转 2021 得到 1202 。反转 12300 得到 321 &#xff0c;不保留前导零 。 给你一个整数 num &#xff0c;反转 num 得到 reversed1 &#xff0c;接着反转 reversed1 得到 reversed2 。如果 reverse…...

5.vue中axios封装工程化

vue工程化中axios封装 视频演示地址&#xff1a;https://www.bilibili.com/video/BV121egeQEHg/?vd_source0f4eae2845bd3b24b877e4586ffda69a 通常我们封装需要封装request.js基础的发送请求工具类&#xff0c;再根据业务封装service类&#xff0c;service类是具体业务的接口…...

实验六:动态数码管实验

实验结果图,从右到左0-7,从左到右7-0,来回滚动。 硬件接线图: 具体看图,不说了,前面讲过,自己查资料就可以,资料得慢慢查,熟练就好了,不浪费时间和版面了 main.c代码 #include<reg52.h>typedef unsigned int u16; typedef unsigned char u8;#define SMG P0 …...

《Cloud Native Data Center Networking》(云原生数据中心网络设计)读书笔记 -- 05网络虚拟化

本章帮助网络工程师或架构师回答如下问题&#xff1a; 什么是网络虚拟化?网络虚拟化有哪些用途?网络虚拟化领域内有哪些不同的技术方向?网络虚拟化的控制面有哪些选择?当使用 VXLAN 时如何进行桥接和路由&#xff1f; 什么是网络虚拟化&#xff1f; 网络虚拟化可以让网络…...

奥威BI数据可视化展示:如何充分发挥数据价值

奥威BI数据可视化展示&#xff1a;如何充分发挥数据价值 在大数据时代&#xff0c;数据已成为企业最宝贵的资产之一。然而&#xff0c;仅仅拥有海量数据并不足以带来竞争优势&#xff0c;关键在于如何有效地挖掘、分析和展示这些数据&#xff0c;从而转化为有价值的洞察和决策…...

jenkins工具配置

上一篇&#xff08;https://blog.csdn.net/abc666_666/article/details/141207741&#xff09;文章我们介绍了基于docker安装jenkins的过程&#xff0c;本文将介绍如何配置jenkins的相关全局工具如maven、 jdk以及git等 配置的页面如下&#xff1a; 打开后的页面如下&#xff…...

VAuditDemo文件漏洞

目录 VAuditDemo文件漏洞 一、首页文件包含漏洞 包含图片马 利用伪协议phar:// 构造shell.inc被压缩为shell.zip&#xff0c;然后更改shell.zip 为 shell.jpg上传 二、任意文件读取漏洞 avatar.php updateAvatar.php logCheck.php 任意文件读取漏洞利用 VAuditDemo文件…...

[Meachines] [Medium] poison LFI+日志投毒+VNC权限提升

信息收集 IP AddressOpening Ports10.10.10.84TCP:22,80 $ nmap -p- 10.10.10.84 --min-rate 1000 -sC -sV 22/tcp open ssh OpenSSH 7.2 (FreeBSD 20161230; protocol 2.0) | ssh-hostkey: | 2048 e3:3b:7d:3c:8f:4b:8c:f9:cd:7f:d2:3a:ce:2d:ff:bb (RSA) | 256 …...

EtherCAT运动控制器上位机开发之Python+Qt(三):PDO配置与SDO读写

ZMC408CE控制器硬件介绍 ZMC408CE是正运动推出的一款多轴高性能EtherCAT总线运动控制器&#xff0c;具有EtherCAT、EtherNET、RS232、CAN和U盘等通讯接口&#xff0c;ZMC系列运动控制器可应用于各种需要脱机或联机运行的场合。 ZMC408CE支持8轴运动控制&#xff0c;最多可扩展…...

MyBatis源码系列1(使用JDBC查询数据)

使用原生jdbc进行查询数据步骤. 1、加载驱动2、获取数据库连接3、创建Statement对象4、占位符赋值5、执行脚本6、解析结果7、关闭资源 代码示例 public class T0 {public static void main(String[] args) throws Exception {String sql "SELECT id,name FROM goods WH…...

【微服务】Nacos配置中心和客户端数据同步模式

一、Nacos概述 Nacos是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。它提供了一组简单易用的特性集&#xff0c;帮助用户快速实现动态服务发现、服务配置、服务元数据及流量管理。 二、数据同步模式 1. 实时同步 Push模式&#xff1a;在服务端的配置信…...

WebRTC音视频开发读书笔记(六)

数据通道不仅可以发送文本消息, 还可以发送图片、二进制文件,将其类型binaryType属性设置成arraybuffer类型即可. 九\、文件传输 1、文件传输流程 &#xff08;1&#xff09;使用表单file打开本地文件 &#xff08;2&#xff09;使用FileReader读取文件的二进制数据 &#…...

高级列表组件ReList

高级列表组件ReList 组件实现基于 Vue3 Element Plus Typescript&#xff0c;同时引用 vueUse lodash-es tailwindCss (不影响功能&#xff0c;可忽略) 主要基于JSX风格实现高度动态的列表渲染组件&#xff0c;可以通过信息配置Metas配置控制信息项展示&#xff0c;同时支持…...

Vxe UI vue vxe-table 实现表格数据分组功能,根据字段数据分组

Vxe UI vue vxe-table 实现表格数据分组功能&#xff0c;根据字段数据分组 实现数据分组功能 基于树结构功能就可以直接实现数据分组功能&#xff0c;代码如下&#xff1a; <template><div><vxe-button status"primary" click"listToGroup()&…...

oracle创建账户

1、查看表空间 SELECT tablespace_name FROM user_tablespaces;2、创建用户 CREATE USER FLINKCDC2 IDENTIFIED BY "123456";也可以使用指定表空间的方式 CREATE USER FLINKCDC2 IDENTIFIED BY "123456" DEFAULT TABLESPACE LOGMINER_TBS QUOTA UNLIMIT…...

2024新型数字政府综合解决方案(五)

新型数字政府综合解决方案通过集成人工智能、大数据、区块链和云计算技术&#xff0c;打造了一个智能化、透明化和高效的政务服务平台&#xff0c;旨在提升政府服务的响应速度、处理效率和数据安全性。该方案实现了跨部门的数据共享与实时更新&#xff0c;通过智能化的流程自动…...

datawind可视化查询-其他函数

飞书文档学习链接:https://www.volcengine.com/docs/4726/47275 1. 用户名函数 用户名函数并非 ClickHouse 官方函数,而是与项目用户信息相结合,用于返回当前使用用户的指定信息的函数。 USERNAME()可返回当前用户的用户名,如下所示。该函数也可与其他函数组合使用 2. J…...

数据库MySQL之事务、索引

目录 1.概述 2.事务 3.索引 3.1索引结构 3.2操作语法 1.概述 场景&#xff1a;假如我们需要解散教学部&#xff0c;那么该部门下的所有员工都需要删除。如果教学部成功删除了&#xff0c;但员工出于某些原因(比如SQL语句写错了等)并没有删除&#xff0c;此时就会出现数据…...

AI学习记录 - transformers的decoder和encoder中的自注意力矩阵和掩码矩阵的数据处理

掩码掩码&#xff0c;指的是掩盖住后面的词汇的词向量对我当前词汇造成影响。把PAD字符设置成负无穷大&#xff0c;概念上不叫掩码&#xff0c;只是计算方式和掩码一样。 怎么生成掩码&#xff0c;在非掩码注意力矩阵中&#xff0c;把PAD词向量每个维度设置成负无穷大&#xf…...

【Solidity】代币

ERC20 ERC-20 全称 “Ethereum Request for Comment 20”&#xff0c;是一种标准接口&#xff0c;用于实现代币合约。ERC20 标准定义了一组函数和事件&#xff0c;使得代币可以在不同的应用和平台之间互操作。 ERC20 标准接口定义了一组必须实现的函数和事件&#xff1a; in…...

武汉做网站的公司有哪些/短视频运营是做什么的

elasticsearch&#xff08;docker&#xff09;、ik分词器、Kibana 安装及配置、测试 Elastricsearch学习 及 head插件 此篇是Elasticsearch 6.7.2;不同版本差异挺大的&#xff0c;SpringDataElasticsearch对应的版本也不同。 文章目录一、java操作ElasticsearchA. maven坐标 p…...

如何在租用的服务器上部署自己的网站 mysql/霸榜seo

文章目录 知识点实例代码目录代码实现知识点 configure_fileconfigure_file 指令通过读取输入文件中的内容,将 CMakeLists.txt 文件中的变量转变为 C/C++ 中可识别的宏定义, 然后存入另一个文件中 我们使用了如下 CMAKE_PROJECT_VERSIONCMAKE_PROJECT_VERSION_MAJORCMAKE_PRO…...

德州宁津建设局网站/免费推广工具有哪些

古老的unix提出了一切皆文件的思想&#xff0c;近代的OO提出了一切皆对象的理论&#xff0c;在unix的年代&#xff0c;人们迫切需要的是如何操作计算机而不是如何设计软件&#xff0c;毕竟那个时候软件设计其实比现在简单&#xff0c;就那么几种&#xff0c;关键是没有人会操作…...

centos。wordpress/网络营销形式

mac自带python和pip等工具&#xff0c;但是在使用安装scrapy时&#xff0c;报了一些错&#xff0c;因为对操作系统一些核心目录&#xff08;比如/Library&#xff09;没有可操作权限&#xff0c;mac有自己的一些权限控制程序&#xff08;非sudo chmod能改变&#xff09;&#x…...

如何使用阿里云做网站/拉新平台

在开发 Flex 或 AIR 应用程序的时候&#xff0c;如果需要把图片、声音等资源嵌入到目标文件中的时候&#xff0c;一般需要使用到 Embed Embed 标记的功能就是把资源生成一个相应的类&#xff0c;以下是 Embed 标记应的地情况说明&#xff1a; 1、在代码中使用 Embed 标记 [Embe…...

网站制作机构/如何做市场调研和分析

我的新书《Android App开发入门与实战》已于2020年8月由人民邮电出版社出版&#xff0c;欢迎购买。点击进入详情 文章目录layoutlayout中的idanimdrawablevalues中的idlayout 全部小写&#xff0c;采用下划线命名法&#xff0c;使用名词或名词词组。 所有Activity或Fragment的…...