RoboticsLabURJC / 2017-tfm-jorge_vela

1 stars 2 forks source link

Añadir el suavizado + redimensionado a ChannelsExtractLUV #6

Closed jmbuena closed 4 years ago

jmbuena commented 5 years ago

Añadir el suavizado a la salida de los canales de color (se suavizan y se reducen de tamaño). Date cuenta que en el script chsCompute.m tenemos:

    I=rgbConvert(I,p.colorSpace); % <-- Nuestro ChannelsExtractorLUV actual.
    I=convTri(I,p.smooth); % <-- Suavizado
    if(p.enabled), chns=addChn(chns,I,nm,p,'replicate',h,w); end % <--- Aquí se redimensiona

y eso significa que se hace un suavizado con el convTri.m (y con versión C++). Pero en el convTri.m nos dicen que eso es equivalente en Matlab a:

    sigma = 4; rg = ceil(3*sigma); f = filterGauss(2*rg+1,[],sigma^2);
    J1=conv2(conv2(imPad(I,rg,'symmetric'),f,'valid'),f','valid');

Es decir, un suavizado gaussiano, que probablemente se puede hacer igual con cv::GaussianBlur de OpenCV. Queremos añadir el suavizado gaussiano a ChannelsExtractLUV cuando los parámetros del constructor digan que hay que hacerlo.

jorgevelap commented 5 years ago

Para las primeras pruebas de este apartado, cv::GaussianBlur y la función convTri de convConst.cpp, que coincide con los resultados de convTri.m , obtengo resultados distintos utilizando la misma matriz:

Captura_gaussian

jmbuena commented 5 years ago

¿Pero la diferencia es en los bordes de la matriz o en toda la matriz? Creo que P. Dollar trata los bordes de una manera especial ¿No hace padding y rellena con ceros o algo así?

jorgevelap commented 5 years ago

Si que se da esta diferencia cuando se hace con los bordes, ya que cuando el pixel que varia esta en el centro no afecta al calculo:

Captura_gaussian_pix28

Probando en la segunda columna, que tiene que hacer el calculo teniendo en cuenta el pixel del borde, también hay una variación entre ambos métodos:

Captura_gaussian_pix18

Si que es verdad que en sus ejemplos antes de llamar a la función llama a imPad para realizar este padding, estoy probando con esto pero el resultado sigue saliendo distinto.

jmbuena commented 5 years ago

Entonces parece que no hay problema. Estodo igual excepto en el borde de la imagen. En las convoluciones el borde de la imagen se puede manejar de diferentes formas. Por ejemplo en la ayuda de Matlab sobre conv2 se dice:

Subsection of the convolution, specified as one of these values:
    - 'full' — Return the full 2-D convolution.
    - 'same' — Return the central part of the convolution, which is the same size as A.
    - 'valid' — Return only parts of the convolution that are computed without zero-padded edges.

Y en la ayuda de convTri, se dice que esta llamada es igual que llamar a conv2 de Matlab con 'valid' pero después de haber llamado a imPad(I,rg,'symmetric'). Y esta función del toolbox de P.Dollar rellena el borde para que la convolución tenga datos en los bordes. En OpenCV tienes diferentes maneras de manejar los bordes en el gaussianBlur.

No está bien documentado lo que hace el 'symmetric' en el imPad, y el código es difícil de seguir. En cualquier caso, yo intentaría probar diferentes maneras de manejar el borde en OpenCV, empezando por: BORDER_REFLECT. Cuyo efecto se parece bastante a la palabra 'symmetric'. De esa manera usaríamos la que nos de el resultado del convTri.

jorgevelap commented 5 years ago

Utilizando BORDER_REFLECT si que se observan los mismos resultados, por lo tanto se puede obtener que la función con la que realiza el suavizado es equivalente a: cv::GaussianBlur(dummy_query, dummy_query2, Size(3,3), 0,0, BORDER_REFLECT);

Para estas pruebas, la matriz la he convertido a cv::mat y he utilizado la función, y luego la conversión inversa a un array.

Muchas gracias, el siguiente paso entonces es añadir esta función como una opción en caso de que se indique en el constructor como me dijiste. Sigo con esta parte.

A continuación dejo una imagen con un ejemplo del resultado obtenido. Captura_gaussian_borders

jorgevelap commented 5 years ago

He creado la función smoothImage en ChannelsExtractorLUV, de forma que si el parámetro del constructor indica que hay que realizar el suavizado, el ultimo paso de la funcion extractFeatures llama a la función que realiza el suavizado sobre cada canal de la imagen.

cv::GaussianBlur(inputImg[0], channelsLUV_output[0], cv::Size(m_smooth_kernel_size, m_smooth_kernel_size), 0,0, cv::BORDER_REFLECT);

jmbuena commented 5 years ago

Perfecto. Ahora tienes que crear los tests en TestChannelsExtractorLUV.cpp comparando con la salida de Matlab y has terminado esta parte.

jorgevelap commented 4 years ago

Los test se han creado y actualizado, en TestChannelsExtractorLUV.cpp está. En lugar de la función GaussianBlurr se ha creado la función convTri en Utils, ya que había que hacer un proceso un poco mas largo y que puede servir también a otras clases. En lugar de gaussianBlurr se llama a filter2D de opencv. Se tiene que crear el kernel específicamente y por eso también añadir la función en utils.

Una vez subido los test y habiendo visto que funciona, se da este hilo por cerrado.