Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在大图像中查找16x16像素相同正方形的有效算法-C#_C#_Algorithm_Image Processing - Fatal编程技术网

在大图像中查找16x16像素相同正方形的有效算法-C#

在大图像中查找16x16像素相同正方形的有效算法-C#,c#,algorithm,image-processing,C#,Algorithm,Image Processing,我正在visual studio 2010中使用C#编写一个软件。该软件的作用是在选定正方形后在图像中查找相同的正方形。每个正方形由16x16像素组成。我当前的算法从第一个像素开始,逐像素扫描整个图像,比较以确定与所选像素相同的像素正方形。这要花很多时间。你能给我提个更好的建议吗 而且每一个正方形都是有序的。所以他们开始时是0-16-32-48 正方形不能从5或65等开始 谢谢您可以缓存每个图像区域的校验和。然后,您只需检查与校验和匹配的值是否相等 让我们假设每个图像是16x16个rgb元素。您

我正在visual studio 2010中使用C#编写一个软件。该软件的作用是在选定正方形后在图像中查找相同的正方形。每个正方形由16x16像素组成。我当前的算法从第一个像素开始,逐像素扫描整个图像,比较以确定与所选像素相同的像素正方形。这要花很多时间。你能给我提个更好的建议吗

而且每一个正方形都是有序的。所以他们开始时是0-16-32-48

正方形不能从5或65等开始


谢谢

您可以缓存每个图像区域的校验和。然后,您只需检查与校验和匹配的值是否相等

让我们假设每个图像是16x16个rgb元素。您可以这样做(是的,它将有整数溢出)

所有这些都是用伪代码编写的——您应该能够将其转换为C

向field image类添加一个int,或创建一个以int作为“校验和”的图像包装器

int checksum = 0
for each pixel in image {
   checksum += pixel.red + pixel.blue + pixel.green
   // you could do anything you wanted here, like
   // checksum *= 17 + pixel.red
   // checksum *= 17 + pixel.blue
   // checksum *= 17 + pixel.green
   // just make it "unique enough", like a hashcode
}
image.checksum = checksum
现在,当您进入搜索时,您可以这样做:

/**
 * equals method before: 
 */
boolean equals(image a, image b) {
  for x = 0..15 do /* all 16 pixels in X */
    for y = 0..15 do /* all 16 pixels in Y */
      if a.getPixel(x,y) != b.getPixel(x,y) return false;
  return true;
}

/**
 * equals method after: 
 *.
boolean equals(image a, image b) {
  /* this check lets you skip the loop in most cases */
  /* still have to verify that the image is equal pixel for pixel though */
  if a.checksum != b.checksum return false;
  for x = 0..15 do /* all 16 pixels in X */
    for y = 0..15 do /* all 16 pixels in Y */
      if a.getPixel(x,y) != b.getPixel(x,y) return false;
  return true;
}

我知道的一种比较两幅图像相似程度的算法是均方根算法。我已经在几个程序中使用过这个,而且一直都很快。这简单地总结了差异,做了一些数学计算,差异将是两个图像彼此“有多近”

但是,如果对每个像素进行比较时访问速度较慢,那么将所有像素相加(或对其进行校验和)时访问速度仍然较慢(尽管稍快)

另一种选择是增加短路。第二个像素完全不匹配,你可以说整个图片不匹配


不过,我很好奇,为什么进展缓慢。图像必须非常大才能不被计算。您使用的是Bitmap.GetPixel()?

与校验和相比,我看不到任何可以提高速度的东西-如果校验和不匹配(它是缓存的,所以您只能计算一次)您可以跳过检查图像的整个过程。@PokemonCraft:关键是他正在计算并存储每个16x16区域的校验和。因此,当您想查看一个区域是否与另一个区域相同时,您需要查看校验和列表,查找与您要比较的区域的校验和匹配的校验和。这是一个简单的整数比较,在大多数情况下校验和不匹配。当存在匹配时,您必须对这两个区域进行详细比较。这种方法速度更快,因为你不必经常做详细的比较。@Jim谢谢。当图像包含几乎相同的像素(例如,它们都具有相同的透明过滤背景色)时,它确实会发光。感谢您对校验和工作原理的详细解释。有一种100%安全的方法。将所有rgb代码相加为字符串。然后md5将它们散列。这将是平方(16x16)像素的校验和。这将只在第一次运行(init)时需要时间。我并没有试图找出2张图片是否相似。我只需要在我的软件中对图像进行逐方块编码,这样可以加快选择方块并为它们赋值的速度。这里我如何得到像素颜色pixelColor=image.GetPixel(x,y);我的电脑有8个内核,在4.8GHz下工作,但软件不能在多线程atm:D下工作