当前位置:   article > 正文

python 找出图片中的差异点_Python3.0以上版本在对比图片相似中的应用

python 机器学习 找图片不同

在网上找的代码,用了方法一,效果很棒!

Python 3.4   以及 Pillow (4.0.0)  第三方包。

方法一、

#!/usr/bin/python

# coding : utf-8

import glob

import os

import sys

from functools import reduce

from PIL import Image

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

EXTS = 'jpg', 'jpeg', 'gif', 'png'

# 通过计算哈希值来得到该张图片的“指纹”

def avhash(im):

# 判断参数im,是不是Image类的一个参数

try:

if not isinstance(im, Image.Image):

im = Image.open(im)

except OSError as ose:

print("打不开图片:{}".format(im))

return "ng"

# resize,格式转换,把图片压缩成8*8大小,ANTIALIAS是抗锯齿效果开启,“L”是将其转化为

# 64级灰度,即一共有64种颜色

im = im.resize((8, 8), Image.ANTIALIAS).convert('L')

# 递归取值,这里是计算所有

# 64个像素的灰度平均值

avg = reduce(lambda x, y: x + y, im.getdata()) / 64.

print(reduce(func_reduce_param, enumerate(map(lambda i: 0 if i < avg else 1, im.getdata())), 0))

# 比较像素的灰度,将每个像素的灰度与平均值进行比较,>=avg:1;

return reduce(func_reduce_param,

enumerate(map(lambda i: 0 if i < avg else 1, im.getdata())), 0)

def func_reduce_param(x, a):

if type(a) == tuple:

y = a[0]

z = a[1]

return x | (z << y)

# 比较指纹,等同于计算“汉明距离”(两个字符串对应位置的字符不同的个数)

def hamming(h1, h2):

if h1 == "ng" or h2 == "ng":

return "获取指纹失败。"

h, d = 0, h1 ^ h2

while d:

h += 1

d &= d - 1

return h

def compare(img1, img2):

if os.path.isfile(img1):

print("源图为:{}".format(img1))

else:

print("给定的源图片:{} 不存在".format(img1))

return "img1"

if os.path.isfile(img2):

print("对比图为:{}".format(img2))

else:

print("给定的对比图片:{} 不存在".format(img2))

return "img2"

ham = hamming(avhash(img2), avhash(img1))

if type(ham) == int:

if ham == 0:

print("源图:{} 与对比图:{} 一样。{}".format(img1, img2, ham))

elif ham <= 3:

print("源图:{} 与对比图:{} 存在差异。{}".format(img1, img2, ham))

elif ham <= 5:

print("源图:{} 与对比图:{} 对比明显存在差异。{}".format(img1, img2, ham))

elif ham <= 8:

print("源图:{} 与对比图:{} 还能看到一点儿相似的希望。{}".format(img1, img2, ham))

elif ham <= 10:

print("源图:{} 与对比图:{} 这两张图片有相同点,但少的可怜啊。{}".format(img1, img2, ham))

elif ham > 10:

print("源图:{} 与对比图:{} 不一样。{}".format(img1, img2, ham))

else:

print("未知的结果,无法完成对比。")

return ""

def compare_many_pic(img, abs_dir):

if os.path.isfile(img):

print("源图为:{}".format(img))

else:

print("给定的源图片:{} 不存在".format(img))

print("Usage: image.jpg [dir]")

return "img"

if os.path.isdir(abs_dir):

print("给定目录为:{}".format(abs_dir))

else:

print("给定的目录:{} 不存在".format(abs_dir))

print("Usage: image.jpg [dir]")

return "dir"

h = avhash(img)

os.chdir(abs_dir)

images = []

for ext in EXTS:

images.extend(glob.glob('*.%s' % ext))

print(images)

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("{}\t{}".format(ham, f))

return ""

if __name__ == '__main__':

compare(img1="./images/1.png", img2="./images/4.png")

方法二、 # 原作者发布在GitHub上的一些列图片对比的方法。

有兴趣研究的可以访问链接如下: # https://github.com/MashiMaroLjc/Learn-to-identify-similar-images

# coding : utf-8

from PIL import Image

def calculate(image1, image2):

g = image1.histogram()

s = image2.histogram()

assert len(g) == len(s), "error"

data = []

for index in range(0, len(g)):

if g[index] != s[index]:

data.append(1 - abs(g[index] - s[index]) / max(g[index], s[index]))

else:

data.append(1)

return sum(data) / len(g)

def split_image(image, part_size):

pw, ph = part_size

w, h = image.size

sub_image_list = []

assert w % pw == h % ph == 0, "error"

for i in range(0, w, pw):

for j in range(0, h, ph):

sub_image = image.crop((i, j, i + pw, j + ph)).copy()

sub_image_list.append(sub_image)

return sub_image_list

def classfiy_histogram_with_split(image1, image2, size=(256, 256), part_size=(64, 64)):

'''

'image1' 和 'image2' 都是Image 对象.

可以通过'Image.open(path)'进行创建。

'size' 重新将 image 对象的尺寸进行重置,默认大小为256 * 256 .

'part_size' 定义了分割图片的大小.默认大小为64*64 .

返回值是 'image1' 和 'image2'对比后的相似度,相似度越高,图片越接近,达到100.0说明图片完全相同。

'''

img1 = image1.resize(size).convert("RGB")

sub_image1 = split_image(img1, part_size)

img2 = image2.resize(size).convert("RGB")

sub_image2 = split_image(img2, part_size)

sub_data = 0

for im1, im2 in zip(sub_image1, sub_image2):

sub_data += calculate(im1, im2)

x = size[0] / part_size[0]

y = size[1] / part_size[1]

pre = round((sub_data / (x * y)), 6)

print(pre * 100)

return pre * 100

if __name__ == '__main__':

image1 = Image.open("./images/1.png")

image2 = Image.open("./images/brain.jpg")

classfiy_histogram_with_split(image1, image2)

对比方法一和方法二,在执行的效率上基本一致,但是在对比的准确度上,方法二要优于方法一。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/287767
推荐阅读
相关标签
  

闽ICP备14008679号