You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 11:40:03