Como quantificar a diferença entre duas imagens?


179

Aqui está o que eu gostaria de fazer:

Estou tirando fotos com uma webcam em intervalos regulares. Mais ou menos como um lapso de tempo. No entanto, se nada realmente mudou, ou seja, a imagem parece a mesma, não quero armazenar o instantâneo mais recente.

Imagino que exista alguma maneira de quantificar a diferença, e eu teria que determinar empiricamente um limite.

Estou procurando mais simplicidade do que perfeição. Eu estou usando python.


Respostas:


269

Ideia geral

Opção 1: carregue as duas imagens como matrizes ( scipy.misc.imread) e calcule uma diferença entre elementos (pixel por pixel). Calcule a norma da diferença.

Opção 2: Carregue as duas imagens. Calcule algum vetor de recurso para cada um deles (como um histograma). Calcule a distância entre vetores de recursos em vez de imagens.

No entanto, existem algumas decisões a serem tomadas primeiro.

Questões

Você deve responder a estas perguntas primeiro:

  • As imagens têm a mesma forma e dimensão?

    Caso contrário, pode ser necessário redimensioná-las ou cortá-las. A biblioteca PIL ajudará a fazê-lo em Python.

    Se forem tiradas com as mesmas configurações e o mesmo dispositivo, provavelmente são as mesmas.

  • As imagens estão bem alinhadas?

    Caso contrário, convém executar a correlação cruzada primeiro, para encontrar o melhor alinhamento primeiro. O SciPy tem funções para fazer isso.

    Se a câmera e a cena estiverem paradas, é provável que as imagens estejam bem alinhadas.

  • A exposição das imagens é sempre a mesma? (A luminosidade / contraste é o mesmo?)

    Caso contrário, você pode normalizar as imagens.

    Mas tenha cuidado, em algumas situações isso pode fazer mais mal do que bem. Por exemplo, um único pixel brilhante em um fundo escuro tornará a imagem normalizada muito diferente.

  • As informações de cores são importantes?

    Se você quiser observar alterações de cores, terá um vetor de valores de cores por ponto, em vez de um valor escalar, como na imagem em escala de cinza. Você precisa de mais atenção ao escrever esse código.

  • Existem arestas distintas na imagem? É provável que eles se mexam?

    Se sim, você pode aplicar o algoritmo de detecção de borda primeiro (por exemplo, calcular gradiente com as transformações Sobel ou Prewitt, aplicar algum limite) e comparar as arestas na primeira imagem com as arestas na segunda.

  • Há ruído na imagem?

    Todos os sensores poluem a imagem com uma certa quantidade de ruído. Sensores de baixo custo têm mais ruído. Você pode aplicar alguma redução de ruído antes de comparar imagens. O desfoque é a abordagem mais simples (mas não a melhor) aqui.

  • Que tipo de mudanças você deseja observar?

    Isso pode afetar a escolha da norma a ser usada para a diferença entre imagens.

    Considere usar a norma Manhattan (a soma dos valores absolutos) ou a norma zero (o número de elementos que não é igual a zero) para medir quanto a imagem mudou. O primeiro dirá o quanto a imagem está desativada, o segundo dirá apenas quantos pixels diferem.

Exemplo

Presumo que suas imagens estejam bem alinhadas, com o mesmo tamanho e formato, possivelmente com exposição diferente. Para simplificar, eu os converto em escala de cinza, mesmo que sejam imagens coloridas (RGB).

Você precisará destas importações:

import sys

from scipy.misc import imread
from scipy.linalg import norm
from scipy import sum, average

Função principal, leia duas imagens, converta em escala de cinza, compare e imprima resultados:

def main():
    file1, file2 = sys.argv[1:1+2]
    # read images as 2D arrays (convert to grayscale for simplicity)
    img1 = to_grayscale(imread(file1).astype(float))
    img2 = to_grayscale(imread(file2).astype(float))
    # compare
    n_m, n_0 = compare_images(img1, img2)
    print "Manhattan norm:", n_m, "/ per pixel:", n_m/img1.size
    print "Zero norm:", n_0, "/ per pixel:", n_0*1.0/img1.size

