如何得到两张图片的SSIM比对分数?

How to get the SSIM comparison score between two images?

我正在尝试计算相应图像之间的 SSIM。例如,ground truth 目录中名为 106.tif 的图像对应于 fake 目录中的 'fake' 生成图像 106.jpg。

真实目录绝对路径是/home/pr/pm/zh_pix2pix/datasets/mousebrain/test/B 假目录绝对路径是/home/pr/pm/zh_pix2pix/output/fake_B

里面的图片一一对应,像这样: see image

我想一对一比较这些图像中的数千张。我不想将一个图像的 SSIM 与许多其他图像进行比较。相应的真实图像和假图像具有相同的文件名,但扩展名不同(即 106.tif 和 106.jpg),我只想将它们相互比较。

我正在努力以这种方式编辑用于 SSIM 比较的可用脚本。我想使用这个:https://github.com/mostafaGwely/Structural-Similarity-Index-SSIM-/blob/master/ssim.py 但欢迎其他建议。代码也如下所示:

# Usage:
#
# python3 script.py --input original.png --output modified.png
# Based on: https://github.com/mostafaGwely/Structural-Similarity-Index-SSIM-

# 1. Import the necessary packages
#from skimage.measure import compare_ssim
from skimage.metrics import structural_similarity as ssim
import argparse
import imutils
import cv2

# 2. Construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-f", "--first", required=True, help="Directory of the image that will be compared")
ap.add_argument("-s", "--second", required=True, help="Directory of the image that will be used to compare")
args = vars(ap.parse_args())

# 3. Load the two input images
imageA = cv2.imread(args["first"])
imageB = cv2.imread(args["second"])

# 4. Convert the images to grayscale
grayA = cv2.cvtColor(imageA, cv2.COLOR_BGR2GRAY)
grayB = cv2.cvtColor(imageB, cv2.COLOR_BGR2GRAY)

# 5. Compute the Structural Similarity Index (SSIM) between the two
#    images, ensuring that the difference image is returned
#(score, diff) = compare_ssim(grayA, grayB, full=True)
(score, diff) = ssim(grayA, grayB, full=True)
diff = (diff * 255).astype("uint8")

# 6. You can print only the score if you want
print("SSIM: {}".format(score))

argparse 的使用目前限制我一次只能使用一张图像,但理想情况下,我希望使用遍历真实目录和假目录的循环来比较它们。如有任何建议,我们将不胜感激。

这是一个将一张图片与另一张图片进行比较的工作示例。您可以展开它以一次比较多个。两张测试输入图像略有不同:

结果

突出差异

相似度得分

Image similarity 0.9639027981846681

差异掩码

代码

from skimage.metrics import structural_similarity
import cv2
import numpy as np

before = cv2.imread('5.jpg')
after = cv2.imread('6.jpg')

# Convert images to grayscale
before_gray = cv2.cvtColor(before, cv2.COLOR_BGR2GRAY)
after_gray = cv2.cvtColor(after, cv2.COLOR_BGR2GRAY)

# Compute SSIM between two images
(score, diff) = structural_similarity(before_gray, after_gray, full=True)
print("Image similarity", score)

# The diff image contains the actual image differences between the two images
# and is represented as a floating point data type in the range [0,1] 
# so we must convert the array to 8-bit unsigned integers in the range
# [0,255] before we can use it with OpenCV
diff = (diff * 255).astype("uint8")

# Threshold the difference image, followed by finding contours to
# obtain the regions of the two input images that differ
thresh = cv2.threshold(diff, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
contours = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]

mask = np.zeros(before.shape, dtype='uint8')
filled_after = after.copy()

for c in contours:
    area = cv2.contourArea(c)
    if area > 40:
        x,y,w,h = cv2.boundingRect(c)
        cv2.rectangle(before, (x, y), (x + w, y + h), (36,255,12), 2)
        cv2.rectangle(after, (x, y), (x + w, y + h), (36,255,12), 2)
        cv2.drawContours(mask, [c], 0, (0,255,0), -1)
        cv2.drawContours(filled_after, [c], 0, (0,255,0), -1)

cv2.imshow('before', before)
cv2.imshow('after', after)
cv2.imshow('diff',diff)
cv2.imshow('mask',mask)
cv2.imshow('filled after',filled_after)
cv2.waitKey(0)