OpenCV - Fastest method to check if two images are

2020-06-22 01:56发布

There are many questions over here which checks if two images are "nearly" similar or not.

My task is simple. With OpenCV, I want to find out if two images are 100% identical or not.

They will be of same size but can be saved with different filenames.

5条回答
贼婆χ
2楼-- · 2020-06-22 02:21

Importing the packages we’ll need — matplotlib for plotting, NumPy for numerical processing, and cv2 for our OpenCV bindings. Structural Similarity Index method is already implemented for us by scikit-image, so we’ll just use their implementation

# import the necessary packages
from skimage.measure import structural_similarity as ssim
import matplotlib.pyplot as plt
import numpy as np
import cv2

Then define the compare_images function which we’ll use to compare two images using both MSE and SSIM. The mse function takes three arguments: imageA and imageB, which are the two images we are going to compare, and then the title of our figure.

We then compute the MSE and SSIM between the two images. We also simply display the MSE and SSIM associated with the two images we are comparing.

def mse(imageA, imageB):
    # the 'Mean Squared Error' between the two images is the
    # sum of the squared difference between the two images;
    # NOTE: the two images must have the same dimension
    err = np.sum((imageA.astype("float") - imageB.astype("float")) ** 2)
    err /= float(imageA.shape[0] * imageA.shape[1])

    # return the MSE, the lower the error, the more "similar"
    # the two images are
    return err
def compare_images(imageA, imageB, title):
    # compute the mean squared error and structural similarity
    # index for the images
    m = mse(imageA, imageB)
    s = ssim(imageA, imageB)
    # setup the figure
    fig = plt.figure(title)
    plt.suptitle("MSE: %.2f, SSIM: %.2f" % (m, s))
    # show first image
    ax = fig.add_subplot(1, 2, 1)
    plt.imshow(imageA, cmap = plt.cm.gray)
    plt.axis("off")
    # show the second image
    ax = fig.add_subplot(1, 2, 2)
    plt.imshow(imageB, cmap = plt.cm.gray)
    plt.axis("off")
    # show the images
    plt.show()

Load images off disk using OpenCV. We’ll be using original image, contrast adjusted image, and our Photoshopped image

We then convert our images to grayscale

# load the images -- the original, the original + contrast,
# and the original + photoshop
original = cv2.imread("images/jp_gates_original.png")
contrast = cv2.imread("images/jp_gates_contrast.png")
shopped = cv2.imread("images/jp_gates_photoshopped.png")
# convert the images to grayscale
original = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY)
contrast = cv2.cvtColor(contrast, cv2.COLOR_BGR2GRAY)
shopped = cv2.cvtColor(shopped, cv2.COLOR_BGR2GRAY)

We will generate a matplotlib figure, loop over our images one-by-one, and add them to our plot. Our plot is then displayed to us.

Finally, we can compare our images together using the compare_images function.

# initialize the figure
fig = plt.figure("Images")
images = ("Original", original), ("Contrast", contrast), ("Photoshopped", shopped)
# loop over the images
for (i, (name, image)) in enumerate(images):
    # show the image
    ax = fig.add_subplot(1, 3, i + 1)
    ax.set_title(name)
    plt.imshow(image, cmap = plt.cm.gray)
    plt.axis("off")
# show the figure
plt.show()
# compare the images
compare_images(original, original, "Original vs. Original")
compare_images(original, contrast, "Original vs. Contrast")
compare_images(original, shopped, "Original vs. Photoshopped")

Reference- https://www.pyimagesearch.com/2014/09/15/python-compare-two-images/

查看更多
Emotional °昔
3楼-- · 2020-06-22 02:24

the sum of the differences should be 0 (for all channels):

bool equal(const Mat & a, const Mat & b)
{
    if ( (a.rows != b.rows) || (a.cols != b.cols) )
        return false;
    Scalar s = sum( a - b );
    return (s[0]==0) && (s[1]==0) && (s[2]==0);
}
查看更多
我命由我不由天
4楼-- · 2020-06-22 02:25

You can use a logical operator like xor operator. If you are using python you can use the following one-line function:

Python

def is_similar(image1, image2):
    return image1.shape == image2.shape and not(np.bitwise_xor(image1,image2).any())

where shape is the property that shows the size of matrix and bitwise_xor is as the name suggests. The C++ version can be made in a similar way!

C++

Please see @berak code.


Notice: The Python code works for any depth images(1-D, 2-D, 3-D , ..), but the C++ version works just for 2-D images. It's easy to convert it to any depth images by yourself. I hope that gives you the insight! :)

Doc: bitwise_xor

EDIT: C++ was removed. Thanks to @Micka and @ berak for their comments.

查看更多
家丑人穷心不美
5楼-- · 2020-06-22 02:26
import cv2
import numpy as np
a = cv2.imread("picture1.png")
b = cv2.imread("picture2.png")
difference = cv2.subtract(a, b)    
result = not np.any(difference)
if result is True:
    print("Pictures are the same")
else:
    print("Pictures are different")
查看更多
啃猪蹄的小仙女
6楼-- · 2020-06-22 02:29

If they are same files except being saved in different file-names, you can check whether their Checksums are identical or not.

查看更多
登录 后发表回答