简体   繁体   English

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

[英]Effective algorithm for finding 16x16 pixel same squares in a big image - C#

i am coding a software at visual studio 2010 by using C#. 我正在使用C#在Visual Studio 2010上编码软件。 what does this software do is finding same squares at the image after a square selected. 该软件的作用是在选择一个正方形后在图像上找到相同的正方形。 every square is composed by 16x16 pixel. 每个正方形由16x16像素组成。 my current algorithm starts from first pixel and scan the entire image pixel by pixel comparing to determine same pixel squares with the selected one. 我目前的算法是从第一个像素开始,然后逐个像素扫描整个图像,以确定与所选像素相同的像素平方。 this takes really big time. 这需要很多时间。 Can you suggest me any better way ? 你能建议我更好的办法吗?

also every square is ordered. 每个广场也是有序的。 so they start like 0 - 16 - 32 - 48 所以他们开始像0-16-32-48

a square can not start from 5 or 65 etc 一个正方形不能以5或65等开头

thank you 谢谢

You could cache a checksum of each image-region. 您可以缓存每个图像区域的校验和。 Then you would only have to check ones that match the checksum for equality. 然后,您只需要检查与校验和匹配的项是否相等即可。

Let's assume each image is 16x16 rgb elements. 假设每个图像都是16x16 rgb元素。 You could do this (and yes, it will have integer overflow.) 您可以这样做(是的,它将有整数溢出。)

All of this is in pseudo code - you're expected to be able to translate this to C#. 所有这些都是伪代码-您应该可以将其转换为C#。

Add an int to the field image class, or create an image wrapper with an int as the 'checksum' 将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

Now when you go to search you can go like this: 现在,当您进行搜索时,您可以像这样:

/**
 * 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;
}

One algorithm I know of to compare how similar two images are is the root mean square algorithm. 我知道用来比较两个图像有多相似的一种算法是均方根算法。 I've used this in several programs and it's always been pretty fast. 我已经在多个程序中使用了它,并且一直非常快。 This simply sums up the differences, does some math, and the difference will be 'how close' the two images are to each other. 这简单地总结了差异,进行了一些数学运算,差异将是两个图像彼此之间的“距离”。

But, if the access is slow for comparison of each pixel, then access will still be slow (albeit slightly faster) adding them all up (or checksumming it). 但是,如果访问速度较慢,无法比较每个像素,则访问速度仍然会很慢(尽管速度稍快),将它们全部加起来(或校验和)。

Another option would be to add a short-circuit. 另一种选择是增加短路。 The second any pixel at all doesn't match, you can claim the whole picture doesn't match. 第二个像素根本不匹配,您可以声称整个图片不匹配。

I would be curious why this is going slow, though. 我会很好奇为什么速度会变慢。 The image would have to be incredibly large for it to not count. 图像必须非常大才能不计数。 Are you using Bitmap.GetPixel()? 您正在使用Bitmap.GetPixel()吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM