Estoy tratando de realizar una ecualización del histograma usando OpenCV usando la siguiente función

Mat Histogram::Equalization(const Mat& inputImage)
{
    if(inputImage.channels() >= 3)
    {
        vector<Mat> channels;
        split(inputImage,channels);
        Mat B,G,R;

        equalizeHist( channels[0], B );
        equalizeHist( channels[1], G );
        equalizeHist( channels[2], R );
        vector<Mat> combined;
        combined.push_back(B);
        combined.push_back(G);
        combined.push_back(R);
        Mat result;
        merge(combined,result);
        return result;
    }
    return Mat();
}

Pero cuando me sale el resultado, no parece haber ninguna diferencia en la imagen de entrada y salida, ¿qué estoy haciendo mal?

Lo siento por la mala calidad de la imagen, «Procesados» (a la izquierda) es el histograma ecualizado, usted puede ver la misma que la de entrada (a la derecha).

Ecualización del histograma no funciona en el color de la imagen - OpenCV

¿Qué señorita?

  • Split -> Ecualizar -> Merge no es el enfoque correcto para realizar la ecualización de histograma de color de la imagen. Se verá seriamente el efecto equilibrio de color de la imagen. Traer un objeto de varios colores en la imagen y podrás ver el color de desequilibrio se va a crear.
InformationsquelleAutor | 2013-02-21

3 Comentarios

  1. 70

    De ecualización de histograma es un proceso no-lineal. Canal de la división y la ecualización de cada canal por separado no es la forma apropiada para la compensación de contraste. Ecualización implica Intensidad los valores de la imagen que no los componentes de color. Así, por una simple imagen en color RGB, ÉL no debe ser aplicada de forma individual en cada canal. Más bien, debe ser aplicado tal que los valores de intensidad se igualan sin perturbar el equilibrio de color de la imagen. Así, el primer paso es convertir el espacio de color de la imagen de RGB en uno de los espacios de color que se separan de los valores de intensidad de las componentes de color. Algunos de estos son:

    Convertir la imagen de RGB a uno de los mencionados espacios de color. YCbCr es preferido, ya que está diseñado para digital imágenes. Realizar ÉL de la intensidad de avión Y. Convertir la imagen a RGB.

    En su situación actual, no observando ningún cambio significativo, ya que sólo hay 2 prominente colores en la imagen. Cuando hay un montón de colores en la imagen, el método de división hará que el color desequilibrio.

    Como un ejemplo, considere las siguientes imágenes:

    De La Imagen De Entrada

    Ecualización del histograma no funciona en el color de la imagen - OpenCV

    Intensidad De La Imagen De Ecualización

    Ecualización del histograma no funciona en el color de la imagen - OpenCV

    Individual De Canales De Ecualización

    (Aviso a los falsos colores)

    Ecualización del histograma no funciona en el color de la imagen - OpenCV

    Aquí es el OpenCV código para la ecualización de histograma de color de la imagen utilizando YCbCr espacio de color.

    Mat equalizeIntensity(const Mat& inputImage)
    {
        if(inputImage.channels() >= 3)
        {
            Mat ycrcb;
    
            cvtColor(inputImage,ycrcb,CV_BGR2YCrCb);
    
            vector<Mat> channels;
            split(ycrcb,channels);
    
            equalizeHist(channels[0], channels[0]);
    
            Mat result;
            merge(channels,ycrcb);
    
            cvtColor(ycrcb,result,CV_YCrCb2BGR);
    
            return result;
        }
        return Mat();
    }
    • Gracias 🙂 Se que probarlo!
    • Hermosa, esta es la mejor solución. Todo lo demás me vio involucrado manipulación de la trama de las matrices. ++++1
  2. 7

    Y la versión de python, @sga:

    import cv2
    import os
    
        def hisEqulColor(img):
            ycrcb=cv2.cvtColor(img,cv2.COLOR_BGR2YCR_CB)
            channels=cv2.split(ycrcb)
            print len(channels)
            cv2.equalizeHist(channels[0],channels[0])
            cv2.merge(channels,ycrcb)
            cv2.cvtColor(ycrcb,cv2.COLOR_YCR_CB2BGR,img)
            return img
    
    
    fname='./your.jpg'
    img=cv2.imread(fname)
    
    cv2.imshow('img', img)
    img2=hisEqulColor(img)
    cv2.imshow('img2',img2)

    Sin embargo, esto va a producir ruido en la imagen (por ejemplo, la imagen de la izquierda abajo) Ecualización del histograma no funciona en el color de la imagen - OpenCV

  3. 1

    He implementado una ecualización del histograma para BGRA de la imagen. Creo que esta función es útil para su objetivo (pero usted debe ignorar el canal alfa).

    Mat equalizeBGRA(const Mat& img)
    {
    Mat res(img.size(), img.type());
    Mat imgB(img.size(), CV_8UC1);
    Mat imgG(img.size(), CV_8UC1);
    Mat imgR(img.size(), CV_8UC1);
    Vec4b pixel;
    if (img.channels() != 4)
    {
    cout << "ERROR: image input is not a BGRA image!" << endl;
    return Mat();
    }
    for (int r = 0; r < img.rows; r++)
    {
    for (int c = 0; c < img.cols; c++)
    {
    pixel = img.at<Vec4b>(r, c);
    imgB.at<uchar>(r, c) = pixel[0];
    imgG.at<uchar>(r, c) = pixel[1];
    imgR.at<uchar>(r, c) = pixel[2];
    }
    }
    equalizeHist(imgB, imgB);
    equalizeHist(imgG, imgG);
    equalizeHist(imgR, imgR);
    for (int r = 0; r < img.rows; r++)
    {
    for (int c = 0; c < img.cols; c++)
    {
    pixel = Vec4b(imgB.at<uchar>(r, c), imgG.at<uchar>(r, c), imgR.at<uchar>(r, c), img.at<Vec4b>(r, c)[3]);
    res.at<Vec4b>(r, c) = pixel;
    }
    }
    return res;
    }
    • Este enfoque está bien, pero todavía sigue el canal en el método de división que no es recomendable. También, en lugar de un bucle, puede usar cv::mixChannels extracto de R, G y B de 4 canales de la imagen.

Dejar respuesta

Please enter your comment!
Please enter your name here