Tengo dos imágenes en blanco y negro y necesito calcular la información mutua.

Image 1 = X 
Image 2 = Y

Sé que la información mutua puede ser definido como:

MI = entropy(X) + entropy(Y) - JointEntropy(X,Y)

MATLAB ya se ha incorporado en las funciones para calcular la entropía, pero no para el cálculo de la articulación de la entropía. Supongo que la verdadera pregunta es: ¿Cómo puedo calcular la entropía conjunta de dos imágenes?

Aquí es un ejemplo de las imágenes que me gustaría encontrar la articulación de la entropía de:

X =

0    0    0    0    0    0
0    0    1    1    0    0
0    0    1    1    0    0
0    0    0    0    0    0
0    0    0    0    0    0

Y =

0    0    0    0    0    0 
0    0    0.38 0.82 0.38 0.04 
0    0    0.32 0.82 0.68 0.17
0    0    0.04 0.14 0.11 0 
0    0    0    0    0    0
  • Si la imagen de las intensidades están en el rango de [0,1], entonces usted todavía puede usar el código que escribí a continuación, pero usted necesita para asegurarse de que las intensidades son números enteros. Si usted tiene imágenes de 8 bits, el uso de im2uint8 antes de ir a través de lo que hice.
  • También, si su imagen es puramente binario, entonces no convertir el uso de im2uint8 como sería un desperdicio de espacio. Usted puede utilizar el código como está. Dejarlo como un histograma con 4 articulación de contenedores en lugar de tener 256 x 256.
  • Muchas gracias por su ayuda. Terminé multiplicando mi imagen por 100 y luego redondear el número + 1 ->Im1 = round(100*Im0+1), de Esta manera he arreglado todos los errores 1) el código que se quiere enteros 2) quiere que los valores positivos. 😀
  • Si su imagen es una imagen de 8 bits, yo no recomendaría hacer que debido a la pérdida de bin contar. Todavía iba a convertir su imagen utilizando im2uint8. Este va a convertir su imagen a [0,255]. También, si nos fijamos en cómo MATLAB implementa la entropy comando, también utilizan im2uint8 así. Usted necesita ser consistente con la cantidad de contenedores que está utilizando para ambos entropy y lo que hemos hablado con la articulación de la entropía.
InformationsquelleAutor Jorge | 2014-05-16

