如何解决在 Python 中比 MSE 更好地比较图像的快速技术
我一直在使用结构相似性指数(通过 tensorflow)来比较图像,但是它花费的时间太长。我想知道是否有一种不需要太多时间的替代技术。如果有人能指出比 Python 中的 tensorflow 更有效的 SSIM 实现也没关系。
我使用 SSIM 的意图是,给定一个参考图像 (A) 和一组 图像 (B),我需要了解 B 中的哪个图像与参考图像最相似A.
解决方法
更新 01-02-2021
我决定探索一些可用于图像比较的其他 Python 模块。我还想使用 concurrent.futures,我以前没有使用过。
我使用自己编写的代码创建了两个 GitGub Gist。
ImageHash aHash image comparison
ImageHash 模块能够在 0.29 秒内比较 100 张图像,而 skimage 模块在同一任务中花费 1.2 秒。
原帖
我没有测试这个答案中代码的速度,因为我只在我发布到 GitHub 的一些图像测试中使用了代码:
下面的代码将生成参考图像 (A) 和图像集 (B) 之间的相似度得分。
完整代码位于in my GitHub repository
import os
from os import walk
import numpy as np
from PIL import Image
from math import *
def get_image_files(directory_of_images):
"""
This function is designed to traverse a directory tree and extract all
the image names contained in the directory.
:param directory_of_images: the name of the target directory containing
the images to be trained on.
:return: list of images to be processed.
"""
images_to_process = []
for (dirpath,dirnames,filenames) in walk(directory_of_images):
for filename in filenames:
accepted_extensions = ('.bmp','.gif','.jpg','.jpeg','.png','.svg','.tiff')
if filename.endswith(accepted_extensions):
images_to_process.append(os.path.join(dirpath,filename))
return images_to_process
def pre_process_images(image_one,image_two,additional_resize=False,max_image_size=1000):
"""
This function is designed to resize the images using the Pillow module.
:param image_one: primary image to evaluate against a secondary image
:param image_two: secondary image to evaluate against the primary image
:param additional_resize:
:param max_image_size: maximum allowable image size in pixels
:return: resized images
"""
lower_boundary_size = (min(image_one.size[0],image_two.size[0]),min(image_one.size[1],image_two.size[1]))
# reference: https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.resize
# reference: https://pillow.readthedocs.io/en/stable/handbook/concepts.html#PIL.Image.LANCZOS
image_one = image_one.resize(lower_boundary_size,resample=Image.LANCZOS)
image_two = image_two.resize(lower_boundary_size,resample=Image.LANCZOS)
if max(image_one.size) > max_image_size and additional_resize:
resize_factor = max_image_size / max(image_one.size)
image_one = image_one.resize((int(lower_boundary_size[0] * resize_factor),int(lower_boundary_size[1] * resize_factor)),resample=Image.LANCZOS)
image_two = image_two.resize((int(lower_boundary_size[0] * resize_factor),resample=Image.LANCZOS)
return image_one,image_two
def get_ssim_similarity(image_one_name,image_two_name,window_size=7,dynamic_range=255):
"""
The Structural Similarity Index (SSIM) is a method for measuring the similarity between two images.
The SSIM index can be viewed as a quality measure of one of the images being compared,provided the
other image is regarded as of perfect quality.
:param image_one_name: primary image to evaluate against a secondary image
:param image_two_name: secondary image to evaluate against the primary image
:param window_size: The side-length of the sliding window used in comparison. Must be an odd value.
:param dynamic_range: Dynamic range of the input image,specified as a positive scalar.
The default dynamic range is 255 for images of data type uint8.
:return: computational score and image names
"""
image_one = Image.open(image_one_name)
image_two = Image.open(image_two_name)
if min(list(image_one.size) + list(image_two.size)) < 7:
raise Exception("One of the images was too small to process using the SSIM approach")
image_one,image_two = pre_process_images(image_one,True)
image_one,image_two = image_one.convert('I'),image_two.convert('I')
c1 = (dynamic_range * 0.01) ** 2
c2 = (dynamic_range * 0.03) ** 2
pixel_length = window_size ** 2
ssim = 0.0
adjusted_width = image_one.size[0] // window_size * window_size
adjusted_height = image_one.size[1] // window_size * window_size
for i in range(0,adjusted_width,window_size):
for j in range(0,adjusted_height,window_size):
crop_box = (i,j,i + window_size,j + window_size)
crop_box_one = image_one.crop(crop_box)
crop_box_two = image_two.crop(crop_box)
np_array_one,np_array_two = np.array(crop_box_one).flatten(),np.array(crop_box_two).flatten()
np_variable_one,np_variable_two = np.var(np_array_one),np.var(np_array_two)
np_average_one,np_average_two = np.average(np_array_one),np.average(np_array_two)
cov = (np.sum(np_array_one * np_array_two) - (np.sum(np_array_one) *
np.sum(crop_box_two) / pixel_length)) / pixel_length
ssim += ((2.0 * np_average_one * np_average_two + c1) * (2.0 * cov + c2)) / \
((np_average_one ** 2 + np_average_two ** 2 + c1) * (np_variable_one + np_variable_two + c2))
similarity_percent = (ssim * pixel_length / (adjusted_height * adjusted_width)) * 100
return round(similarity_percent,2)
target_image = 'a.jpg'
image_directory = 'b_images'
images = get_image_files(image_directory)
for image in images:
ssim_result = get_ssim_similarity(target_image,image)
我还建议查看 Python 模块 ImageHash。我有多个代码示例和测试用例 published here。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。