在Visual Studio C#中使用GPU进行图像比较
我是图像处理新手。我有一个图像的一部分,我必须通过比较像素在整个图像中搜索。我需要得到完整图像中小图像的坐标 那么,我在做什么在Visual Studio C#中使用GPU进行图像比较,c#,visual-studio,opencl,gpu,C#,Visual Studio,Opencl,Gpu,我是图像处理新手。我有一个图像的一部分,我必须通过比较像素在整个图像中搜索。我需要得到完整图像中小图像的坐标 那么,我在做什么 for int i = 0 to Complete_Image.Lenght for int j = 0 to Complete_Image.Height for int x = 0 to Small_Image.Lenght for int y = 0 to Small_Image.Height if Complete_Image[i+j+x][i
for int i = 0 to Complete_Image.Lenght
for int j = 0 to Complete_Image.Height
for int x = 0 to Small_Image.Lenght
for int y = 0 to Small_Image.Height
if Complete_Image[i+j+x][i+j+y] == Small_Image[x][y]
Message "image found at coordinate x, y"
Break
它是一种简单的像素匹配算法,通过比较像素在完整图像中找到图像的某一部分
这很费时。例如,如果必须在1000 X 1000图像中查找50X50图像的坐标,则需要进行1000 X 1000 X 50 X 50像素的颜色比较
因此:
- 有没有更好的方法在C#中进行图像比较
- 我可以使用AMD Radeon 460 GPU并行地进行比较吗?或者至少部分算法使用GPU电源
无论如何,我已经没有时间了,也许可以在以后完成并行版本 前提是被动地遍历子图像,如果发现一整行像素匹配,则执行子循环以比较整个子图像
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool CheckSubImage(int* m0, int* s0, Rectangle mR, Rectangle sR, int x, int y, out Point? result)
{
result = null;
for (int sX = 0, mX = x; sX < sR.Width && mX < mR.Right; sX++, mX++)
for (int sY = 0, mY = y; sY < sR.Height && mY < mR.Bottom; sY++, mY++)
if (*(m0 + mX + mY * mR.Width) != *(s0 + sX + sY * sR.Width))
return false;
result = new Point(x, y);
return true;
}
protected override Point? GetPoint(string main, string sub)
{
using (Bitmap m = new Bitmap(main), s = new Bitmap(sub))
{
Rectangle mR = new Rectangle(Point.Empty, m.Size), sR = new Rectangle(Point.Empty, s.Size);
var mD = m.LockBits(mR, ImageLockMode.ReadOnly, PixelFormat.Format32bppPArgb);
var sD = s.LockBits(sR, ImageLockMode.ReadOnly, PixelFormat.Format32bppPArgb);
int* m0 = (int*)mD.Scan0, s0 = (int*)sD.Scan0;
for (var x = mR.Left; x < mR.Right; x++)
for (var y = mR.Top; y < mR.Bottom; y++)
if (*(m0 + x + y * mR.Width) == *s0)
if (CheckSubImage(m0, s0, mR, sR, x, y, out var result))
return result;
m.UnlockBits(mD);
s.UnlockBits(sD);
}
return null;
}
结果比简单的4循环方法快100倍左右
注意,这使用了不安全关键字,因此您必须将project设置为允许不安全
免责声明:这可以进行更多优化,也可以并行进行,显然在gpu上会更快。关键是算法与处理器无关是的,你可以使用C语言的GPU# 这里有他们图书馆的教程 您需要在OpenCL中编写一些说明 您可能还需要检查是否有opencl()的
代码主要是样板文件。非常直截了当。安装依赖项可能比编写代码花费更多的时间。即使没有gpu,您也可以加快速度。通过使用一些智能、固定内存、指针访问和并行处理。不管gpu与否,这都是你如何实现的,它的速度将得到最大的提高。您当前的算法时间复杂度高,效率低。两幅图像的像素完美匹配的频率是多少?您确定这是您想要的搜索类型吗?将只有一个精确匹配。我有一个截图的一部分,我必须在完整的截图中找到,并得到它的坐标。只有一个精确匹配。有更好的算法和/或GPU处理吗?显然,GPU会更快,这取决于你想走多快,我得到的5000*3000图像的速度不到10秒,寻找300*300图像,在非GPU中没有并行处理,与原始算法相当,运行时间约为10秒。然而,我只是调整了一个并行版本,这样我应该能够更快地获得它。谢谢代码。我试试看。我现有的代码占用了太多的CPU,无法在1600 X 900的屏幕截图中找到50 X 50的图像。所以,我必须找到一个更好的算法,或者使用GPU实现4循环方法。
var result = GetPoint(@"D:\TestImages\Main.bmp", @"D:\TestImages\1159-980.bmp");