Una exploración preliminar del reconocimiento de imágenes: buscar ojos

Recientemente, la maestra en el laboratorio asignó la primera tarea simple: dar una imagen y una imagen de los ojos tomados de los personajes en la imagen, y diseñar un algoritmo para encontrar la posición de los ojos en la imagen completa.

Primero ve al efecto intuitivo,
ingresa la imagen
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

Imagen de salida
Inserte la descripción de la imagen aquí

Imagen de entrada
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

Imagen de salida
Inserte la descripción de la imagen aquí

El conocimiento previo necesario para completar esta tarea (solo necesita comprenderlo sin profundizar) incluye la naturaleza de la multiplicación de vectores y el concepto de convolución .

La llamada convolución, en términos simples, es la matriz y los elementos correspondientes de la matriz se multiplican respectivamente ( nota, no multiplicación de matrices ), generalmente habrá una matriz más pequeña como filtro, desde la esquina superior izquierda de la imagen más grande hasta la esquina inferior derecha, cálculo La suma de convolución de cada matriz pequeña (el tamaño de la matriz pequeña es el mismo que la matriz de filtro), donde el punto correspondiente a la suma más grande es la esquina superior izquierda de la matriz con el grado de coincidencia más alto.

¿Por qué la suma convolucional más grande es la mejor coincidencia? Piénselo, el proceso de convolución es la multiplicación de los puntos correspondientes en la matriz, que es lo mismo que el resultado de expandir la matriz en un vector unidimensional y luego multiplicar. A partir de la propiedad de la multiplicación de vectores se puede saber que el valor máximo de la multiplicación se puede obtener cuando dos vectores son paralelos, porque el ángulo es 0 y cos0 = 1. Por supuesto, dos vectores idénticos son paralelos, por lo que la suma de la convolución es la mayor.

Sin embargo, todavía está mal. Puede hacer esa pregunta. Una matriz grande se puede dividir en muchas matrices pequeñas. Si los valores de las dos matrices son muy diferentes entre sí y el filtro no tiene mucho efecto, ¿qué debo hacer en este momento? ¿Qué? La respuesta es simple, es decir, para cada matriz pequeña en la matriz grande, el valor promedio de sí mismo se resta antes de la convolución con la matriz de filtro, para evitar que la brecha de valores sea demasiado grande.

Dado que se ha restado el valor promedio de la matriz pequeña en la matriz grande, ¿verdad?
Bueno, aunque no es necesario hacer esto, puede hacer que el valor calculado sea relativamente pequeño.

oficial

Después de la ola de análisis anterior, además de eliminar el denominador, de hecho, la versión final es simplemente encontrar el coeficiente de correlación orz. Cuanto mayor sea el coeficiente de correlación, mayor será el grado de coincidencia.
Inserte la descripción de la imagen aquí

En este punto, la estructura del algoritmo está fuera y el código es muy conciso, como sigue:

import matplotlib.pyplot as plt # plt 用于显示图片
import numpy as np
from PIL import Image

def find_piece_in_pic(whole_pic, part_pic) :
    #两个参数分别是两张图片的地址
    
    part = Image.open(part_pic)
    #转化为灰度图
    part = part.convert('L')
    part = np.array(part).astype('float64')

    whole = Image.open(whole_pic)
    whole = whole.convert('L')
    whole = np.array(whole).astype('float64')

    H, W = whole.shape
    h, w = part.shape

    part = part - int(np.average(part))

    res = np.zeros((whole.shape))

    for r in range(H - h + 1) :
        for c in range(W - w + 1) :
            cur_whole = whole[r : r + h, c : c + w]
            cur_whole = cur_whole - np.average(cur_whole)
            temp1 = (math.sqrt(np.sum(part * part)) * math.sqrt(np.sum(cur_whole * cur_whole)))
            if temp1 == 0 : continue
            temp = np.sum(cur_whole * part) / temp1
            res[r ,c] = temp

    topr, topc = np.where(res == np.max(res))
    print(topr, topc)
    print(np.max(res))

    plt.figure()
    plt.imshow(whole, cmap='gray')#灰度图要加上这个参数
    plt.gca().add_patch(plt.Rectangle((topc,topr), w, h, color='black'))
    plt.show()
    

find_piece_in_pic('einstain.png', 'eye.png')

Función Matlab

Por supuesto, un algoritmo tan simple y altamente aplicable debe incluirse en Matlab. Se vuelve extremadamente simple en Matlab porque todas las funciones están encapsuladas.
Todavía tome a Einstein y sus encantadores ojos grandes como ejemplo:

eye = rgb2gray(imread('eye.png'));
einstain = rgb2gray(imread('einstain.png'));
imshowpair(peppers,onion,'montage')

c = normxcorr2(eye,einstain); #就是这个函数
figure, surf(c), shading flat
[ypeak, xpeak] = find(c==max(c(:)));

yoffSet = ypeak-size(eye,1);
xoffSet = xpeak-size(eye,2);

figure
imshow(einstain);
imrect(gca, [xoffSet+1, yoffSet+1, size(eye,2), size(eye,1)]);

Supongo que te gusta

Origin blog.csdn.net/weixin_43867940/article/details/106162416
Recomendado
Clasificación