Domanda

Took an example image from opencv (cat.jpg).To reduce brightness at particular area. here is the link for the image

http://tinypic.com/view.php?pic=2lnfx46&s=5

È stato utile?

Soluzione

Here is one possible solution. The bright spots are detected using a simple threshold operation. Then the bright spots are darkened using a gamma transformation. The result looks slightly better, but unfortunately, if the pixels in the image are exactly white, all the pixel information is lost and you will not be able to recover this information.

#include <opencv2/opencv.hpp>
#include <iostream>
#include <cfloat>

int threshold = 200;
double gammav = 3;

int main(int argc, char** argv )
{
    cv::Mat image,gray_image,bin_image;

    // read image
    cv::imread(argv[1]).convertTo(image,CV_32FC3);

    // find bright spots with thresholding
    cv::cvtColor(image, gray_image, CV_RGB2GRAY);
    cv::threshold( gray_image, bin_image, threshold, 255,0 );

    // blur mask to smooth transitions
    cv::GaussianBlur(bin_image, bin_image, cv::Size(21,21), 5 );

    // create 3 channel mask
    std::vector<cv::Mat> channels;
    channels.push_back(bin_image);
    channels.push_back(bin_image);
    channels.push_back(bin_image);
    cv::Mat bin_image3;
    cv::merge(channels,bin_image3); 

    // create darker version of the image using gamma correction
    cv::Mat dark_image = image.clone();
    for(int y=0; y<dark_image.rows; y++)
       for(int x=0; x<dark_image.cols; x++)
         for(int c=0;c<3;c++)
            dark_image.at<cv::Vec3f>(y,x)[c] = 255.0 * pow(dark_image.at<cv::Vec3f>(y,x)[c]/255.0,gammav);

    // create final image
    cv::Mat res_image = image.mul((255-bin_image3)/255.0) + dark_image.mul((bin_image3)/255.0);


    cv::imshow("orig",image/255);
    cv::imshow("dark",dark_image/255);
    cv::imshow("bin",bin_image/255);
    cv::imshow("res",res_image/255);

    cv::waitKey(0);
}

enter image description here

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top