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

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

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)

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用Python的图像处理库和特征提取算法来实现这个功能。以下是一个可能的实现方法: 1. 导入必要的库: ```python import os import cv2 import numpy as np from skimage.measure import compare_ssim ``` 2. 定义一个函数来计算两张图片之间的相似度,可以使用结构相似性指数(SSIM)作为相似度度量标准: ```python def calculate_similarity(image1, image2): # 将图像转换为灰度图 gray1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY) gray2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY) # 计算SSIM值 (_, similarity) = compare_ssim(gray1, gray2, full=True) return similarity ``` 3. 定义一个函数来查和目标图片相似图片: ```python def find_similar_image(target_image_path, folder_path): # 读取目标图片 target_image = cv2.imread(target_image_path) # 遍历文件夹的所有图片文件 max_similarity = 0 similar_image_path = None for file_name in os.listdir(folder_path): file_path = os.path.join(folder_path, file_name) # 忽略非图片文件 if not file_path.endswith(('.jpg', '.jpeg', '.png')): continue # 读取当前图片 current_image = cv2.imread(file_path) # 计算当前图片与目标图片相似度 similarity = calculate_similarity(target_image, current_image) # 更新最相似图片的路径和相似度 if similarity > max_similarity: max_similarity = similarity similar_image_path = file_path return similar_image_path ``` 4. 调用`find_similar_image`函数并传入目标图片和文件夹路径来查相似图片: ```python target_image_path = 'path/to/target_image.jpg' folder_path = 'path/to/images_folder' similar_image_path = find_similar_image(target_image_path, folder_path) print('The most similar image is:', similar_image_path) ``` 请确保将`target_image_path`和`folder_path`替换为实际的目标图片路径和文件夹路径。 这个实现方法使用了OpenCV库来读取和处理图像,并使用了scikit-image库的SSIM函数来计算相似度。你可以根据需要进行调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值