Como comparar img1e img2são matrizes 2D SciPy aqui:

def compare_images(img1, img2):
    # normalize to compensate for exposure difference, this may be unnecessary
    # consider disabling it
    img1 = normalize(img1)
    img2 = normalize(img2)
    # calculate the difference and its norms
    diff = img1 - img2  # elementwise for scipy arrays
    m_norm = sum(abs(diff))  # Manhattan norm
    z_norm = norm(diff.ravel(), 0)  # Zero norm
    return (m_norm, z_norm)

Se o arquivo for uma imagem colorida, imreadretornará uma matriz 3D, canais RGB médios (o último eixo da matriz) para obter intensidade. Não é necessário fazer isso para imagens em escala de cinza (por exemplo .pgm):

def to_grayscale(arr):
    "If arr is a color image (3D array), convert it to grayscale (2D array)."
    if len(arr.shape) == 3:
        return average(arr, -1)  # average over the last axis (color channels)
    else:
        return arr

A normalização é trivial, você pode optar por normalizar para [0,1] em vez de [0,255]. arré uma matriz SciPy aqui, portanto, todas as operações são baseadas em elementos:

def normalize(arr):
    rng = arr.max()-arr.min()
    amin = arr.min()
    return (arr-amin)*255/rng

Execute a mainfunção:

if __name__ == "__main__":
    main()

Agora você pode colocar tudo isso em um script e executar duas imagens. Se compararmos a imagem consigo mesma, não há diferença:

$ python compare.py one.jpg one.jpg
Manhattan norm: 0.0 / per pixel: 0.0
Zero norm: 0 / per pixel: 0.0

Se borrarmos a imagem e comparamos com o original, há alguma diferença:

$ python compare.py one.jpg one-blurred.jpg 
Manhattan norm: 92605183.67 / per pixel: 13.4210411116
Zero norm: 6900000 / per pixel: 1.0

PS Script compare.py inteiro .

Atualização: técnicas relevantes

Como a pergunta é sobre uma sequência de vídeo, em que os quadros provavelmente são quase os mesmos, e você procura algo incomum, gostaria de mencionar algumas abordagens alternativas que podem ser relevantes:

  • subtração e segmentação em segundo plano (para detectar objetos em primeiro plano)
  • fluxo óptico escasso (para detectar movimento)
  • comparando histogramas ou outras estatísticas em vez de imagens

Eu recomendo dar uma olhada no livro “Learning OpenCV”, capítulos 9 (partes e segmentação de imagens) e 10 (rastreamento e movimento). O primeiro ensina a usar o método de subtração Background, o último fornece algumas informações sobre os métodos de fluxo óptico. Todos os métodos são implementados na biblioteca OpenCV. Se você usa Python, sugiro usar o OpenCV ≥ 2.3 e seu cv2módulo Python.

A versão mais simples da subtração em segundo plano:

  • aprenda o valor médio μ e o desvio padrão σ para cada pixel do plano de fundo
  • compare os valores atuais de pixel com o intervalo de (μ-2σ, μ + 2σ) ou (μ-σ, μ + σ)

Versões mais avançadas levam em consideração séries temporais para cada pixel e lidam com cenas não estáticas (como mover árvores ou grama).

A idéia do fluxo óptico é pegar dois ou mais quadros e atribuir o vetor de velocidade a cada pixel (fluxo óptico denso) ou a alguns deles (fluxo óptico esparso). Para estimar o fluxo óptico esparso, você pode usar o método Lucas-Kanade (também é implementado no OpenCV). Obviamente, se houver muito fluxo (média alta acima dos valores máximos do campo de velocidade), algo estará se movendo no quadro e as imagens subseqüentes serão mais diferentes.

Comparar histogramas pode ajudar a detectar mudanças repentinas entre quadros consecutivos. Essa abordagem foi usada em Courbon et al, 2010 :

Semelhança de quadros consecutivos. A distância entre dois quadros consecutivos é medida. Se estiver muito alto, significa que o segundo quadro está corrompido e, portanto, a imagem é eliminada. A distância Kullback-Leibler , ou entropia mútua, nos histogramas dos dois quadros:

$$ d (p, q) = \ sum_i p (i) \ log (p (i) / q (i)) $$

em que p e q são os histogramas dos quadros é usado. O limite é fixo em 0,2.


Eu recebo um RuntimeWarning: invalid value encountered in double_scalarsna linha 44 ( return (arr-amin)*255/rng) e um ValueError: array must not contain infs or NaNsna linha 30 ( z_norm = norm(diff.ravel(), 0))
BioGeek

@BioGeek, ou seja, rngigual a zero. Basta adicionar um cheque e setrng = 1
haisi

76

Uma solução simples:

Codifique a imagem como um JPEG e procure uma alteração substancial no tamanho do arquivo .

Eu implementei algo semelhante nas miniaturas de vídeo e tive muito sucesso e escalabilidade.


3
Essa é uma solução muito fácil e simples e é muito melhor do que qualquer comparação em termos de pixel. Se houver um pouco de ruído na imagem da sua webcam ou se a imagem for alterada em até um pixel, uma comparação direta captará todas essas alterações sem sentido. Uma abordagem mais robusta seria calcular a transformação discreta de cosseno e depois comparar as imagens no domínio da frequência. O uso da compactação JPEG dessa maneira oferece a maioria dos benefícios sem se aprofundar na teoria de Fourier.
AndrewF

Gosto disso. Embora outras soluções funcionem também, isso tem uma grande vantagem para uma situação comum: e se você não quiser salvar a imagem "base"? salve o tamanho do arquivo como um hash e compare apenas os números com a subtração. No meu caso, tenho 4 imagens, uma delas é muito semelhante e as outras 3 são absolutamente diferentes. Apenas dimensione para as mesmas dimensões, para jpg e subtrair. Muito bom.
Diego Andrés Díaz Espinoza

60

Você pode comparar duas imagens usando as funções do PIL .

import Image
import ImageChops

im1 = Image.open("splash.png")
im2 = Image.open("splash2.png")

diff = ImageChops.difference(im2, im1)

O objeto diff é uma imagem na qual cada pixel é o resultado da subtração dos valores de cores desse pixel na segunda imagem da primeira imagem. Usando a imagem diff, você pode fazer várias coisas. O mais simples é a diff.getbbox()função. Ele mostrará o retângulo mínimo que contém todas as alterações entre as duas imagens.

Provavelmente você pode implementar aproximações dos outros itens mencionados aqui usando funções do PIL também.


2
Quero salvar a imagem da diferença. significa o objeto diff que mantém a diferença de imagens. Como eu salvo?
Sagar

2
@ Anthony você pode chamar save () no objeto diff especificando o nome da imagem. assim: diff.save ("diff.png") salvará a imagem da diferença para você.
Sagar

20

Dois métodos populares e relativamente simples são: (a) a distância euclidiana já sugerida, ou (b) correlação cruzada normalizada. A correlação cruzada normalizada tende a ser visivelmente mais robusta às mudanças de iluminação do que a simples correlação cruzada. A Wikipedia fornece uma fórmula para a correlação cruzada normalizada . Existem métodos mais sofisticados também, mas exigem um pouco mais de trabalho.

Usando sintaxe parecida com numpy,

dist_euclidean = sqrt (soma ((i1 - i2) ^ 2)) / i1.size

dist_manhattan = soma (abs (i1 - i2)) / i1.size

dist_ncc = soma ((i1 - média (i1)) * (i2 - média (i2))) / (
  (i1.size - 1) * stdev (i1) * stdev (i2))

assumindo que i1e i2são matrizes de imagem em escala de cinza 2D.


3
As funções de correlação cruzada de imagem são incorporadas ao SciPy ( docs.scipy.org/doc/scipy/reference/generated/… ), e uma versão rápida usando a FFT está disponível no stsci python ( stsci.edu/resources/software_hardware/pyraf/ stsci_python )
endolith

14

Uma coisa trivial para tentar:

Realize uma nova amostra de ambas as imagens em miniaturas pequenas (por exemplo, 64 x 64) e compare as miniaturas pixel por pixel com um determinado limite. Se as imagens originais forem quase as mesmas, as miniaturas reamostradas serão muito parecidas ou até exatamente iguais. Este método cuida do ruído que pode ocorrer principalmente em cenas com pouca luz. Pode até ser melhor se você usar a escala de cinza.


