C#实现相似图片搜索(根据缩略图,找出原图)

遊戲王千金 2012-10-10 10:22:41
在网络上搜索该功能实现方式,
找到大神用python实现
http://www.ruanyifeng.com/blog/2011/07/principle_of_similar_image_search.html
具体代码

#!/usr/bin/python

import glob
import os
import sys

from PIL import Image

EXTS = 'jpg', 'jpeg', 'JPG', 'JPEG', 'gif', 'GIF', 'png', 'PNG'

def avhash(im):
if not isinstance(im, Image.Image):
im = Image.open(im)
im = im.resize((8, 8), Image.ANTIALIAS).convert('L')
avg = reduce(lambda x, y: x + y, im.getdata()) / 64.
return reduce(lambda x, (y, z): x | (z << y),
enumerate(map(lambda i: 0 if i < avg else 1, im.getdata())),
0)

def hamming(h1, h2):
h, d = 0, h1 ^ h2
while d:
h += 1
d &= d - 1
return h

if __name__ == '__main__':
if len(sys.argv) <= 1 or len(sys.argv) > 3:
print "Usage: %s image.jpg [dir]" % sys.argv[0]
else:
im, wd = sys.argv[1], '.' if len(sys.argv) < 3 else sys.argv[2]
h = avhash(im)

os.chdir(wd)
images = []
for ext in EXTS:
images.extend(glob.glob('*.%s' % ext))

seq = []
prog = int(len(images) > 50 and sys.stdout.isatty())
for f in images:
seq.append((f, hamming(avhash(f), h)))
if prog:
perc = 100. * prog / len(images)
x = int(2 * perc / 5)
print '\rCalculating... [' + '#' * x + ' ' * (40 - x) + ']',
print '%.2f%%' % perc, '(%d/%d)' % (prog, len(images)),
sys.stdout.flush()
prog += 1

if prog: print
for f, ham in sorted(seq, key=lambda i: i[1]):
print "%d\t%s" % (ham, f)


现在想把该Python代码转为C#,因不懂python语法,转为C#有点困难,故求论坛高手帮助
python代码实现思路是
第一步,缩小尺寸。
将图片缩小到8x8的尺寸,总共64个像素。这一步的作用是去除图片的细节,只保留结构、明暗等基本信息,摒弃不同尺寸、比例带来的图片差异。

第二步,简化色彩。

将缩小后的图片,转为64级灰度。也就是说,所有像素点总共只有64种颜色。

第三步,计算平均值。

计算所有64个像素的灰度平均值。

第四步,比较像素的灰度。

将每个像素的灰度,与平均值进行比较。大于或等于平均值,记为1;小于平均值,记为0。

第五步,计算哈希值。

大家保持队形,l楼让我先来
...全文
1228 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
shellyforever 2012-10-29
  • 打赏
  • 举报
回复
既然楼主解决这个大难题了,就把代码共享一下可以吗。
csdn_风中雪狼 2012-10-16
  • 打赏
  • 举报
回复
你是根据avhash的返回值做比较吗,
我刚测试了下,同一个图片的缩略图与原图通过调用 avhash 返回值,相差是很大的,
这个应该怎么样来判断,是否就是它的原图呢,
这个范围在好多之内,
csdn_风中雪狼 2012-10-16
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 的回复:]
自己写个findSameImage的比较图片就行。调用avhash
我没有按jshi123 写的那个Main方法去测试
[/Quote]
能否讲或共享,
调用avhash,怎么来进行比较
比较两个值还是什么的
遊戲王千金 2012-10-16
  • 打赏
  • 举报
回复
自己写个findSameImage的比较图片就行。调用avhash
我没有按jshi123 写的那个Main方法去测试
csdn_风中雪狼 2012-10-16
  • 打赏
  • 举报
回复
把传入的原图目录下,所有图片都输出来了,
lz你是怎么解决的?
csdn_风中雪狼 2012-10-16
  • 打赏
  • 举报
回复
唉,不对呢,
为什么这边测试的时候,
每次都是把 指定目录下的 所有图片都输出出来了,
那一个才是找到的原图呢

0 E:\test\test\image\aa.jpg
0 E:\test\test\image\asf45a.jpg
0 E:\test\test\image\bg2011072103.jpg
0 E:\test\test\image\fsfsfsf.jpg
csdn_风中雪狼 2012-10-16
  • 打赏
  • 举报
