Python image comparison improved percentage results

110 Views Asked by At

Running a python code to compare two images. It seems to compare most images well, that do not have white background but gets low results for equal images where white is not the same. Attaching the full code. original comparison I get a similarty of 50% or so which seems low since the images are identical.

import requests
import pandas as pd
import string
import time
import traceback
import os
import sys
import re
import os
import urllib.request
import io
import base64
import datetime
from lxml.html import fromstring
from functools import reduce
from itertools import cycle
from requests.exceptions import ConnectTimeout,ProxyError,ReadTimeout, ConnectionError
from bs4 import BeautifulSoup
from random import shuffle
from PIL import Image
from scipy.signal import gaussian
import numpy
from scipy.signal import fftconvolve
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from PIL import Image, ImageChops
import cv2
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.chrome.options import Options
from selenium import webdriver

file = r'Z:\Shared\Boto Egnyte\03 Resources\TOOLS\00 DESIGN rename\00 LIBRARY\TMP\orig.jpg'
a_to_z = string.ascii_uppercase
big_num = 0

def ssim(im1, im2, window, k=(0.01, 0.03), l=255):
    """See https://ece.uwaterloo.ca/~z70wang/research/ssim/"""
    # Check if the window is smaller than the images.
    for a, b in zip(window.shape, im1.shape):
        if a > b:
            return None, None
    # Values in k must be positive according to the base implementation.
    for ki in k:
        if ki < 0:
            return None, None

    c1 = (k[0] * l) ** 2
    c2 = (k[1] * l) ** 2
    window = window/numpy.sum(window)

    mu1 = fftconvolve(im1, window, mode='valid')
    mu2 = fftconvolve(im2, window, mode='valid')
    mu1_sq = mu1 * mu1
    mu2_sq = mu2 * mu2
    mu1_mu2 = mu1 * mu2
    sigma1_sq = fftconvolve(im1 * im1, window, mode='valid') - mu1_sq
    sigma2_sq = fftconvolve(im2 * im2, window, mode='valid') - mu2_sq
    sigma12 = fftconvolve(im1 * im2, window, mode='valid') - mu1_mu2

    if c1 > 0 and c2 > 0:
        num = (2 * mu1_mu2 + c1) * (2 * sigma12 + c2)
        den = (mu1_sq + mu2_sq + c1) * (sigma1_sq + sigma2_sq + c2)
        ssim_map = num / den
    else:
        num1 = 2 * mu1_mu2 + c1
        num2 = 2 * sigma12 + c2
        den1 = mu1_sq + mu2_sq + c1
        den2 = sigma1_sq + sigma2_sq + c2
        ssim_map = numpy.ones(numpy.shape(mu1))
        index = (den1 * den2) > 0
        ssim_map[index] = (num1[index] * num2[index]) / (den1[index] * den2[index])
        index = (den1 != 0) & (den2 == 0)
        ssim_map[index] = num1[index] / den1[index]

    mssim = ssim_map.mean()
    return mssim, ssim_map



def save_image_as_base64(browser, url):
    """

    """
    base = browser.execute_async_script("""
    var done = arguments[0];
    function toDataURL(url, callback) {
      var xhr = new XMLHttpRequest();
      xhr.onload = function() {
        var reader = new FileReader();
        reader.onloadend = function() {
          callback(reader.result);
        }
        reader.readAsDataURL(xhr.response);
      };
      xhr.open('GET', url);
      xhr.responseType = 'blob';
      xhr.send();
    }
    setTimeout(function(){
      done("notplayed");
    }, 12000);
    toDataURL('%s', done)""" % url)
    base = base.split(',')[-1]
    return base

def img_chk(img1, img2, big_num):
     # Create a 2d gaussian for the window parameter
    win = numpy.array([gaussian(11, 1.5)])
    win2d = win * (win.T)

    num_metrics = 2

    for band1, band2 in zip(img1.split(), img2.split()):
        b1 = numpy.asarray(band1, dtype=numpy.double)
        b2 = numpy.asarray(band2, dtype=numpy.double)
        # SSIM
        res, smap = ssim(b1, b2, win2d)
    print ("Result:", file, round(res,4))
    match_change = False
    if big_num == 0:
        big_num = round(res,4)
        row['Match'] = round(res,4)
        match_change = True
    if big_num < round(res,4):
        row['Match'] = round(res,4)
        big_num = round(res,4)
        match_change = True
    return match_change, big_num


def download_with_selenium(url):
    print('getting ',url)
    browser.get(url)
    time.sleep(1)
    html, title = browser.page_source, browser.title
    #open(urlparse(url).path[4:]+'.htmk','w',encoding='utf-8').write(html)
    return html, title

def expand2square(pil_img, background_color):
    width, height = pil_img.size
    if width == height:
        return pil_img
    elif width > height:
        result = Image.new(pil_img.mode, (width, width), background_color)
        result.paste(pil_img, (0, (width - height) // 2))
        return result
    else:
        result = Image.new(pil_img.mode, (height, height), background_color)
        result.paste(pil_img, ((height - width) // 2, 0))
        return result


chrome_options = Options()
chrome_options.headless = False
browser = webdriver.Chrome(
    service=Service(ChromeDriverManager().install()), options=chrome_options)
df = pd.DataFrame()

row = {}
ok_img = "https://m.media-amazon.com/images/I/51qVJ6oJ7sL._AC_.jpg"
big_num = 0

base = save_image_as_base64(browser, ok_img)
image_file = io.BytesIO(base64.b64decode(base))
img = Image.open(image_file)
wi, hi = img.size
if wi != hi:
    img = expand2square(img,(255,255,255))

orig = Image.open(file)
wi, hi = orig.size
if wi != hi:
    orig = expand2square(orig,(255,255,255))
if img.size != orig.size:
    orig = orig.resize(img.size, Image.ANTIALIAS)
match_change,big_num = img_chk(img, orig, big_num)
print(big_num)
0

There are 0 best solutions below