Commit 17609b90 authored by Fedor Morozov's avatar Fedor Morozov

Mantiuk's tonemapping

parent c51b50b4
......@@ -123,10 +123,9 @@ HdrEncoder::~HdrEncoder()
bool HdrEncoder::write( const Mat& _img, const std::vector<int>& params )
{
CV_Assert(_img.channels() == 3);
Mat img;
if(_img.depth() == CV_32F) {
_img.convertTo(img, CV_32FC3);
} else {
if(_img.depth() != CV_32F) {
_img.convertTo(img, CV_32FC3, 1/255.0f);
}
CV_Assert(params.empty() || params[0] == HDR_NONE || params[0] == HDR_RLE);
......
......@@ -102,17 +102,25 @@ CV_EXPORTS_W Ptr<TonemapLinear> createTonemapLinear(float gamma = 1.0f);
class CV_EXPORTS_W TonemapDrago : public Tonemap
{
public:
CV_WRAP virtual float getSaturation() const = 0;
CV_WRAP virtual void setSaturation(float saturation) = 0;
CV_WRAP virtual float getBias() const = 0;
CV_WRAP virtual void setBias(float bias) = 0;
};
CV_EXPORTS_W Ptr<TonemapDrago> createTonemapDrago(float gamma = 1.0f, float bias = 0.85f);
CV_EXPORTS_W Ptr<TonemapDrago> createTonemapDrago(float gamma = 1.0f, float saturation = 1.0f, float bias = 0.85f);
// "Fast Bilateral Filtering for the Display of High-Dynamic-Range Images", Durand, Dorsey, 2002
class CV_EXPORTS_W TonemapDurand : public Tonemap
{
public:
CV_WRAP virtual float getSaturation() const = 0;
CV_WRAP virtual void setSaturation(float saturation) = 0;
CV_WRAP virtual float getContrast() const = 0;
CV_WRAP virtual void setContrast(float contrast) = 0;
......@@ -124,7 +132,7 @@ public:
};
CV_EXPORTS_W Ptr<TonemapDurand>
createTonemapDurand(float gamma = 1.0f, float contrast = 4.0f, float sigma_space = 2.0f, float sigma_color = 2.0f);
createTonemapDurand(float gamma = 1.0f, float saturation = 1.0f, float contrast = 4.0f, float sigma_space = 2.0f, float sigma_color = 2.0f);
// "Dynamic Range Reduction Inspired by Photoreceptor Physiology", Reinhard, Devlin, 2005
......@@ -144,6 +152,19 @@ public:
CV_EXPORTS_W Ptr<TonemapReinhardDevlin>
createTonemapReinhardDevlin(float gamma = 1.0f, float intensity = 0.0f, float light_adapt = 1.0f, float color_adapt = 0.0f);
class CV_EXPORTS_W TonemapMantiuk : public Tonemap
{
public:
CV_WRAP virtual float getScale() const = 0;
CV_WRAP virtual void setScale(float scale) = 0;
CV_WRAP virtual float getSaturation() const = 0;
CV_WRAP virtual void setSaturation(float saturation) = 0;
};
CV_EXPORTS_W Ptr<TonemapMantiuk>
createTonemapMantiuk(float gamma = 1.0f, float scale = 0.7f, float saturation = 1.0f);
class CV_EXPORTS_W ExposureAlign : public Algorithm
{
public:
......
......@@ -71,4 +71,16 @@ Mat tringleWeights()
return w;
}
void mapLuminance(Mat src, Mat dst, Mat lum, Mat new_lum, float saturation)
{
std::vector<Mat> channels(3);
split(src, channels);
for(int i = 0; i < 3; i++) {
channels[i] = channels[i].mul(1.0f / lum);
pow(channels[i], saturation, channels[i]);
channels[i] = channels[i].mul(new_lum);
}
merge(channels, dst);
}
};
\ No newline at end of file
......@@ -53,6 +53,8 @@ void checkImageDimensions(const std::vector<Mat>& images);
Mat tringleWeights();
void mapLuminance(Mat src, Mat dst, Mat lum, Mat new_lum, float saturation);
};
#endif
\ No newline at end of file
......@@ -109,7 +109,7 @@ public:
Mat response(256, 3, CV_32F);
for(int i = 0; i < 256; i++) {
for(int j = 0; j < 3; j++) {
response.at<float>(i, j) = max(i, 1);
response.at<float>(i, j) = static_cast<float>(max(i, 1));
}
}
process(src, dst, times, response);
......
This diff is collapsed.
......@@ -91,12 +91,11 @@ void loadResponseCSV(String path, Mat& response)
TEST(Photo_Tonemap, regression)
{
string test_path = string(cvtest::TS::ptr()->get_data_path()) + "hdr/";
string test_path = string(cvtest::TS::ptr()->get_data_path()) + "hdr/tonemap/";
Mat img, expected, result;
loadImage(test_path + "rle.hdr", img);
loadImage(test_path + "image.hdr", img);
float gamma = 2.2f;
test_path += "tonemap/";
Ptr<TonemapLinear> linear = createTonemapLinear(gamma);
linear->process(img, result);
......@@ -121,6 +120,12 @@ TEST(Photo_Tonemap, regression)
loadImage(test_path + "reinharddevlin.png", expected);
result.convertTo(result, CV_8UC3, 255);
checkEqual(result, expected, 0);
Ptr<TonemapMantiuk> mantiuk = createTonemapMantiuk(gamma);
mantiuk->process(img, result);
loadImage(test_path + "mantiuk.png", expected);
result.convertTo(result, CV_8UC3, 255);
checkEqual(result, expected, 0);
}
TEST(Photo_AlignMTB, regression)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment