C# 并行元素矩阵(2dArray)计算

C# 并行元素矩阵(2dArray)计算,c#,arrays,matrix,optimization,parallel-processing,C#,Arrays,Matrix,Optimization,Parallel Processing,这是我的第一个问题,我对C#比较陌生。(请原谅我英语不好) 我正在用C#编写一个模板匹配算法,使用Visual Studio中带有WindowsForms应用程序的.NET Framework。遗憾的是,C#8.0中的新索引和范围函数,特别是范围操作符(..),没有在.NET框架中实现。我知道有一个解决办法,你可以在这里看到,但它是不受微软支持。因此,我正在寻找另一种方法来并行我的elementwise 2D数组(矩阵)计算,以使我的程序更快 在我的程序中,我正在计算一个二维数组(我的图像)和一

这是我的第一个问题,我对C#比较陌生。(请原谅我英语不好)

我正在用C#编写一个模板匹配算法,使用Visual Studio中带有WindowsForms应用程序的.NET Framework。遗憾的是,C#8.0中的新索引和范围函数,特别是范围操作符(..),没有在.NET框架中实现。我知道有一个解决办法,你可以在这里看到,但它是不受微软支持。因此,我正在寻找另一种方法来并行我的elementwise 2D数组(矩阵)计算,以使我的程序更快

在我的程序中,我正在计算一个二维数组(我的图像)和一个二维数组(我的模板)中一个区域(具有模板大小)的微分平方(ds)。这些值被写入一个新的2dAary(DS)中,该2dAary(DS)将所有微分方块保存在图像的相应位置。我可以搜索DS的索引,其中微分平方最小,等于模板在图像中的匹配位置(模板和图像之间的最高对应)

在python中,使用索引范围操作符(:)计算DS非常快,如下所示:

H,W = I.shape                                # read out Height H & Width W from Image I
h,w = T.shape                                # read out Height h & Width w from Template T

for i in range(H-h+1):
        for j in range(W-w+1):
            DS[i,j] = np.sum((I[i:i+h,j:j+w] - T)**2)
但在C#中,我必须对DS元素进行计算,因此它看起来像这样,并且永远需要:

int Tw = template.Width;
int Th = template.Height;
int Iw = image.Width;
int Ih = image.Height;

int d = 0;
int[,] ds = new int[Tw, Th];
int[,] DS = new int[Iw - Tw + 1, Ih - Th + 1];
         
for (int y = 0; y < Ih - Th + 1; y++)
        {
            for (int x = 0; x < Iw - Tw + 1; x++)
            {
                for (int yT = 0; yT < Th; yT++)
                {
                    for (int xT = 0; xT < Tw; xT++)
                    {
                        d = I[x + xT, y + yT] - T[xT, yT];
                        ds[xt, yt] = d * d;
                    }
                }

                int sum = ds.Cast<int>().Sum();
                DS[x, y] = sum;
            }
        }
int Tw=模板宽度;
int Th=模板高度;
int Iw=图像宽度;
int Ih=图像高度;
int d=0;
int[,]ds=新的int[Tw,Th];
int[,]DS=新的int[Iw-Tw+1,Ih-Th+1];
对于(int y=0;y
我知道我可以使用线程,但这对我来说有点复杂。 或者我可以使用CUDA和我的Nvidia GPU来加快速度

但我在问你和我自己,有没有其他方法来并行(优化)我的元素数组计算

我期待任何帮助。 非常感谢

编辑:

这里有一个.NETFramework控制台应用程序代码的工作示例。如您所见,我进行了大量的元素二维和三维阵列计算,我希望并行处理这些计算(或以任何其他方式更快地执行它们):

使用系统;
使用系统图;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
命名空间模板匹配器控制台
{
班级计划
{
公共静态整型[,]位图矩阵(位图bmp)
{
int[,]I=新int[bmp.Width,bmp.Height,3];
对于(int y=0;yusing System;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TemplateMatcher_Console
{
    class Program
    {
        public static int[,,] bitmapToMatrix(Bitmap bmp)
        {
            int[,,] I = new int[bmp.Width, bmp.Height, 3];

            for (int y = 0; y < bmp.Height; y++)
            {
                for (int x = 0; x < bmp.Width; x++)
                {
                    Color pix = bmp.GetPixel(x, y);

                    I[x, y, 0] = Convert.ToInt32(pix.R);
                    I[x, y, 1] = Convert.ToInt32(pix.G);
                    I[x, y, 2] = Convert.ToInt32(pix.B);
                }
            }

            return I;
        }

        public static int[] indexOfMiniumValue(int[,] matrix)
        {
            int value = 0;
            int minValue = 999999999;
            int minFirstIndex = 0;
            int minSecondIndex = 0;

            int[] ij = new int[2];

            for (int i = 0; i < matrix.GetLength(0); i++)
            {
                for (int j = 0; j < matrix.GetLength(1); j++)
                {
                    value = matrix[i, j];

                    if (value < minValue)
                    {
                        minValue = value;

                        minFirstIndex = i;
                        minSecondIndex = j;
                    }
                }
            }

            ij[0] = minFirstIndex;
            ij[1] = minSecondIndex;

            return ij;
        }

        public static void Print2DArray<T>(T[,] matrix)
        {
            for (int i = 0; i < matrix.GetLength(0); i++)
            {
                for (int j = 0; j < matrix.GetLength(1); j++)
                {
                    Console.Write(matrix[i, j] + "\t");
                }
                Console.WriteLine();
            }
        }

        static void Main(string[] args)
        {
            // Deklaration & Eingabe

            Console.WriteLine("Type the filepath for your image and then press Enter");
            string im = Console.ReadLine();

            Console.WriteLine("\nType the filepath for your template and then press Enter");
            string temp = Console.ReadLine();

            Bitmap template = new Bitmap(@temp);
            Bitmap image = new Bitmap(@im);

            int Tw = template.Width;
            int Th = template.Height;
            int Iw = image.Width;
            int Ih = image.Height;

            int[,] ds = new int[Tw, Th];
            int[,] DS = new int[Iw - Tw + 1, Ih - Th + 1];
            int[,,] DS_rgb = new int[Iw - Tw + 1, Ih - Th + 1, 3];

            int[] xy = new int[2];


            // Verarbeitung
            // int[,,] I = Array.ConvertAll(image_I, new Converter<byte, int>(Convert.ToInt32));
            int[,,] I = bitmapToMatrix(image);
            int[,,] T = bitmapToMatrix(template);


            for (int rgb = 0; rgb < 3; rgb++)
            {
                for (int y = 0; y < Ih - Th + 1; y++)
                {
                    for (int x = 0; x < Iw - Tw + 1; x++)
                    {
                        //DS_rgb[x, y, rgb] = (I[x .. x + template.Width, y .. y + template.Height, rgb] - T[0 .. template.Width, 0 .. template.Height, rgb]);
                        for (int yT = 0; yT < Th; yT++)
                        {
                            for (int xT = 0; xT < Tw; xT++)
                            {
                                ds[xT, yT] = (I[x + xT, y + yT, rgb] - T[xT, yT, rgb]) * (I[x + xT, y + yT, rgb] - T[xT, yT, rgb]);
                            }
                        }

                        int sum = ds.Cast<int>().Sum();
                        DS_rgb[x, y, rgb] = sum;
                    }
                }
            }


            //DS[.., ..] = DS_rgb[.., .., 0] + DS_rgb[.., .., 1] + DS_rgb[.., .., 2];
            for (int y = 0; y < Ih - Th + 1; y++)
            {
                for (int x = 0; x < Iw - Tw + 1; x++)
                {
                    DS[x, y] = DS_rgb[x, y, 0] + DS_rgb[x, y, 1] + DS_rgb[x, y, 2];
                }
            }

            //xy = DS.FindIndex(z => z == Math.Min(DS));
            xy = indexOfMiniumValue(DS);

            // Ausgabe

            // Ausgeben der Matrix DS
            /*
            Console.WriteLine("\nMatrix with all differtial squares:");
            Print2DArray(DS);
            */

            Console.WriteLine($"\nPosition of your template in your image (upper left corner): ({xy[0]}, {xy[1]})");
            Console.Write("\nPress any key to close the TemplateMatcher console app...");
            Console.ReadKey();
        }
    }
}