imagen - histograma opencv c++
EcualizaciĆ³n de histograma no funciona en la imagen en color-OpenCV (3)
Implementé una ecualización de histograma para la imagen BGRA. Creo que esta función es útil para su objetivo (pero 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;
}
Estoy tratando de realizar una ecualización de 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 obtengo el resultado, parece que no hay diferencia en la imagen de entrada y salida, ¿qué estoy haciendo mal?
Perdón por la mala calidad de la imagen, "Preprocesado" (izquierda) se ecualiza el histograma, puede ver lo mismo que la entrada (derecha).
¿Qué falló?
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 producirá ruido en la imagen (por ejemplo, la imagen de la izquierda a continuación)
La ecualización de histogramas es un proceso no lineal. Canal dividir y ecualizar cada canal por separado no es la forma adecuada para la igualación de contraste. La ecualización implica valores de Intensidad de la imagen, no los componentes de color. Por lo tanto, para una imagen de color RGB simple, HE no se debe aplicar individualmente en cada canal. Por el contrario, debe aplicarse de manera que los valores de intensidad se igualen sin alterar el equilibrio de color de la imagen. Por lo tanto, el primer paso es convertir el espacio de color de la imagen de RGB en uno de los espacios de color que separa los valores de intensidad de los componentes de color. Algunos de estos son:
Convierte la imagen de RGB a uno de los espacios de color mencionados anteriormente. Se prefiere YCbCr ya que está diseñado para imágenes digitales . Realice HE del plano de intensidad Y. Convierta la imagen a RGB.
En su situación actual, no está observando ningún cambio significativo, porque solo hay 2 colores prominentes en la imagen. Cuando hay muchos colores en la imagen, el método de división causará un desequilibrio de color.
Como ejemplo, considere las siguientes imágenes:
Imagen de entrada
Ecualización de imagen de intensidad
Ecualización de canal individual
(Observe los colores falsos)
Aquí está el código de OpenCV para la ecualización del histograma de la imagen en color usando el espacio de color YCbCr .
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();
}