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