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

时间:2011-02-23 22:16:54

标签: c# algorithm image-processing

我正在使用C#在visual studio 2010上编写软件。这个软件做的是在选择正方形后在图像上找到相同的正方形。每个方块由16x16像素组成。我当前的算法从第一个像素开始并逐个像素地扫描整个图像,以确定与所选像素相同的像素方块。这需要很长时间。你能建议我更好的方法吗?

也订购了每个广场。所以他们开始像0 - 16 - 32 - 48

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

谢谢

2 个答案:

答案 0 :(得分:6)

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

假设每个图像都是16x16 rgb元素。你可以这样做(是的,它会有整数溢出。)

所有这些都是伪代码 - 您应该能够将其转换为C#。

在字段图像类中添加一个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;
}

答案 1 :(得分:1)

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

但是,如果对于每个像素的比较访问速度很慢,那么访问仍然会很慢(尽管稍微快一些)将它们全部添加(或校验它)。

另一种选择是添加短路。第二个任何像素都不匹配,你可以声称整个图片不匹配。

我很好奇为什么这会变得缓慢。图像必须非常大,因为它不计算在内。你在使用Bitmap.GetPixel()?