回复
今天测试了下,
太牛了,
learnJSee
你十一楼的那个代码,是搞什么的,
也是放在 jshi123 写的 C# 代码中吗
遊戲王千金 2012-10-11
  • 打赏
  • 举报
回复
超赞jshi123 写得C#代码

// convert('L')
var data = new long[64];
for (int y = 0; y < bmp.Height; y++)
{
for (int x = 0; x < bmp.Width; x++)
{
Color c = bmp.GetPixel(x, y);
var l = c.R * 299 / 1000 + c.G * 587 / 1000 + c.B * 114 / 1000;
data[y * 8 + x] = l;
}
}
var avg = data.Sum() / 64;
return data.Select((i, y) => new { y, z = i < avg ? 0 : 1 }).Aggregate(0L, (x, a) => x | ((long)a.z << a.y));



遊戲王千金 2012-10-11
  • 打赏
  • 举报
回复
上面的算法,可根据缩略图,找出原图,很不错。
但作者说的 "汉明距离"(Hamming distance)。如果不相同的数据位不超过5,就说明两张图片很相似;
经过测试,不能达到理想,误差可能会很大。


csdn_风中雪狼 2012-10-11
  • 打赏
  • 举报
回复
楼主,
解决了,
共享下吧
一滴巫血 2012-10-11
  • 打赏
  • 举报
回复
不明白,超出我理解,关注中。。
jokeesloat 2012-10-10
  • 打赏
  • 举报
回复
不明白,还是继续学习吧。
zyug 2012-10-10
  • 打赏
  • 举报
回复
窃以为你这种改代码的方式不可取

现在原理你有了。
技术手段也有了,
只差实现了.

照着别人的代码改一次。没有自己想法,不好。
遊戲王千金 2012-10-10
  • 打赏
  • 举报
回复
求reduce在C#里如何破
reduce的语法
python中的reduce内建函数是一个二元操作函数,他用来将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给reduce中的函数 func()(必须是一个二元操作函数)先对集合中的第1,2个数据进行操作,得到的结果再与第三个数据用func()函数运算,最后得到一个结果。
例子
reduce(lambda x,y: x.capitalize()+y, ['a', 'b', 'c','d'])
第一次 x='a' y='b' 返回Ab
第二次x='Ab' y='c' 返回Abc
第三次x='Abc' y='d' 返回Abcd
LMAOhuaNL 2012-10-10
  • 打赏
  • 举报
回复
这个真的高级了,
zyug 2012-10-10
  • 打赏
  • 举报
回复
VisualC#图像处理程序设计实例
搜索一下这本书,如果只是基本的操作,都有介绍

如果只是近似的对比缩略图灰度之类的。误差可能会很大

遊戲王千金 2012-10-10
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
根据缩略图找原图?。。。
难度很大哟

插值算法呢。

双线性插值,还是三次卷积。。。。。
[/Quote]
http://www.ruanyifeng.com/blog/2011/07/principle_of_similar_image_search.html这篇博文有介绍方法,都我无法运行python代码,第一步先将作者为python代码改为C#,运行看才知道,个人觉得博文介绍方法是能实现相似图片搜索的功能.
zyug 2012-10-10
  • 打赏
  • 举报
回复
根据缩略图找原图?。。。
难度很大哟

插值算法呢。

双线性插值,还是三次卷积。。。。。

遊戲王千金 2012-10-10
  • 打赏
  • 举报
回复
C#处理缩小尺寸,没resize这么方便的方法,先写一个resizeImage方法

private static Image resizeImage(Image imgToResize, Size size)
{
int sourceWidth = imgToResize.Width;
int sourceHeight = imgToResize.Height;

float nPercent = 0;
float nPercentW = 0;
float nPercentH = 0;

nPercentW = ((float)size.Width / (float)sourceWidth);
nPercentH = ((float)size.Height / (float)sourceHeight);

if (nPercentH < nPercentW)
nPercent = nPercentH;
else
nPercent = nPercentW;

int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);

Bitmap b = new Bitmap(destWidth, destHeight);
Graphics g = Graphics.FromImage((Image)b);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;

g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
g.Dispose();

return (Image)b;
}
加载更多回复(1)

62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