C# 并行元素矩阵(2dArray)计算
这是我的第一个问题,我对C#比较陌生。(请原谅我英语不好) 我正在用C#编写一个模板匹配算法,使用Visual Studio中带有WindowsForms应用程序的.NET Framework。遗憾的是,C#8.0中的新索引和范围函数,特别是范围操作符(..),没有在.NET框架中实现。我知道有一个解决办法,你可以在这里看到,但它是不受微软支持。因此,我正在寻找另一种方法来并行我的elementwise 2D数组(矩阵)计算,以使我的程序更快 在我的程序中,我正在计算一个二维数组(我的图像)和一个二维数组(我的模板)中一个区域(具有模板大小)的微分平方(ds)。这些值被写入一个新的2dAary(DS)中,该2dAary(DS)将所有微分方块保存在图像的相应位置。我可以搜索DS的索引,其中微分平方最小,等于模板在图像中的匹配位置(模板和图像之间的最高对应) 在python中,使用索引范围操作符(:)计算DS非常快,如下所示: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数组(矩阵)计算,以使我的程序更快 在我的程序中,我正在计算一个二维数组(我的图像)和一
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();
}
}
}