1 Comentario

  1. 60

    Para calcular la entropía conjunta, debe calcular el histograma conjunto entre las dos imágenes. La articulación histograma es esencialmente el mismo como una normal 1D histograma pero la primera dimensión de los registros de intensidades para la primera imagen y la segunda dimensión de los registros de intensidades para la segunda imagen. Esto es muy similar a lo que comúnmente se conoce como un matriz de co-ocurrencia. En la ubicación (i,j) en la articulación de histograma, le dice cómo muchos de los valores de intensidad, nos hemos encontrado con que intensidad i en la primera imagen y la intensidad j en la segunda imagen.

    Lo importante es que esta registros de cuántas veces hemos visto este par de intensidades en las mismas ubicaciones correspondientes. Por ejemplo, si tenemos un conjunto de histograma recuento de (7,3) = 2, esto significa que cuando estábamos de escaneo de imágenes de ambos, cuando encontramos la intensidad de 7, en la misma ubicación correspondiente en la segunda imagen, se encontró que la intensidad de 3 para un total de 2 veces.

    La construcción de un conjunto de histograma es muy simple de hacer.

    1. En primer lugar, crear un 256 x 256 de la matriz (asumiendo que su imagen es de 8 bits sin signo entero) e inicializar a todos los ceros. También, usted necesita para asegurarse de que ambas imágenes son del mismo tamaño (anchura y altura).
    2. Una vez hecho eso, echar un vistazo a la primera de píxeles de cada imagen, que denominaremos como la esquina superior izquierda. Específicamente, echa un vistazo a las intensidades de la primera y segunda imagen en este lugar. La intensidad de la primera imagen servirá como la fila mientras que la intensidad de la segunda imagen que servirá como la columna.
    3. Encontrar esta ubicación en la matriz y el incremento de este punto en la matriz por el 1.
    4. Repita este procedimiento para el resto de las ubicaciones en la imagen.
    5. Después de que haya terminado, dividir todas las entradas por el número total de elementos en la imagen (recuerda que debe ser del mismo tamaño). Esto nos dará la distribución de probabilidad conjunta entre ambas imágenes.

    Uno estaría inclinado a hacer esto con for bucles, pero como es comúnmente conocido, for bucles son notoriamente lentos y debe evitarse si es posible. Sin embargo, usted puede hacer esto fácilmente en MATLAB de la siguiente manera sin bucles. Supongamos que im1 y im2 son la primera y la segunda de las imágenes que desea comparar. Lo que podemos hacer es convertir im1 y im2 en vectores. A continuación, podemos utilizar accumarray para ayudarnos a calcular el conjunto de histograma. accumarray es uno de los más potentes funciones en MATLAB. Usted puede pensar en él como una miniatura paradigma MapReduce. Simplemente, cada uno de los datos de entrada tiene una clave y un valor asociado. El objetivo de accumarray es bin todos los valores que pertenecen a la misma clave y hacer alguna operación en todos estos valores. En nuestro caso, la «clave» sería la intensidad de valores, y los valores propios son el valor de 1 para cada valor de intensidad. Entonces, nos quieren agregar de seguridad de todos los valores de 1 que se asignan a la misma bin, que es exactamente cómo nos gustaría que se calcula un histograma. El comportamiento por defecto para accumarray es agregar todos estos valores. Específicamente, la salida de accumarray sería una matriz en la que cada posición se calcula la suma de todos los valores que asigna a la tecla. Por ejemplo, la primera posición sería la suma de todos los valores que se asignan a la clave de la 1, la segunda posición sería la suma de todos los valores que se asignan a la clave de la 2 y así sucesivamente.

    Sin embargo, para el conjunto de histograma, se quiere averiguar qué valores se asignan a la misma intensidad par de (i,j), y así que las llaves aquí sería un par de coordenadas 2D. Como tal, cualquier intensidades que tienen una intensidad de i en la primera imagen y j en la segunda imagen en la misma ubicación espacial compartida entre las dos imágenes ir a la misma clave. Por lo tanto en 2D caso, la salida de accumarray sería una matriz 2D donde cada elemento (i,j) contiene la suma de todos los valores que se asignan a la tecla de (i,j), similar a la 1D caso que se ha mencionado anteriormente, que es exactamente lo que estamos buscando.

    En otras palabras:

    indrow = double(im1(:)) + 1;
    indcol = double(im2(:)) + 1; %//Should be the same size as indrow
    jointHistogram = accumarray([indrow indcol], 1);
    jointProb = jointHistogram / numel(indrow);

    Con accumarray, la primera entrada son las claves y la segunda entrada son los valores. Una nota con accumarray es que si cada tecla tiene la mismo valor, usted puede simplemente asignar una constante para la segunda entrada, que es lo que he hecho y 1. En general, esta es una matriz con el mismo número de filas que la primera entrada. Además, tome nota especial de las dos primeras líneas. Inevitablemente habrá una intensidad de 0 en su imagen, pero debido a que MATLAB se inicia la indexación en 1, necesitamos compensar las matrices 1.

    Ahora que tenemos el conjunto de histograma, es realmente simple para calcular la articulación de la entropía. Es similar a la de la entropía en 1D, excepto que ahora sólo estamos sumando más de la totalidad de la probabilidad conjunta de la matriz. Tenga en cuenta que es muy probable que su articulación histograma tendrá muchas 0 entradas. Necesitamos asegurarnos de que nos saltamos los o el log2 operación será indefinido. Vamos a deshacernos de cualquier cero entradas ahora:

    indNoZero = jointHistogram ~= 0;
    jointProb1DNoZero = jointProb(indNoZero);

    Tomar nota de que he buscado la articulación histograma en lugar de la probabilidad conjunta de la matriz. Esto es debido a que la articulación histograma consiste de números enteros, mientras que la probabilidad conjunta de la matriz se encuentran entre 0 y 1. A causa de la división, quiero evitar la comparación de las entradas de esta matriz con 0 debido a numéricos de redondeo y la inestabilidad. Los anteriores también convertir nuestra probabilidad conjunta de la matriz en una apilada 1D vector, lo cual está bien.

    Como tal, el conjunto de la entropía se puede calcular como:

    jointEntropy = -sum(jointProb1DNoZero.*log2(jointProb1DNoZero));

    Si mi comprensión de cálculo de la entropía de una imagen en MATLAB es correcta, se debe calcular el histograma /distribución de probabilidad sobre 256 contenedores, por lo que sin duda se puede utilizar la función que aquí el conjunto de la entropía que se acaba de calcular.

    Lo que si tenemos datos de punto flotante lugar?

    Hasta ahora, hemos supuesto que las imágenes que se han tratado con intensidades de valor entero. Lo que si hemos de datos de punto flotante? accumarray se supone que está tratando de índice en la matriz de salida usando números enteros, pero todavía podemos ciertamente lograr lo que queremos con este pequeño bache en el camino. Lo que haría es simplemente asignar a cada valor de punto flotante en ambas imágenes para tener una IDENTIFICADOR único. Sería por lo tanto el uso accumarray con estos Identificadores de lugar. Para facilitar esta IDENTIFICACIÓN de la asignación, uso único – específicamente la tercera salida de la función. Usted podría tomar cada una de las imágenes, poner en unique y hacer que estos son los índices de la entrada en accumarray. En otras palabras, hacer esto en su lugar:

    [~,~,indrow] = unique(im1(:)); %//Change here
    [~,~,indcol] = unique(im2(:)); %//Change here
    
    %//Same code
    jointHistogram = accumarray([indrow indcol], 1);
    jointProb = jointHistogram / numel(indrow);
    indNoZero = jointHistogram ~= 0;
    jointProb1DNoZero = jointProb(indNoZero);
    jointEntropy = -sum(jointProb1DNoZero.*log2(jointProb1DNoZero));

    Tenga en cuenta que con indrow y indcol, estamos directamente a la asignación de la tercera salida de unique a estas variables y, a continuación, utilizando el mismo conjunto de entropía código que hemos calculado anteriormente. No tenemos a la compensación de las variables por 1 como hicimos anteriormente porque unique va a asignar Identificadores a partir de la 1.

    A un lado

    Realidad se puede calcular los histogramas o distribuciones de probabilidad para cada imagen de forma individual utilizando la probabilidad conjunta de la matriz. Si quieres calcular los histogramas /distribuciones de probabilidad para la primera imagen, basta con acumular todas las columnas de cada fila. Para hacerlo en la segunda imagen, basta con acumular todas las filas de cada columna. Como tal, usted puede hacer:

    histogramImage1 = sum(jointHistogram, 1);
    histogramImage2 = sum(jointHistogram, 2);

    Después, se puede calcular la entropía de ambos por ti mismo. Doble comprobación, asegúrese de apagar tanto de estos en Pdf, a continuación, calcular la entropía usando el estándar de la ecuación (igual que arriba).


    ¿Cómo hago para finalmente calcular la Información Mutua?

    Para finalmente calcular la Información Mutua, vas a necesitar la entropía de las dos imágenes. Usted puede utilizar MATLAB integrado en entropía función, pero esto supone que no hay 256 niveles únicos. Usted probablemente desee aplicar esto para el caso de no ser N distintos niveles en lugar de 256, y así que usted puede utilizar lo que hicieron anteriormente con el conjunto de histograma, luego de computación de los histogramas para cada imagen en el lado de código anterior, y, a continuación, calcular la entropía para cada imagen. Sólo tendría que repetir el cálculo de la entropía que fue utilizado de manera conjunta, pero se aplica a cada imagen de forma individual:

    %//Find non-zero elements for first image's histogram
    indNoZero = histogramImage1 ~= 0;
    
    %//Extract them out and get the probabilities
    prob1NoZero = histogramImage1(indNoZero);
    prob1NoZero = prob1NoZero / sum(prob1NoZero);
    
    %//Compute the entropy
    entropy1 = -sum(prob1NoZero.*log2(prob1NoZero));
    
    %//Repeat for the second image
    indNoZero = histogramImage2 ~= 0;
    prob2NoZero = histogramImage2(indNoZero);
    prob2NoZero = prob2NoZero / sum(prob2NoZero);
    entropy2 = -sum(prob2NoZero.*log2(prob2NoZero));
    
    %//Now compute mutual information
    mutualInformation = entropy1 + entropy2 - jointEntropy;

    Espero que esto ayude!

    • Buena alternativa para el uso de for bucles.
    • esto es casi un spam comentario, pero tenía que decir esto: esta es una de las mejores respuestas que he encontrado en TAN. de manera concisa explica el fondo, la razón detrás de el código y va desde la más sencilla (entero) a la más difícil de caso reales (real valorados). También, uno de los mejores ejemplos de la utilización de accumarray.
    • muchas gracias 🙂 de hecho, esta fue una de mis anteriores respuestas, cuando empecé a responder a las preguntas. Nunca fue esperando que esto sea tan popular. En realidad la versión actual que se observa ahora había una gran cantidad de ediciones de la versión inicial. Yo sólo lo resuelto por el entero caso y se resuelve sólo para el conjunto de histograma. He editado el este a lo largo del tiempo, y que incluía el de punto flotante caso y, finalmente, la computación de la información mutua. De cualquier modo, gracias por el comentario 🙂 se lo agradezco mucho.
    • He aprendido mucho de esta respuesta al inicio de mi tesis de Doctorado.
    • Soy nuevo en esto, estoy trabajando en este ejemplo y me sale negativo de MI. No se debería esperar que el MI ser positivo? im1 = ones(10,10); im2 = ones(10,10);
    • También, para cualquier par de matrices aleatorias de cualquier tamaño, que a MI se convierte en una función de sus tamaños.
    • Gracias por tu comentario. En realidad, no fue un error que no he entendido que se hizo evidente con su ejemplo. Acabo de arreglar. Ejecutar ahora y debe ser correcto. Básicamente, yo no estaba en la creación de las distribuciones de probabilidad entre las dos señales correctamente. Sin embargo, para responder a su pregunta de la entropía entre las dos señales es 0, lo que significa que la información mutua entre ellos también es 0. Esto es debido a que todos los valores sólo se correlacionan con 1 bandeja, y por lo que la probabilidad de que el valor que ocurre siempre será 1, por lo tanto el log2 de que es 0.
    • Gracias por la rápida respuesta. Todavía tengo algún problema, aunque. para im1 = rand(10,10); im2 = rand(10,10); siempre devuelve 6.6439 y lo mismo sucede con las im1 = rand(10,10); im2 = im1;.
    • se utiliza el código suponiendo doble precisión? Deberá utilizar el código apropiado para el tipo de datos.
    • Ah, gracias. Que resuelve el problema. Gracias por tu ayuda.
    • aha! Np a todos. Mi placer. También gracias por llegar a mí. Yo no habría encontrado el error en el código, si no ponte en contacto conmigo. Muy apreciado.
    • Una nota más, me doy cuenta de que el código de cuenta de cómo muchas de las intensidades son «exactamente» iguales el uno al otro, para que, cuando estoy tratando con doble precisión, que (casi) nunca coinciden. Es allí cualquier manera de construir el PDF de considerar algunos cajones que tomar en cuenta un umbral? por ejemplo, si tengo un vector de longitud 1000 de números entre 0 y 1, puedo modificar esto para considerar 0.05 y 0.06 en el mismo?
    • Creo que este debería ser tomada con cuidado, antes de llegar a «unique()» parte. Tal vez debería bin primero los datos de forma independiente, y luego ir de allí?
    • parece, esto va a hacer es: edges = -1:0.01:1; im1b = discretize(im1,edges); im2b = discretize(im2,edges);
    • Esa es una buena idea. No voy a usar discretize con el fin de acomodar las antiguas versiones de MATLAB. Voy a actualizar cuando soy capaz. Gracias por el aporte!

Dejar respuesta

Please enter your comment!
Please enter your name here