如何获取两张图片之间的SSIM比较分数?

7
我正在尝试计算对应图像之间的SSIM。例如,地面真实目录中名为106.tif的图像对应于假生成图像目录中的106.jpg。 地面真实目录的绝对路径为/home/pr/pm/zh_pix2pix/datasets/mousebrain/test/B, 假生成图像目录的绝对路径是/home/pr/pm/zh_pix2pix/output/fake_B
这些图像相互对应,如下图所示: 请查看图片 我希望在一对一的基础上比较成千上万个这些图像。我不想将一个图像与多个其他图像进行比较。对应的真实和假图像具有相同的文件名,但扩展名不同(即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只能一次处理一张图片,但我希望通过在真实目录和虚假目录之间循环比较它们。欢迎提供建议。

1个回答

15
以下是一个工作示例,可以比较一张图像与另一张图像。您可以扩展它以同时比较多个图像。这里有两个具有轻微差异的测试输入图像: enter image description here enter image description here 结果 突出显示差异: enter image description here enter image description here 相似度分数:

Image similarity 0.9639027981846681

差异掩模: enter image description here enter image description here enter image description here 代码:
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)

这个很好用!SSIM是我所需要的,但其他部分也非常有用。改成了for循环并且适用于我有的多张图片。 - prernaroy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接