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

Mantiuk's tonemapping

parent c51b50b4
...@@ -123,10 +123,9 @@ HdrEncoder::~HdrEncoder() ...@@ -123,10 +123,9 @@ HdrEncoder::~HdrEncoder()
bool HdrEncoder::write( const Mat& _img, const std::vector<int>& params ) bool HdrEncoder::write( const Mat& _img, const std::vector<int>& params )
{ {
CV_Assert(_img.channels() == 3);
Mat img; Mat img;
if(_img.depth() == CV_32F) { if(_img.depth() != CV_32F) {
_img.convertTo(img, CV_32FC3);
} else {
_img.convertTo(img, CV_32FC3, 1/255.0f); _img.convertTo(img, CV_32FC3, 1/255.0f);
} }
CV_Assert(params.empty() || params[0] == HDR_NONE || params[0] == HDR_RLE); 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); ...@@ -102,17 +102,25 @@ CV_EXPORTS_W Ptr<TonemapLinear> createTonemapLinear(float gamma = 1.0f);
class CV_EXPORTS_W TonemapDrago : public Tonemap class CV_EXPORTS_W TonemapDrago : public Tonemap
{ {
public: 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 float getBias() const = 0;
CV_WRAP virtual void setBias(float bias) = 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 // "Fast Bilateral Filtering for the Display of High-Dynamic-Range Images", Durand, Dorsey, 2002
class CV_EXPORTS_W TonemapDurand : public Tonemap class CV_EXPORTS_W TonemapDurand : public Tonemap
{ {
public: 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 float getContrast() const = 0;
CV_WRAP virtual void setContrast(float contrast) = 0; CV_WRAP virtual void setContrast(float contrast) = 0;
...@@ -124,7 +132,7 @@ public: ...@@ -124,7 +132,7 @@ public:
}; };
CV_EXPORTS_W Ptr<TonemapDurand> 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 // "Dynamic Range Reduction Inspired by Photoreceptor Physiology", Reinhard, Devlin, 2005
...@@ -144,6 +152,19 @@ public: ...@@ -144,6 +152,19 @@ public:
CV_EXPORTS_W Ptr<TonemapReinhardDevlin> CV_EXPORTS_W Ptr<TonemapReinhardDevlin>
createTonemapReinhardDevlin(float gamma = 1.0f, float intensity = 0.0f, float light_adapt = 1.0f, float color_adapt = 0.0f); 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 class CV_EXPORTS_W ExposureAlign : public Algorithm
{ {
public: public:
......
...@@ -71,4 +71,16 @@ Mat tringleWeights() ...@@ -71,4 +71,16 @@ Mat tringleWeights()
return w; 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); ...@@ -53,6 +53,8 @@ void checkImageDimensions(const std::vector<Mat>& images);
Mat tringleWeights(); Mat tringleWeights();
void mapLuminance(Mat src, Mat dst, Mat lum, Mat new_lum, float saturation);
}; };
#endif #endif
\ No newline at end of file
...@@ -109,7 +109,7 @@ public: ...@@ -109,7 +109,7 @@ public:
Mat response(256, 3, CV_32F); Mat response(256, 3, CV_32F);
for(int i = 0; i < 256; i++) { for(int i = 0; i < 256; i++) {
for(int j = 0; j < 3; j++) { 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); process(src, dst, times, response);
......
This diff is collapsed.
...@@ -91,12 +91,11 @@ void loadResponseCSV(String path, Mat& response) ...@@ -91,12 +91,11 @@ void loadResponseCSV(String path, Mat& response)
TEST(Photo_Tonemap, regression) 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; Mat img, expected, result;
loadImage(test_path + "rle.hdr", img); loadImage(test_path + "image.hdr", img);
float gamma = 2.2f; float gamma = 2.2f;
test_path += "tonemap/";
Ptr<TonemapLinear> linear = createTonemapLinear(gamma); Ptr<TonemapLinear> linear = createTonemapLinear(gamma);
linear->process(img, result); linear->process(img, result);
...@@ -121,6 +120,12 @@ TEST(Photo_Tonemap, regression) ...@@ -121,6 +120,12 @@ TEST(Photo_Tonemap, regression)
loadImage(test_path + "reinharddevlin.png", expected); loadImage(test_path + "reinharddevlin.png", expected);
result.convertTo(result, CV_8UC3, 255); result.convertTo(result, CV_8UC3, 255);
checkEqual(result, expected, 0); 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) 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