mas como você compararia os pixels?
transportadora

Depois de ter as miniaturas, você pode simplesmente comparar os pixels um por um. Você calcularia a "distância" dos valores RGB, se estiver trabalhando em cores ou apenas a diferença entre os tons de cinza, se estiver em escala de cinza.
Ates Goral 15/10/08

1
"compara os pixels um por um". O que isso significa? O teste deve falhar se UM dos testes de 64 ^ 2 pixels por pixel falhar?
Federico A. Ramponi 15/10/08

O que eu quis dizer com "comparar as miniaturas pixel por pixel com um certo limite" é criar um algoritmo difuso para comparar os pixels. Se a diferença calculada (depende do seu algoritmo difuso) exceder um determinado limite, as imagens "não são as mesmas".
Ates Goral 15/10/08

1
Exemplo muito simples, sem o "algoritmo difusa": circuito paralelo através de cada pixel (comparar pixels # n da imagem # 1 a # pixel de n da imagem # 2), e adicionar a diferença de valor a uma variável
MK12

7

Estou abordando especificamente a questão de como calcular se elas são "suficientemente diferentes". Eu suponho que você possa descobrir como subtrair os pixels um por um.

Primeiro, eu pegava um monte de imagens sem mudar nada e descobria a quantidade máxima que qualquer pixel muda apenas por causa de variações na captura, ruído no sistema de imagem, artefatos de compactação JPEG e alterações momento a momento na iluminação . Talvez você descubra que diferenças de 1 ou 2 bits são esperadas mesmo quando nada se move.

Então, para o teste "real", você deseja um critério como este:

  • o mesmo se até P pixels diferirem em não mais que E.

Então, talvez, se E = 0,02, P = 1000, isso significaria (aproximadamente) que seria "diferente" se algum pixel único mudasse em mais de ~ 5 unidades (assumindo imagens de 8 bits) ou se mais de 1000 pixels tiveram algum erro.

Isso se destina principalmente a ser uma boa técnica de "triagem" para identificar rapidamente imagens próximas o suficiente para não precisar de mais exames. As imagens que "falham" podem então se tornar uma técnica mais elaborada / cara que não teria falsos positivos se a câmera tremesse um pouco, por exemplo, ou fosse mais robusta às mudanças de iluminação.

Eu corro um projeto de código aberto, o OpenImageIO , que contém um utilitário chamado "idiff" que compara diferenças com limites como este (ainda mais elaborado, na verdade). Mesmo se você não quiser usar este software, consulte a fonte para ver como fizemos. É usada comercialmente um pouco e essa técnica de limiar foi desenvolvida para que pudéssemos ter um conjunto de testes para renderização e processamento de imagens, com "imagens de referência" que podem ter pequenas diferenças de plataforma para plataforma ou quando fizemos pequenos ajustes para algoritmos, então queríamos uma operação de "correspondência dentro da tolerância".


6

Eu tive um problema semelhante no trabalho, estava reescrevendo nosso ponto de extremidade de transformação de imagem e queria verificar se a nova versão estava produzindo a mesma ou quase a mesma saída da versão antiga. Então eu escrevi isso:

https://github.com/nicolashahn/diffimg

Que opera em imagens do mesmo tamanho e, no nível por pixel, mede a diferença de valores em cada canal: R, G, B (, A), pega a diferença média desses canais e calcula a média da diferença entre todos os pixels e retorna uma proporção.

Por exemplo, com uma imagem 10x10 de pixels brancos e a mesma imagem, mas um pixel mudou para vermelho, a diferença nesse pixel é 1/3 ou 0,33 ... (RGB 0,0,0 vs 255,0,0 ) e em todos os outros pixels é 0. Com um total de 100 pixels, 0,33 ... / 100 = uma diferença de ~ 0,33% na imagem.

Acredito que isso funcionaria perfeitamente para o projeto do OP (percebo que este é um post muito antigo agora, mas publicando para futuros StackOverflowers que também desejam comparar imagens em python).


5

A maioria das respostas dadas não trata de níveis de iluminação.

Eu normalizaria a imagem para um nível de luz padrão antes de fazer a comparação.


Se você estiver capturando imagens periódicas e diferindo pares adjacentes, provavelmente poderá manter a primeira depois que alguém acender as luzes.
WalkyTalky

5

Outra maneira simples e agradável de medir a semelhança entre duas imagens:

import sys
from skimage.measure import compare_ssim
from skimage.transform import resize
from scipy.ndimage import imread

# get two images - resize both to 1024 x 1024
img_a = resize(imread(sys.argv[1]), (2**10, 2**10))
img_b = resize(imread(sys.argv[2]), (2**10, 2**10))

# score: {-1:1} measure of the structural similarity between the images
score, diff = compare_ssim(img_a, img_b, full=True)
print(score)

Se outras pessoas estiverem interessadas em uma maneira mais poderosa de comparar a similaridade de imagens, montei um tutorial e um aplicativo da Web para medir e visualizar imagens semelhantes usando o Tensorflow.


3
Sim, skimageé muito bom de usar para esta aplicação. Eu uso from skimage.measure import compare_ssim, compare_msemuito. skimage.measure docs .
ximiki 11/11

3

Você viu o algoritmo para encontrar imagens semelhantes ? Confira para ver sugestões.

Eu sugeriria uma transformação wavelet de seus quadros (eu escrevi uma extensão C para isso usando a transformação Haar); comparando os índices dos maiores fatores de onda (proporcionalmente) entre as duas figuras, você deve obter uma aproximação de similaridade numérica.


2

Peço desculpas se é tarde demais para responder, mas desde que eu venho fazendo algo semelhante, pensei que poderia contribuir de alguma forma.

Talvez com o OpenCV você possa usar a correspondência de modelos. Supondo que você esteja usando uma webcam como você disse:

  1. Simplifique as imagens (limiar talvez?)
  2. Aplique a correspondência de modelo e verifique o max_val com minMaxLoc

Dica: max_val (ou min_val, dependendo do método usado) fornecerá números, números grandes. Para obter a diferença em porcentagem, use a correspondência de modelo com a mesma imagem - o resultado será 100%.

Pseudo código para exemplificar:

previous_screenshot = ...
current_screenshot = ...

# simplify both images somehow

# get the 100% corresponding value
res = matchTemplate(previous_screenshot, previous_screenshot, TM_CCOEFF)
_, hundred_p_val, _, _ = minMaxLoc(res)

# hundred_p_val is now the 100%

res = matchTemplate(previous_screenshot, current_screenshot, TM_CCOEFF)
_, max_val, _, _ = minMaxLoc(res)

difference_percentage = max_val / hundred_p_val

# the tolerance is now up to you

Espero que ajude.


1

A distância dos motores da Terra pode ser exatamente o que você precisa. Pode ser um pouco pesado para implementar em tempo real.


Eu realmente não sinto que esta resposta seja satisfatória: "Estou procurando mais a simplicidade do que a perfeição. Estou usando o python".
PilouPili 28/10/19

Eu acho que, como esse segmento de perguntas recebe muito tráfego e o título que atrai a maioria dos espectadores é sobre como quantificar a diferença entre duas imagens, ele tem valor aqui.
Danoram 28/10/19

1

Que tal calcular a distância de Manhattan das duas imagens. Isso fornece valores n * n. Em seguida, você poderia fazer algo como uma média de linha para reduzir para n valores e uma função sobre isso para obter um único valor.


1

Tenho tido muita sorte com imagens jpg tiradas com a mesma câmera em um tripé (1) simplificando bastante (como ir de 3000 pixels de largura a 100 pixels de largura ou menos) (2) achatando cada conjunto de jpg em um único vetor (3) correlacionar imagens sequenciais em pares com um algoritmo de correlação simples para obter o coeficiente de correlação (4) coeficiente de correlação ao quadrado para obter o quadrado r (ie fração da variabilidade em uma imagem explicada pela variação na próxima) (5) geralmente em minha aplicação se r-quadrado <0,9, digo que as duas imagens são diferentes e algo aconteceu no meio.

Isso é robusto e rápido na minha implementação (Mathematica 7)

Vale a pena brincar com a parte da imagem em que você está interessado e focar nisso cortando todas as imagens nessa pequena área, caso contrário, uma mudança distante da câmera, mas importante, será perdida.

Não sei como usar o Python, mas tenho certeza de que também faz correlações, não?


1

você pode calcular o histograma de ambas as imagens e calcular o coeficiente de Bhattacharyya , este é um algoritmo muito rápido e eu o usei para detectar alterações de tiro em um vídeo de críquete (em C usando openCV)


Você poderia calcular o coeficiente nas próprias imagens?
endolith 24/02

Você precisará calcular os histogramas para as imagens (com o tamanho da bandeja do histograma conforme os requisitos).
vishalv2050

1

Confira como o Haar Wavelets é implementado pelo isk-daemon . Você pode usar o código imgdb C ++ para calcular a diferença entre as imagens rapidamente:

O isk-daemon é um servidor de banco de dados de código aberto capaz de adicionar imagens (visuais) baseadas em conteúdo a qualquer site ou software relacionado a imagens.

Essa tecnologia permite que os usuários de qualquer site ou software relacionado à imagem desenhem em um widget qual imagem eles desejam encontrar e o site responda as imagens mais semelhantes ou simplesmente solicite fotos mais semelhantes em cada página de detalhes da imagem.


1

Eu tive o mesmo problema e escrevi um módulo python simples que compara duas imagens do mesmo tamanho usando o ImageChops da almofada para criar uma imagem diff em preto / branco e resume os valores do histograma.

Você pode obter essa pontuação diretamente ou um valor percentual comparado a uma comparação completa de preto versus branco.

Ele também contém uma função is_equal simples, com a possibilidade de fornecer um limite difuso abaixo (e incluindo) da imagem que passa como igual.

A abordagem não é muito elaborada, mas talvez seja útil para outros que estão por aí lutando com o mesmo problema.

https://pypi.python.org/pypi/imgcompare/


1

Uma abordagem um pouco mais baseada em princípios é usar um descritor global para comparar imagens, como GIST ou CENTRIST. Uma função de hash, conforme descrito aqui , também fornece uma solução semelhante.


1
import os
from PIL import Image
from PIL import ImageFile
import imagehash
  
#just use to the size diferent picture
def compare_image(img_file1, img_file2):
    if img_file1 == img_file2:
        return True
    fp1 = open(img_file1, 'rb')
    fp2 = open(img_file2, 'rb')

    img1 = Image.open(fp1)
    img2 = Image.open(fp2)

    ImageFile.LOAD_TRUNCATED_IMAGES = True
    b = img1 == img2

    fp1.close()
    fp2.close()

    return b





#through picturu hash to compare
def get_hash_dict(dir):
    hash_dict = {}
    image_quantity = 0
    for _, _, files in os.walk(dir):
        for i, fileName in enumerate(files):
            with open(dir + fileName, 'rb') as fp:
                hash_dict[dir + fileName] = imagehash.average_hash(Image.open(fp))
                image_quantity += 1

    return hash_dict, image_quantity

def compare_image_with_hash(image_file_name_1, image_file_name_2, max_dif=0):
    """
    max_dif: The maximum hash difference is allowed, the smaller and more accurate, the minimum is 0.
    recommend to use
    """
    ImageFile.LOAD_TRUNCATED_IMAGES = True
    hash_1 = None
    hash_2 = None
    with open(image_file_name_1, 'rb') as fp:
        hash_1 = imagehash.average_hash(Image.open(fp))
    with open(image_file_name_2, 'rb') as fp:
        hash_2 = imagehash.average_hash(Image.open(fp))
    dif = hash_1 - hash_2
    if dif < 0:
        dif = -dif
    if dif <= max_dif:
        return True
    else:
        return False


def compare_image_dir_with_hash(dir_1, dir_2, max_dif=0):
    """
    max_dif: The maximum hash difference is allowed, the smaller and more accurate, the minimum is 0.

    """
    ImageFile.LOAD_TRUNCATED_IMAGES = True
    hash_dict_1, image_quantity_1 = get_hash_dict(dir_1)
    hash_dict_2, image_quantity_2 = get_hash_dict(dir_2)

    if image_quantity_1 > image_quantity_2:
        tmp = image_quantity_1
        image_quantity_1 = image_quantity_2
        image_quantity_2 = tmp

        tmp = hash_dict_1
        hash_dict_1 = hash_dict_2
        hash_dict_2 = tmp

    result_dict = {}

    for k in hash_dict_1.keys():
        result_dict[k] = None

    for dif_i in range(0, max_dif + 1):
        have_none = False

        for k_1 in result_dict.keys():
            if result_dict.get(k_1) is None:
                have_none = True

        if not have_none:
            return result_dict

        for k_1, v_1 in hash_dict_1.items():
            for k_2, v_2 in hash_dict_2.items():
                sub = (v_1 - v_2)
                if sub < 0:
                    sub = -sub
                if sub == dif_i and result_dict.get(k_1) is None:
                    result_dict[k_1] = k_2
                    break
    return result_dict


def main():
    print(compare_image('image1\\815.jpg', 'image2\\5.jpg'))
    print(compare_image_with_hash('image1\\815.jpg', 'image2\\5.jpg', 7))
    r = compare_image_dir_with_hash('image1\\', 'image2\\', 10)
    for k in r.keys():
        print(k, r.get(k))


if __name__ == '__main__':
    main()
  • resultado:

    Falso
    Verdadeiro
    image2 \ 5.jpg image1 \ 815.jpg
    image2 \
    6.jpg image1 \ 819.jpg
    image2 \ 7.jpg image1 \ 900.jpg
    image2 \ 8.jpg image1 \ 998.jpg image2 \ 9.jpg image1 \ 1012 .jpg

  • as imagens de exemplo:

    • 815.jpg
      815.jpg

    • 5.jpg
      5.jpg


0

Eu acho que você poderia simplesmente calcular a distância euclidiana (isto é, sqrt (soma dos quadrados das diferenças, pixel por pixel)) entre a luminância das duas imagens e considerá-las iguais se isso cair abaixo de algum limiar empírico. E é melhor fazê-lo envolvendo uma função C.


0

Existem muitas métricas disponíveis para avaliar se duas imagens se parecem / com o que elas se parecem.

Não vou entrar em nenhum código aqui, porque acho que deve ser um problema científico, além de técnico.

Geralmente, a questão está relacionada à percepção do ser humano nas imagens, de modo que cada algoritmo tem seu suporte nos traços do sistema visual humano.

As abordagens clássicas são:

Preditor de diferenças visíveis: um algoritmo para a avaliação da fidelidade da imagem ( https://www.spiedigitallibrary.org/conference-proceedings-of-spie/1666/0000/Visible-differences-predictor--an-algorithm-for-the- avaliação-de / 10.1117 / 12.135952.short? SSO = 1 )

Avaliação da qualidade da imagem: da visibilidade do erro à semelhança estrutural ( http://www.cns.nyu.edu/pub/lcv/wang03-reprint.pdf )

FSIM: um índice de similaridade de recursos para avaliação da qualidade da imagem ( https://www4.comp.polyu.edu.hk/~cslzhang/IQA/TIP_IQA_FSIM.pdf )

Entre eles, o SSIM (Avaliação da qualidade da imagem: da visibilidade do erro à semelhança estrutural) é o mais fácil de calcular e sua sobrecarga também é pequena, conforme relatado em outro artigo "Avaliação da qualidade da imagem com base na similaridade de gradiente" ( https: //www.semanticscholar .org / paper / Avaliação da qualidade da imagem com base no gradiente-Liu-Lin / 2b819bef80c02d5d4cb56f27b202535e119df988 ).

Existem muitas outras abordagens. Dê uma olhada no Google Scholar e pesquise algo como "diferença visual", "avaliação da qualidade da imagem" etc., se você estiver interessado / realmente se interessar pela arte.


0

Existe uma solução simples e rápida usando numpy calculando o erro quadrático médio:

before = np.array(get_picture())
while True:
    now = np.array(get_picture())
    MSE = np.mean((now - before)**2)

    if  MSE > threshold:
        break

    before = now
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.