2014-06-21 12 views
37

Ho alcune foto a colori e l'illuminazione non è regolare nelle foto: un lato dell'immagine è più luminoso dell'altro lato.correzione dell'illuminazione semplice in immagini openCV C++

Mi piacerebbe risolvere questo problema correggendo l'illuminazione. Penso contrasto locale mi aiuterà, ma io non so come :(

Vi prego di aiutare con un pezzo di codice o di un oleodotto?

risposta

85

convertire l'immagine RGB a Lab dello spazio colore (ad esempio, , qualsiasi spazio colore con un canale di luminanza funzionerà bene), quindi applicare adaptive histogram equalization al canale L. Infine convertire il Lab risultante in RGB

Quello che si desidera è l'algoritmo CLAHE (Contrast Limited Adaptive Histogram Equalization) di OpenCV. Tuttavia, per quanto ne so non è documentato. C'è an example in python. Puoi leggere su CLAHE in Graphics Gems IV, pp474-485

Ecco un esempio di CLAHE in azione: enter image description here

E qui è il C++ che ha prodotto l'immagine qui sopra, sulla base di http://answers.opencv.org/question/12024/use-of-clahe/, ma esteso per il colore.

#include <opencv2/core.hpp> 
#include <vector>  // std::vector 
int main(int argc, char** argv) 
{ 
    // READ RGB color image and convert it to Lab 
    cv::Mat bgr_image = cv::imread("image.png"); 
    cv::Mat lab_image; 
    cv::cvtColor(bgr_image, lab_image, CV_BGR2Lab); 

    // Extract the L channel 
    std::vector<cv::Mat> lab_planes(3); 
    cv::split(lab_image, lab_planes); // now we have the L image in lab_planes[0] 

    // apply the CLAHE algorithm to the L channel 
    cv::Ptr<cv::CLAHE> clahe = cv::createCLAHE(); 
    clahe->setClipLimit(4); 
    cv::Mat dst; 
    clahe->apply(lab_planes[0], dst); 

    // Merge the the color planes back into an Lab image 
    dst.copyTo(lab_planes[0]); 
    cv::merge(lab_planes, lab_image); 

    // convert back to RGB 
    cv::Mat image_clahe; 
    cv::cvtColor(lab_image, image_clahe, CV_Lab2BGR); 

    // display the results (you might also want to see lab_planes[0] before and after). 
    cv::imshow("image original", bgr_image); 
    cv::imshow("image CLAHE", image_clahe); 
    cv::waitKey(); 
} 
+1

vi ringrazio molto – user3762718

+0

cercherò ora e farò pot mio risultato. grazie per il vostro gentile supporto – user3762718

+5

python è stato spostato. ecco il nuovo link: https://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_histograms/py_histogram_equalization/py_histogram_equalization.html –

5

sulla base delle ottime C++ example written by Bull, sono stato in grado di scrivere questo metodo per Android.

Ho sostituito "Core.extractChannel" per "Core.split". Ciò evita un known memory leak issue.

public void applyCLAHE(Mat srcArry, Mat dstArry) { 
    //Function that applies the CLAHE algorithm to "dstArry". 

    if (srcArry.channels() >= 3) { 
     // READ RGB color image and convert it to Lab 
     Mat channel = new Mat(); 
     Imgproc.cvtColor(srcArry, dstArry, Imgproc.COLOR_BGR2Lab); 

     // Extract the L channel 
     Core.extractChannel(dstArry, channel, 0); 

     // apply the CLAHE algorithm to the L channel 
     CLAHE clahe = Imgproc.createCLAHE(); 
     clahe.setClipLimit(4); 
     clahe.apply(channel, channel); 

     // Merge the the color planes back into an Lab image 
     Core.insertChannel(channel, dstArry, 0); 

     // convert back to RGB 
     Imgproc.cvtColor(dstArry, dstArry, Imgproc.COLOR_Lab2BGR); 

     // Temporary Mat not reused, so release from memory. 
     channel.release(); 
    } 

} 

e chiamarlo in questo modo:

public Mat onCameraFrame(CvCameraViewFrame inputFrame){ 
    Mat col = inputFrame.rgba(); 

    applyCLAHE(col, col);//Apply the CLAHE algorithm to input color image. 

    return col; 
} 
16

La risposta fornita dal Bull è la migliore Mi sono imbattuto finora. L'ho usato per. Ecco il codice Python per lo stesso:

import cv2 

#-----Reading the image----------------------------------------------------- 
img = cv2.imread('Dog.jpg', 1) 
cv2.imshow("img",img) 

#-----Converting image to LAB Color model----------------------------------- 
lab= cv2.cvtColor(img, cv2.COLOR_BGR2LAB) 
cv2.imshow("lab",lab) 

#-----Splitting the LAB image to different channels------------------------- 
l, a, b = cv2.split(lab) 
cv2.imshow('l_channel', l) 
cv2.imshow('a_channel', a) 
cv2.imshow('b_channel', b) 

#-----Applying CLAHE to L-channel------------------------------------------- 
clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8,8)) 
cl = clahe.apply(l) 
cv2.imshow('CLAHE output', cl) 

#-----Merge the CLAHE enhanced L-channel with the a and b channel----------- 
limg = cv2.merge((cl,a,b)) 
cv2.imshow('limg', limg) 

#-----Converting image from LAB Color model to RGB model-------------------- 
final = cv2.cvtColor(limg, cv2.COLOR_LAB2BGR) 
cv2.imshow('final', final) 

#_____END_____# 
+1

Works. Ci sono alcuni errori di battitura nel tuo codice: i livelli l, a, b sono referenziati come l, aa, bb e successivamente cl è indicato come cl2. clipLimit consente di sintonizzare l'effetto, 1.0 è piuttosto sottile, 3 e 4 sono più aggressivi. – jdelange

+0

Grazie per averlo individuato! –

0

È inoltre possibile utilizzare Adaptive Istogramma equalizzazione,

from skimage import exposure 

img_adapteq = exposure.equalize_adapthist(img, clip_limit=0.03)