Python图像对比对白色背景图像相似度计算结果偏低问题求助
图像对比相似度偏低问题
我用Python代码做图像对比,发现无白色背景的图像对比效果正常,但内容相同、仅白色背景存在差异的图像,计算出的相似度仅约50%,结果明显偏低。
原始图与对比图说明:
- 原始图:产品主体内容清晰,白色背景区域规整
- 对比图:产品主体与原始图完全一致,但白色背景的范围、排布存在差异
完整代码如下:
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)
内容的提问来源于stack exchange,提问作者Vaidas
相关产品推荐
相关产品推荐

