Commit c9ace388 authored by Fedor Morozov's avatar Fedor Morozov Committed by Alexander Shishkov

Docs updated, added InputArray, fixes for makePtr,...

parent f99be6bd
......@@ -39,4 +39,3 @@
#7 & #8 & #9
\end{bmatrix}
}
......@@ -40,13 +40,13 @@ Explanation
loadExposureSeq(argv[1], images, times);
Firstly we load input images and exposure times from user-defined folder. The folder should contain images and *list.txt* - file that contains file names and inverse exposure times.
For our image sequence the list is following:
.. code-block:: none
.. code-block:: none
memorial00.png 0.03125
memorial01.png 0.0625
memorial01.png 0.0625
...
memorial15.png 1024
......@@ -57,9 +57,9 @@ Explanation
Mat response;
Ptr<CalibrateDebevec> calibrate = createCalibrateDebevec();
calibrate->process(images, response, times);
It is necessary to know camera response function (CRF) for a lot of HDR construction algorithms. We use one of the calibration algorithms to estimate inverse CRF for all 256 pixel values.
3. **Make HDR image**
.. code-block:: cpp
......@@ -67,39 +67,39 @@ Explanation
Mat hdr;
Ptr<MergeDebevec> merge_debevec = createMergeDebevec();
merge_debevec->process(images, hdr, times, response);
We use Debevec's weighting scheme to construct HDR image using response calculated in the previous item.
4. **Tonemap HDR image**
.. code-block:: cpp
Mat ldr;
Ptr<TonemapDurand> tonemap = createTonemapDurand(2.2f);
tonemap->process(hdr, ldr);
Since we want to see our results on common LDR display we have to map our HDR image to 8-bit range preserving most details. It is the main goal of tonemapping methods. We use tonemapper with bilateral filtering and set 2.2 as the value for gamma correction.
5. **Perform exposure fusion**
.. code-block:: cpp
Mat fusion;
Ptr<MergeMertens> merge_mertens = createMergeMertens();
merge_mertens->process(images, fusion);
There is an alternative way to merge our exposures in case when we don't need HDR image. This process is called exposure fusion and produces LDR image that doesn't require gamma correction. It also doesn't use exposure values of the photographs.
6. **Write results**
.. code-block:: cpp
imwrite("fusion.png", fusion * 255);
imwrite("ldr.png", ldr * 255);
imwrite("hdr.hdr", hdr);
Now it's time to look at the results. Note that HDR image can't be stored in one of common image formats, so we save it to Radiance image (.hdr). Also all HDR imaging functions return results in [0, 1] range so we should multiply result by 255.
Results
=======
......@@ -111,7 +111,7 @@ Tonemapped image
:width: 242pt
:alt: Tonemapped image
:align: center
Exposure fusion
------------------
......
......@@ -155,7 +155,7 @@ As always, we would be happy to hear your comments and receive your contribution
:height: 80pt
:width: 80pt
:alt: photo Icon
* :ref:`Table-Of-Content-GPU`
.. tabularcolumns:: m{100pt} m{300pt}
......
......@@ -49,10 +49,10 @@ namespace cv
HdrDecoder::HdrDecoder()
{
m_signature = "#?RGBE";
m_signature_alt = "#?RADIANCE";
file = NULL;
m_type = CV_32FC3;
m_signature = "#?RGBE";
m_signature_alt = "#?RADIANCE";
file = NULL;
m_type = CV_32FC3;
}
HdrDecoder::~HdrDecoder()
......@@ -61,61 +61,61 @@ HdrDecoder::~HdrDecoder()
size_t HdrDecoder::signatureLength() const
{
return m_signature.size() > m_signature_alt.size() ?
m_signature.size() : m_signature_alt.size();
return m_signature.size() > m_signature_alt.size() ?
m_signature.size() : m_signature_alt.size();
}
bool HdrDecoder::readHeader()
{
file = fopen(m_filename.c_str(), "rb");
if(!file) {
return false;
}
RGBE_ReadHeader(file, &m_width, &m_height, NULL);
if(m_width <= 0 || m_height <= 0) {
fclose(file);
file = NULL;
return false;
}
return true;
file = fopen(m_filename.c_str(), "rb");
if(!file) {
return false;
}
RGBE_ReadHeader(file, &m_width, &m_height, NULL);
if(m_width <= 0 || m_height <= 0) {
fclose(file);
file = NULL;
return false;
}
return true;
}
bool HdrDecoder::readData(Mat& _img)
{
Mat img(m_height, m_width, CV_32FC3);
if(!file) {
if(!readHeader()) {
return false;
}
}
RGBE_ReadPixels_RLE(file, const_cast<float*>(img.ptr<float>()), img.cols, img.rows);
fclose(file); file = NULL;
if(_img.depth() == img.depth()) {
img.convertTo(_img, _img.type());
} else {
img.convertTo(_img, _img.type(), 255);
}
return true;
Mat img(m_height, m_width, CV_32FC3);
if(!file) {
if(!readHeader()) {
return false;
}
}
RGBE_ReadPixels_RLE(file, const_cast<float*>(img.ptr<float>()), img.cols, img.rows);
fclose(file); file = NULL;
if(_img.depth() == img.depth()) {
img.convertTo(_img, _img.type());
} else {
img.convertTo(_img, _img.type(), 255);
}
return true;
}
bool HdrDecoder::checkSignature( const String& signature ) const
{
if(signature.size() >= m_signature.size() &&
(!memcmp(signature.c_str(), m_signature.c_str(), m_signature.size()) ||
!memcmp(signature.c_str(), m_signature_alt.c_str(), m_signature_alt.size())))
return true;
return false;
if(signature.size() >= m_signature.size() &&
(!memcmp(signature.c_str(), m_signature.c_str(), m_signature.size()) ||
!memcmp(signature.c_str(), m_signature_alt.c_str(), m_signature_alt.size())))
return true;
return false;
}
ImageDecoder HdrDecoder::newDecoder() const
{
return new HdrDecoder;
return makePtr<HdrDecoder>();
}
HdrEncoder::HdrEncoder()
{
m_description = "Radiance HDR (*.hdr;*.pic)";
m_description = "Radiance HDR (*.hdr;*.pic)";
}
HdrEncoder::~HdrEncoder()
......@@ -124,41 +124,41 @@ HdrEncoder::~HdrEncoder()
bool HdrEncoder::write( const Mat& input_img, const std::vector<int>& params )
{
Mat img;
CV_Assert(input_img.channels() == 3 || input_img.channels() == 1);
if(input_img.channels() == 1) {
std::vector<Mat> splitted(3, input_img);
merge(splitted, img);
} else {
input_img.copyTo(img);
}
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);
FILE *fout = fopen(m_filename.c_str(), "wb");
if(!fout) {
return false;
}
RGBE_WriteHeader(fout, img.cols, img.rows, NULL);
if(params.empty() || params[0] == HDR_RLE) {
RGBE_WritePixels_RLE(fout, const_cast<float*>(img.ptr<float>()), img.cols, img.rows);
} else {
RGBE_WritePixels(fout, const_cast<float*>(img.ptr<float>()), img.cols * img.rows);
}
fclose(fout);
return true;
Mat img;
CV_Assert(input_img.channels() == 3 || input_img.channels() == 1);
if(input_img.channels() == 1) {
std::vector<Mat> splitted(3, input_img);
merge(splitted, img);
} else {
input_img.copyTo(img);
}
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);
FILE *fout = fopen(m_filename.c_str(), "wb");
if(!fout) {
return false;
}
RGBE_WriteHeader(fout, img.cols, img.rows, NULL);
if(params.empty() || params[0] == HDR_RLE) {
RGBE_WritePixels_RLE(fout, const_cast<float*>(img.ptr<float>()), img.cols, img.rows);
} else {
RGBE_WritePixels(fout, const_cast<float*>(img.ptr<float>()), img.cols * img.rows);
}
fclose(fout);
return true;
}
ImageEncoder HdrEncoder::newEncoder() const
{
return new HdrEncoder;
return makePtr<HdrEncoder>();
}
bool HdrEncoder::isFormatSupported( int depth ) const {
return depth != CV_64F;
return depth != CV_64F;
}
}
......@@ -58,29 +58,29 @@ enum HdrCompression
class HdrDecoder : public BaseImageDecoder
{
public:
HdrDecoder();
~HdrDecoder();
bool readHeader();
bool readData( Mat& img );
bool checkSignature( const String& signature ) const;
ImageDecoder newDecoder() const;
size_t signatureLength() const;
HdrDecoder();
~HdrDecoder();
bool readHeader();
bool readData( Mat& img );
bool checkSignature( const String& signature ) const;
ImageDecoder newDecoder() const;
size_t signatureLength() const;
protected:
String m_signature_alt;
FILE *file;
String m_signature_alt;
FILE *file;
};
// ... writer
class HdrEncoder : public BaseImageEncoder
{
public:
HdrEncoder();
~HdrEncoder();
bool write( const Mat& img, const std::vector<int>& params );
ImageEncoder newEncoder() const;
bool isFormatSupported( int depth ) const;
HdrEncoder();
~HdrEncoder();
bool write( const Mat& img, const std::vector<int>& params );
ImageEncoder newEncoder() const;
bool isFormatSupported( int depth ) const;
protected:
};
}
......
......@@ -72,7 +72,7 @@ TiffDecoder::TiffDecoder()
TIFFSetErrorHandler( GrFmtSilentTIFFErrorHandler );
TIFFSetWarningHandler( GrFmtSilentTIFFErrorHandler );
}
m_hdr = false;
m_hdr = false;
}
......@@ -135,13 +135,13 @@ bool TiffDecoder::readHeader()
m_width = wdth;
m_height = hght;
if((bpp == 32 && ncn == 3) || photometric == PHOTOMETRIC_LOGLUV)
{
m_type = CV_32FC3;
m_hdr = true;
return true;
}
m_hdr = false;
if((bpp == 32 && ncn == 3) || photometric == PHOTOMETRIC_LOGLUV)
{
m_type = CV_32FC3;
m_hdr = true;
return true;
}
m_hdr = false;
if( bpp > 8 &&
((photometric != 2 && photometric != 1) ||
......@@ -181,10 +181,10 @@ bool TiffDecoder::readHeader()
bool TiffDecoder::readData( Mat& img )
{
if(m_hdr && img.type() == CV_32FC3)
{
return readHdrData(img);
}
if(m_hdr && img.type() == CV_32FC3)
{
return readHdrData(img);
}
bool result = false;
bool color = img.channels() > 1;
uchar* data = img.data;
......@@ -394,35 +394,35 @@ bool TiffDecoder::readData( Mat& img )
return result;
}
bool TiffDecoder::readHdrData(Mat& img)
bool TiffDecoder::readHdrData(Mat& img)
{
int rows_per_strip = 0, photometric = 0;
if(!m_tif)
{
return false;
}
TIFF *tif = static_cast<TIFF*>(m_tif);
TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rows_per_strip);
int rows_per_strip = 0, photometric = 0;
if(!m_tif)
{
return false;
}
TIFF *tif = static_cast<TIFF*>(m_tif);
TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rows_per_strip);
TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric );
TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_FLOAT);
int size = 3 * m_width * m_height * sizeof (float);
int strip_size = 3 * m_width * rows_per_strip;
float *ptr = img.ptr<float>();
for (size_t i = 0; i < TIFFNumberOfStrips(tif); i++, ptr += strip_size)
{
TIFFReadEncodedStrip(tif, i, ptr, size);
size -= strip_size * sizeof(float);
}
close();
if(photometric == PHOTOMETRIC_LOGLUV)
{
cvtColor(img, img, COLOR_XYZ2BGR);
}
else
{
cvtColor(img, img, COLOR_RGB2BGR);
}
return true;
TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_FLOAT);
int size = 3 * m_width * m_height * sizeof (float);
int strip_size = 3 * m_width * rows_per_strip;
float *ptr = img.ptr<float>();
for (size_t i = 0; i < TIFFNumberOfStrips(tif); i++, ptr += strip_size)
{
TIFFReadEncodedStrip(tif, i, ptr, size);
size -= strip_size * sizeof(float);
}
close();
if(photometric == PHOTOMETRIC_LOGLUV)
{
cvtColor(img, img, COLOR_XYZ2BGR);
}
else
{
cvtColor(img, img, COLOR_RGB2BGR);
}
return true;
}
#endif
......@@ -452,8 +452,8 @@ bool TiffEncoder::isFormatSupported( int depth ) const
{
#ifdef HAVE_TIFF
return depth == CV_8U || depth == CV_16U || depth == CV_32F;
#else
return depth == CV_8U || depth == CV_16U;
#else
return depth == CV_8U || depth == CV_16U;
#endif
}
......@@ -608,29 +608,29 @@ bool TiffEncoder::writeLibTiff( const Mat& img, const std::vector<int>& params)
bool TiffEncoder::writeHdr(const Mat& _img)
{
Mat img;
cvtColor(_img, img, COLOR_BGR2XYZ);
TIFF* tif = TIFFOpen(m_filename.c_str(), "w");
if (!tif)
{
Mat img;
cvtColor(_img, img, COLOR_BGR2XYZ);
TIFF* tif = TIFFOpen(m_filename.c_str(), "w");
if (!tif)
{
return false;
}
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, img.cols);
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, img.rows);
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_SGILOG);
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_LOGLUV);
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_FLOAT);
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
int strip_size = 3 * img.cols;
float *ptr = const_cast<float*>(img.ptr<float>());
for (int i = 0; i < img.rows; i++, ptr += strip_size)
{
TIFFWriteEncodedStrip(tif, i, ptr, strip_size * sizeof(float));
}
TIFFClose(tif);
return true;
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, img.cols);
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, img.rows);
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_SGILOG);
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_LOGLUV);
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_FLOAT);
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
int strip_size = 3 * img.cols;
float *ptr = const_cast<float*>(img.ptr<float>());
for (int i = 0; i < img.rows; i++, ptr += strip_size)
{
TIFFWriteEncodedStrip(tif, i, ptr, strip_size * sizeof(float));
}
TIFFClose(tif);
return true;
}
#endif
......@@ -645,10 +645,10 @@ bool TiffEncoder::write( const Mat& img, const std::vector<int>& /*params*/)
int width = img.cols, height = img.rows;
int depth = img.depth();
#ifdef HAVE_TIFF
if(img.type() == CV_32FC3)
{
return writeHdr(img);
}
if(img.type() == CV_32FC3)
{
return writeHdr(img);
}
#endif
if (depth != CV_8U && depth != CV_16U)
......
......@@ -108,8 +108,8 @@ public:
protected:
void* m_tif;
int normalizeChannelsNumber(int channels) const;
bool readHdrData(Mat& img);
bool m_hdr;
bool readHdrData(Mat& img);
bool m_hdr;
};
#endif
......@@ -132,7 +132,7 @@ protected:
int count, int value );
bool writeLibTiff( const Mat& img, const std::vector<int>& params );
bool writeHdr( const Mat& img );
bool writeHdr( const Mat& img );
};
}
......
......@@ -59,15 +59,10 @@ struct ImageCodecInitializer
{
ImageCodecInitializer()
{
<<<<<<< HEAD
decoders.push_back( new BmpDecoder );
encoders.push_back( new BmpEncoder );
decoders.push_back( new HdrDecoder );
encoders.push_back( new HdrEncoder );
=======
decoders.push_back( makePtr<BmpDecoder>() );
encoders.push_back( makePtr<BmpEncoder>() );
>>>>>>> 99a43257d5912ff215016e1cf5f4e0c2a934b72f
decoders.push_back( makePtr<HdrDecoder>() );
encoders.push_back( makePtr<HdrEncoder>() );
#ifdef HAVE_JPEG
decoders.push_back( makePtr<JpegDecoder>() );
encoders.push_back( makePtr<JpegEncoder>() );
......
This diff is collapsed.
......@@ -51,13 +51,13 @@
typedef struct {
int valid; /* indicate which fields are valid */
char programtype[16]; /* listed at beginning of file to identify it
* after "#?". defaults to "RGBE" */
float gamma; /* image has already been gamma corrected with
char programtype[16]; /* listed at beginning of file to identify it
* after "#?". defaults to "RGBE" */
float gamma; /* image has already been gamma corrected with
* given gamma. defaults to 1.0 (no correction) */
float exposure; /* a value of 1.0 in an image corresponds to
* <exposure> watts/steradian/m^2.
* defaults to 1.0 */
* <exposure> watts/steradian/m^2.
* defaults to 1.0 */
} rgbe_header_info;
/* flags indicating which fields in an rgbe_header_info are valid */
......@@ -82,11 +82,8 @@ int RGBE_ReadPixels(FILE *fp, float *data, int numpixels);
/* read or write run length encoded files */
/* must be called to read or write whole scanlines */
int RGBE_WritePixels_RLE(FILE *fp, float *data, int scanline_width,
int num_scanlines);
int num_scanlines);
int RGBE_ReadPixels_RLE(FILE *fp, float *data, int scanline_width,
int num_scanlines);
int num_scanlines);
#endif/*_RGBE_HDR_H_*/
......@@ -479,11 +479,7 @@ TEST(Highgui_WebP, encode_decode_lossless_webp)
TEST(Highgui_WebP, encode_decode_lossy_webp)
{
cvtest::TS& ts = *cvtest::TS::ptr();
<<<<<<< HEAD
string input = string(ts.get_data_path()) + "/../cv/shared/lena.png";
=======
std::string input = std::string(ts.get_data_path()) + "../cv/shared/lena.png";
>>>>>>> 99a43257d5912ff215016e1cf5f4e0c2a934b72f
cv::Mat img = cv::imread(input);
ASSERT_FALSE(img.empty());
......@@ -533,24 +529,24 @@ TEST(Highgui_WebP, encode_decode_with_alpha_webp)
TEST(Highgui_Hdr, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "/readwrite/";
string name_rle = folder + "rle.hdr";
string name_no_rle = folder + "no_rle.hdr";
Mat img_rle = imread(name_rle, -1);
ASSERT_FALSE(img_rle.empty()) << "Could not open " << name_rle;
Mat img_no_rle = imread(name_no_rle, -1);
ASSERT_FALSE(img_no_rle.empty()) << "Could not open " << name_no_rle;
double min = 0.0, max = 1.0;
minMaxLoc(abs(img_rle - img_no_rle), &min, &max);
string name_rle = folder + "rle.hdr";
string name_no_rle = folder + "no_rle.hdr";
Mat img_rle = imread(name_rle, -1);
ASSERT_FALSE(img_rle.empty()) << "Could not open " << name_rle;
Mat img_no_rle = imread(name_no_rle, -1);
ASSERT_FALSE(img_no_rle.empty()) << "Could not open " << name_no_rle;
double min = 0.0, max = 1.0;
minMaxLoc(abs(img_rle - img_no_rle), &min, &max);
ASSERT_FALSE(max > DBL_EPSILON);
string tmp_file_name = tempfile(".hdr");
vector<int>param(1);
for(int i = 0; i < 2; i++) {
param[0] = i;
imwrite(tmp_file_name, img_rle, param);
Mat written_img = imread(tmp_file_name, -1);
ASSERT_FALSE(written_img.empty()) << "Could not open " << tmp_file_name;
minMaxLoc(abs(img_rle - written_img), &min, &max);
string tmp_file_name = tempfile(".hdr");
vector<int>param(1);
for(int i = 0; i < 2; i++) {
param[0] = i;
imwrite(tmp_file_name, img_rle, param);
Mat written_img = imread(tmp_file_name, -1);
ASSERT_FALSE(written_img.empty()) << "Could not open " << tmp_file_name;
minMaxLoc(abs(img_rle - written_img), &min, &max);
ASSERT_FALSE(max > DBL_EPSILON);
}
}
}
This diff is collapsed.
......@@ -127,12 +127,12 @@ public:
CV_WRAP virtual void setSigmaColor(float sigma_color) = 0;
};
CV_EXPORTS_W Ptr<TonemapDurand>
CV_EXPORTS_W Ptr<TonemapDurand>
createTonemapDurand(float gamma = 1.0f, float contrast = 4.0f, float saturation = 1.0f, float sigma_space = 2.0f, float sigma_color = 2.0f);
// "Dynamic Range Reduction Inspired by Photoreceptor Physiology", Reinhard, Devlin, 2005
class CV_EXPORTS_W TonemapReinhardDevlin : public Tonemap
class CV_EXPORTS_W TonemapReinhard : public Tonemap
{
public:
CV_WRAP virtual float getIntensity() const = 0;
......@@ -145,8 +145,8 @@ public:
CV_WRAP virtual void setColorAdaptation(float color_adapt) = 0;
};
CV_EXPORTS_W Ptr<TonemapReinhardDevlin>
createTonemapReinhardDevlin(float gamma = 1.0f, float intensity = 0.0f, float light_adapt = 1.0f, float color_adapt = 0.0f);
CV_EXPORTS_W Ptr<TonemapReinhard>
createTonemapReinhard(float gamma = 1.0f, float intensity = 0.0f, float light_adapt = 1.0f, float color_adapt = 0.0f);
// "Perceptual Framework for Contrast Processing of High Dynamic Range Images", Mantiuk et al., 2006
......@@ -160,29 +160,29 @@ public:
CV_WRAP virtual void setSaturation(float saturation) = 0;
};
CV_EXPORTS_W Ptr<TonemapMantiuk>
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 AlignExposures : public Algorithm
{
public:
CV_WRAP virtual void process(InputArrayOfArrays src, std::vector<Mat>& dst,
const std::vector<float>& times, InputArray response) = 0;
InputArray times, InputArray response) = 0;
};
// "Fast, Robust Image Registration for Compositing High Dynamic Range Photographs from Handheld Exposures", Ward, 2003
class CV_EXPORTS_W AlignMTB : public ExposureAlign
class CV_EXPORTS_W AlignMTB : public AlignExposures
{
public:
CV_WRAP virtual void process(InputArrayOfArrays src, std::vector<Mat>& dst,
const std::vector<float>& times, InputArray response) = 0;
InputArray times, InputArray response) = 0;
CV_WRAP virtual void process(InputArrayOfArrays src, std::vector<Mat>& dst) = 0;
CV_WRAP virtual void calculateShift(InputArray img0, InputArray img1, Point& shift) = 0;
CV_WRAP virtual Point calculateShift(InputArray img0, InputArray img1) = 0;
CV_WRAP virtual void shiftMat(InputArray src, OutputArray dst, const Point shift) = 0;
CV_WRAP virtual void computeBitmaps(Mat& img, Mat& tb, Mat& eb) = 0;
CV_WRAP virtual void computeBitmaps(InputArray img, OutputArray tb, OutputArray eb) = 0;
CV_WRAP virtual int getMaxBits() const = 0;
CV_WRAP virtual void setMaxBits(int max_bits) = 0;
......@@ -196,20 +196,20 @@ public:
CV_EXPORTS_W Ptr<AlignMTB> createAlignMTB(int max_bits = 6, int exclude_range = 4, bool cut = true);
class CV_EXPORTS_W ExposureCalibrate : public Algorithm
class CV_EXPORTS_W CalibrateCRF : public Algorithm
{
public:
CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst, std::vector<float>& times) = 0;
CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst, InputArray times) = 0;
};
// "Recovering High Dynamic Range Radiance Maps from Photographs", Debevec, Malik, 1997
class CV_EXPORTS_W CalibrateDebevec : public ExposureCalibrate
class CV_EXPORTS_W CalibrateDebevec : public CalibrateCRF
{
public:
CV_WRAP virtual float getLambda() const = 0;
CV_WRAP virtual void setLambda(float lambda) = 0;
CV_WRAP virtual int getSamples() const = 0;
CV_WRAP virtual void setSamples(int samples) = 0;
......@@ -221,46 +221,46 @@ CV_EXPORTS_W Ptr<CalibrateDebevec> createCalibrateDebevec(int samples = 70, floa
// "Dynamic range improvement through multiple exposures", Robertson et al., 1999
class CV_EXPORTS_W CalibrateRobertson : public ExposureCalibrate
class CV_EXPORTS_W CalibrateRobertson : public CalibrateCRF
{
public:
CV_WRAP virtual int getMaxIter() const = 0;
CV_WRAP virtual void setMaxIter(int max_iter) = 0;
CV_WRAP virtual float getThreshold() const = 0;
CV_WRAP virtual void setThreshold(float threshold) = 0;
CV_WRAP virtual Mat getRadiance() const = 0;
};
CV_EXPORTS_W Ptr<CalibrateRobertson> createCalibrateRobertson(int max_iter = 30, float threshold = 0.01f);
class CV_EXPORTS_W ExposureMerge : public Algorithm
class CV_EXPORTS_W MergeExposures : public Algorithm
{
public:
CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst,
const std::vector<float>& times, InputArray response) = 0;
InputArray times, InputArray response) = 0;
};
// "Recovering High Dynamic Range Radiance Maps from Photographs", Debevec, Malik, 1997
class CV_EXPORTS_W MergeDebevec : public ExposureMerge
class CV_EXPORTS_W MergeDebevec : public MergeExposures
{
public:
CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst,
const std::vector<float>& times, InputArray response) = 0;
CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst, const std::vector<float>& times) = 0;
InputArray times, InputArray response) = 0;
CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst, InputArray times) = 0;
};
CV_EXPORTS_W Ptr<MergeDebevec> createMergeDebevec();
// "Exposure Fusion", Mertens et al., 2007
class CV_EXPORTS_W MergeMertens : public ExposureMerge
class CV_EXPORTS_W MergeMertens : public MergeExposures
{
public:
CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst,
const std::vector<float>& times, InputArray response) = 0;
InputArray times, InputArray response) = 0;
CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst) = 0;
CV_WRAP virtual float getContrastWeight() const = 0;
......@@ -273,17 +273,17 @@ public:
CV_WRAP virtual void setExposureWeight(float exposure_weight) = 0;
};
CV_EXPORTS_W Ptr<MergeMertens>
CV_EXPORTS_W Ptr<MergeMertens>
createMergeMertens(float contrast_weight = 1.0f, float saturation_weight = 1.0f, float exposure_weight = 0.0f);
// "Dynamic range improvement through multiple exposures", Robertson et al., 1999
class CV_EXPORTS_W MergeRobertson : public ExposureMerge
class CV_EXPORTS_W MergeRobertson : public MergeExposures
{
public:
CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst,
const std::vector<float>& times, InputArray response) = 0;
CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst, const std::vector<float>& times) = 0;
InputArray times, InputArray response) = 0;
CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst, InputArray times) = 0;
};
CV_EXPORTS_W Ptr<MergeRobertson> createMergeRobertson();
......
......@@ -50,16 +50,16 @@ namespace cv
class AlignMTBImpl : public AlignMTB
{
public:
AlignMTBImpl(int max_bits, int exclude_range, bool cut) :
max_bits(max_bits),
exclude_range(exclude_range),
cut(cut),
name("AlignMTB")
AlignMTBImpl(int _max_bits, int _exclude_range, bool _cut) :
name("AlignMTB"),
max_bits(_max_bits),
exclude_range(_exclude_range),
cut(_cut)
{
}
void process(InputArrayOfArrays src, std::vector<Mat>& dst,
const std::vector<float>& times, InputArray response)
InputArray, InputArray)
{
process(src, dst);
}
......@@ -68,7 +68,7 @@ public:
{
std::vector<Mat> src;
_src.getMatVector(src);
checkImageDimensions(src);
dst.resize(src.size());
......@@ -85,8 +85,7 @@ public:
}
Mat gray;
cvtColor(src[i], gray, COLOR_RGB2GRAY);
Point shift;
calculateShift(gray_base, gray, shift);
Point shift = calculateShift(gray_base, gray);
shifts.push_back(shift);
shiftMat(src[i], dst[i], shift);
}
......@@ -113,7 +112,7 @@ public:
}
}
void calculateShift(InputArray _img0, InputArray _img1, Point& shift)
Point calculateShift(InputArray _img0, InputArray _img1)
{
Mat img0 = _img0.getMat();
Mat img1 = _img1.getMat();
......@@ -126,11 +125,11 @@ public:
std::vector<Mat> pyr0;
std::vector<Mat> pyr1;
buildPyr(img0, pyr0, maxlevel);
buildPyr(img1, pyr1, maxlevel);
shift = Point(0, 0);
buildPyr(img1, pyr1, maxlevel);
Point shift(0, 0);
for(int level = maxlevel; level >= 0; level--) {
shift *= 2;
Mat tb1, tb2, eb1, eb2;
computeBitmaps(pyr0[level], tb1, eb1);
......@@ -151,14 +150,15 @@ public:
if(err < min_err) {
new_shift = test_shift;
min_err = err;
}
}
}
}
shift = new_shift;
}
return shift;
}
void shiftMat(InputArray _src, OutputArray _dst, const Point shift)
void shiftMat(InputArray _src, OutputArray _dst, const Point shift)
{
Mat src = _src.getMat();
_dst.create(src.size(), src.type());
......@@ -186,7 +186,7 @@ public:
{
fs << "name" << name
<< "max_bits" << max_bits
<< "exclude_range" << exclude_range
<< "exclude_range" << exclude_range
<< "cut" << static_cast<int>(cut);
}
......@@ -197,11 +197,15 @@ public:
max_bits = fn["max_bits"];
exclude_range = fn["exclude_range"];
int cut_val = fn["cut"];
cut = static_cast<bool>(cut_val);
cut = (cut_val != 0);
}
void computeBitmaps(Mat& img, Mat& tb, Mat& eb)
void computeBitmaps(InputArray _img, OutputArray _tb, OutputArray _eb)
{
Mat img = _img.getMat();
_tb.create(img.size(), CV_8U);
_eb.create(img.size(), CV_8U);
Mat tb = _tb.getMat(), eb = _eb.getMat();
int median = getMedian(img);
compare(img, median, tb, CMP_GT);
compare(abs(img - median), exclude_range, eb, CMP_GT);
......@@ -230,7 +234,7 @@ protected:
}
}
void buildPyr(Mat& img, std::vector<Mat>& pyr, int maxlevel)
void buildPyr(Mat& img, std::vector<Mat>& pyr, int maxlevel)
{
pyr.resize(maxlevel + 1);
pyr[0] = img.clone();
......@@ -242,7 +246,7 @@ protected:
int getMedian(Mat& img)
{
int channels = 0;
Mat hist;
Mat hist;
int hist_size = LDR_SIZE;
float range[] = {0, LDR_SIZE} ;
const float* ranges[] = {range};
......@@ -260,8 +264,7 @@ protected:
Ptr<AlignMTB> createAlignMTB(int max_bits, int exclude_range, bool cut)
{
return new AlignMTBImpl(max_bits, exclude_range, cut);
return makePtr<AlignMTBImpl>(max_bits, exclude_range, cut);
}
}
......@@ -48,25 +48,26 @@
namespace cv
{
class CalibrateDebevecImpl : public CalibrateDebevec
{
public:
CalibrateDebevecImpl(int samples, float lambda, bool random) :
samples(samples),
lambda(lambda),
CalibrateDebevecImpl(int _samples, float _lambda, bool _random) :
name("CalibrateDebevec"),
w(tringleWeights()),
random(random)
samples(_samples),
lambda(_lambda),
random(_random),
w(tringleWeights())
{
}
void process(InputArrayOfArrays src, OutputArray dst, std::vector<float>& times)
void process(InputArrayOfArrays src, OutputArray dst, InputArray _times)
{
std::vector<Mat> images;
src.getMatVector(images);
Mat times = _times.getMat();
CV_Assert(images.size() == times.size());
CV_Assert(images.size() == times.total());
checkImageDimensions(images);
CV_Assert(images[0].depth() == CV_8U);
......@@ -75,14 +76,14 @@ public:
dst.create(LDR_SIZE, 1, CV_32FCC);
Mat result = dst.getMat();
std::vector<Point> sample_points;
if(random) {
for(int i = 0; i < samples; i++) {
sample_points.push_back(Point(rand() % images[0].cols, rand() % images[0].rows));
}
} else {
int x_points = sqrt(static_cast<double>(samples) * images[0].cols / images[0].rows);
int x_points = static_cast<int>(sqrt(static_cast<double>(samples) * images[0].cols / images[0].rows));
int y_points = samples / x_points;
int step_x = images[0].cols / x_points;
int step_y = images[0].rows / y_points;
......@@ -106,7 +107,7 @@ public:
int val = images[j].ptr()[3*(sample_points[i].y * images[j].cols + sample_points[j].x) + channel];
A.at<float>(eq, val) = w.at<float>(val);
A.at<float>(eq, LDR_SIZE + i) = -w.at<float>(val);
B.at<float>(eq, 0) = w.at<float>(val) * log(times[j]);
B.at<float>(eq, 0) = w.at<float>(val) * log(times.at<float>(j));
eq++;
}
}
......@@ -151,7 +152,7 @@ public:
samples = fn["samples"];
lambda = fn["lambda"];
int random_val = fn["random"];
random = static_cast<bool>(random_val);
random = (random_val != 0);
}
protected:
......@@ -164,26 +165,27 @@ protected:
Ptr<CalibrateDebevec> createCalibrateDebevec(int samples, float lambda, bool random)
{
return new CalibrateDebevecImpl(samples, lambda, random);
return makePtr<CalibrateDebevecImpl>(samples, lambda, random);
}
class CalibrateRobertsonImpl : public CalibrateRobertson
{
public:
CalibrateRobertsonImpl(int max_iter, float threshold) :
max_iter(max_iter),
threshold(threshold),
CalibrateRobertsonImpl(int _max_iter, float _threshold) :
name("CalibrateRobertson"),
max_iter(_max_iter),
threshold(_threshold),
weight(RobertsonWeights())
{
}
void process(InputArrayOfArrays src, OutputArray dst, std::vector<float>& times)
void process(InputArrayOfArrays src, OutputArray dst, InputArray _times)
{
std::vector<Mat> images;
src.getMatVector(images);
Mat times = _times.getMat();
CV_Assert(images.size() == times.size());
CV_Assert(images.size() == times.total());
checkImageDimensions(images);
CV_Assert(images[0].depth() == CV_8U);
......@@ -205,7 +207,7 @@ public:
}
card = 1.0 / card;
Ptr<MergeRobertson> merge = createMergeRobertson();
Ptr<MergeRobertson> merge = createMergeRobertson();
for(int iter = 0; iter < max_iter; iter++) {
radiance = Mat::zeros(images[0].size(), CV_32FCC);
......@@ -217,7 +219,7 @@ public:
float* rad_ptr = radiance.ptr<float>();
for(size_t pos = 0; pos < images[i].total(); pos++) {
for(int c = 0; c < channels; c++, ptr++, rad_ptr++) {
new_response.at<Vec3f>(*ptr)[c] += times[i] * *rad_ptr;
new_response.at<Vec3f>(*ptr)[c] += times.at<float>(i) * *rad_ptr;
}
}
}
......@@ -228,7 +230,7 @@ public:
new_response.at<Vec3f>(i)[c] /= middle;
}
}
float diff = sum(sum(abs(new_response - response)))[0] / channels;
float diff = static_cast<float>(sum(sum(abs(new_response - response)))[0] / channels);
new_response.copyTo(response);
if(diff < threshold) {
break;
......@@ -268,7 +270,7 @@ protected:
Ptr<CalibrateRobertson> createCalibrateRobertson(int max_iter, float threshold)
{
return new CalibrateRobertsonImpl(max_iter, threshold);
return makePtr<CalibrateRobertsonImpl>(max_iter, threshold);
}
}
\ No newline at end of file
}
......@@ -97,7 +97,7 @@ Mat linearResponse(int channels)
{
Mat response = Mat(LDR_SIZE, 1, CV_MAKETYPE(CV_32F, channels));
for(int i = 0; i < LDR_SIZE; i++) {
response.at<Vec3f>(i) = Vec3f::all(i);
response.at<Vec3f>(i) = Vec3f::all(static_cast<float>(i));
}
return response;
}
......
......@@ -55,13 +55,14 @@ public:
weights(tringleWeights())
{
}
void process(InputArrayOfArrays src, OutputArray dst, const std::vector<float>& times, InputArray input_response)
void process(InputArrayOfArrays src, OutputArray dst, InputArray _times, InputArray input_response)
{
std::vector<Mat> images;
src.getMatVector(images);
Mat times = _times.getMat();
CV_Assert(images.size() == times.size());
CV_Assert(images.size() == times.total());
checkImageDimensions(images);
CV_Assert(images[0].depth() == CV_8U);
......@@ -79,12 +80,12 @@ public:
response.at<Vec3f>(0) = response.at<Vec3f>(1);
}
log(response, response);
CV_Assert(response.rows == LDR_SIZE && response.cols == 1 &&
CV_Assert(response.rows == LDR_SIZE && response.cols == 1 &&
response.channels() == channels);
Mat exp_values(times);
log(exp_values, exp_values);
result = Mat::zeros(size, CV_32FCC);
std::vector<Mat> result_split;
split(result, result_split);
......@@ -117,7 +118,7 @@ public:
exp(result, result);
}
void process(InputArrayOfArrays src, OutputArray dst, const std::vector<float>& times)
void process(InputArrayOfArrays src, OutputArray dst, InputArray times)
{
process(src, dst, times, Mat());
}
......@@ -129,21 +130,21 @@ protected:
Ptr<MergeDebevec> createMergeDebevec()
{
return new MergeDebevecImpl;
return makePtr<MergeDebevecImpl>();
}
class MergeMertensImpl : public MergeMertens
{
public:
MergeMertensImpl(float wcon, float wsat, float wexp) :
wcon(wcon),
wsat(wsat),
wexp(wexp),
name("MergeMertens")
MergeMertensImpl(float _wcon, float _wsat, float _wexp) :
name("MergeMertens"),
wcon(_wcon),
wsat(_wsat),
wexp(_wexp)
{
}
void process(InputArrayOfArrays src, OutputArrayOfArrays dst, const std::vector<float>& times, InputArray response)
void process(InputArrayOfArrays src, OutputArrayOfArrays dst, InputArray, InputArray)
{
process(src, dst);
}
......@@ -217,7 +218,7 @@ public:
weights[i] /= weight_sum;
Mat img;
images[i].convertTo(img, CV_32F, 1.0f/255.0f);
std::vector<Mat> img_pyr, weight_pyr;
buildPyramid(img, img_pyr, maxlevel);
buildPyramid(weights[i], weight_pyr, maxlevel);
......@@ -283,7 +284,7 @@ protected:
Ptr<MergeMertens> createMergeMertens(float wcon, float wsat, float wexp)
{
return new MergeMertensImpl(wcon, wsat, wexp);
return makePtr<MergeMertensImpl>(wcon, wsat, wexp);
}
class MergeRobertsonImpl : public MergeRobertson
......@@ -294,13 +295,14 @@ public:
weight(RobertsonWeights())
{
}
void process(InputArrayOfArrays src, OutputArray dst, const std::vector<float>& times, InputArray input_response)
void process(InputArrayOfArrays src, OutputArray dst, InputArray _times, InputArray input_response)
{
std::vector<Mat> images;
src.getMatVector(images);
Mat times = _times.getMat();
CV_Assert(images.size() == times.size());
CV_Assert(images.size() == times.total());
checkImageDimensions(images);
CV_Assert(images[0].depth() == CV_8U);
......@@ -312,11 +314,12 @@ public:
Mat response = input_response.getMat();
if(response.empty()) {
response = linearResponse(channels) / (LDR_SIZE / 2.0f);
float middle = LDR_SIZE / 2.0f;
response = linearResponse(channels) / middle;
}
CV_Assert(response.rows == LDR_SIZE && response.cols == 1 &&
CV_Assert(response.rows == LDR_SIZE && response.cols == 1 &&
response.channels() == channels);
result = Mat::zeros(images[0].size(), CV_32FCC);
Mat wsum = Mat::zeros(images[0].size(), CV_32FCC);
for(size_t i = 0; i < images.size(); i++) {
......@@ -324,13 +327,13 @@ public:
LUT(images[i], weight, w);
LUT(images[i], response, im);
result += times[i] * w.mul(im);
wsum += pow(times[i], 2) * w;
result += times.at<float>(i) * w.mul(im);
wsum += times.at<float>(i) * times.at<float>(i) * w;
}
result = result.mul(1 / wsum);
}
void process(InputArrayOfArrays src, OutputArray dst, const std::vector<float>& times)
void process(InputArrayOfArrays src, OutputArray dst, InputArray times)
{
process(src, dst, times, Mat());
}
......@@ -342,7 +345,7 @@ protected:
Ptr<MergeRobertson> createMergeRobertson()
{
return new MergeRobertsonImpl;
return makePtr<MergeRobertsonImpl>();
}
}
......@@ -50,17 +50,17 @@ namespace cv
class TonemapImpl : public Tonemap
{
public:
TonemapImpl(float gamma) : gamma(gamma), name("Tonemap")
TonemapImpl(float _gamma) : name("Tonemap"), gamma(_gamma)
{
}
void process(InputArray _src, OutputArray _dst)
void process(InputArray _src, OutputArray _dst)
{
Mat src = _src.getMat();
CV_Assert(!src.empty());
_dst.create(src.size(), CV_32FC3);
Mat dst = _dst.getMat();
double min, max;
minMaxLoc(src, &min, &max);
if(max - min > DBL_EPSILON) {
......@@ -95,27 +95,27 @@ protected:
Ptr<Tonemap> createTonemap(float gamma)
{
return new TonemapImpl(gamma);
return makePtr<TonemapImpl>(gamma);
}
class TonemapDragoImpl : public TonemapDrago
{
public:
TonemapDragoImpl(float gamma, float saturation, float bias) :
gamma(gamma),
saturation(saturation),
bias(bias),
name("TonemapDrago")
TonemapDragoImpl(float _gamma, float _saturation, float _bias) :
name("TonemapDrago"),
gamma(_gamma),
saturation(_saturation),
bias(_bias)
{
}
void process(InputArray _src, OutputArray _dst)
void process(InputArray _src, OutputArray _dst)
{
Mat src = _src.getMat();
CV_Assert(!src.empty());
_dst.create(src.size(), CV_32FC3);
Mat img = _dst.getMat();
Ptr<Tonemap> linear = createTonemap(1.0f);
linear->process(src, img);
......@@ -139,7 +139,7 @@ public:
div.release();
mapLuminance(img, img, gray_img, map, saturation);
linear->setGamma(gamma);
linear->process(img, img);
}
......@@ -177,23 +177,23 @@ protected:
Ptr<TonemapDrago> createTonemapDrago(float gamma, float saturation, float bias)
{
return new TonemapDragoImpl(gamma, saturation, bias);
return makePtr<TonemapDragoImpl>(gamma, saturation, bias);
}
class TonemapDurandImpl : public TonemapDurand
{
public:
TonemapDurandImpl(float gamma, float contrast, float saturation, float sigma_color, float sigma_space) :
gamma(gamma),
contrast(contrast),
saturation(saturation),
sigma_color(sigma_color),
sigma_space(sigma_space),
name("TonemapDurand")
TonemapDurandImpl(float _gamma, float _contrast, float _saturation, float _sigma_color, float _sigma_space) :
name("TonemapDurand"),
gamma(_gamma),
contrast(_contrast),
saturation(_saturation),
sigma_color(_sigma_color),
sigma_space(_sigma_space)
{
}
void process(InputArray _src, OutputArray _dst)
void process(InputArray _src, OutputArray _dst)
{
Mat src = _src.getMat();
CV_Assert(!src.empty());
......@@ -208,7 +208,7 @@ public:
log(gray_img, log_img);
Mat map_img;
bilateralFilter(log_img, map_img, -1, sigma_color, sigma_space);
double min, max;
minMaxLoc(map_img, &min, &max);
float scale = contrast / static_cast<float>(max - min);
......@@ -238,8 +238,8 @@ public:
{
fs << "name" << name
<< "gamma" << gamma
<< "contrast" << contrast
<< "sigma_color" << sigma_color
<< "contrast" << contrast
<< "sigma_color" << sigma_color
<< "sigma_space" << sigma_space
<< "saturation" << saturation;
}
......@@ -257,23 +257,23 @@ public:
protected:
String name;
float gamma, saturation, contrast, sigma_color, sigma_space;
float gamma, contrast, saturation, sigma_color, sigma_space;
};
Ptr<TonemapDurand> createTonemapDurand(float gamma, float contrast, float saturation, float sigma_color, float sigma_space)
{
return new TonemapDurandImpl(gamma, contrast, saturation, sigma_color, sigma_space);
return makePtr<TonemapDurandImpl>(gamma, contrast, saturation, sigma_color, sigma_space);
}
class TonemapReinhardDevlinImpl : public TonemapReinhardDevlin
class TonemapReinhardImpl : public TonemapReinhard
{
public:
TonemapReinhardDevlinImpl(float gamma, float intensity, float light_adapt, float color_adapt) :
gamma(gamma),
intensity(intensity),
light_adapt(light_adapt),
color_adapt(color_adapt),
name("TonemapReinhardDevlin")
TonemapReinhardImpl(float _gamma, float _intensity, float _light_adapt, float _color_adapt) :
name("TonemapReinhard"),
gamma(_gamma),
intensity(_intensity),
light_adapt(_light_adapt),
color_adapt(_color_adapt)
{
}
......@@ -285,7 +285,7 @@ public:
Mat img = _dst.getMat();
Ptr<Tonemap> linear = createTonemap(1.0f);
linear->process(src, img);
Mat gray_img;
cvtColor(img, gray_img, COLOR_RGB2GRAY);
Mat log_img;
......@@ -310,11 +310,11 @@ public:
Mat adapt = color_adapt * channels[i] + (1.0f - color_adapt) * gray_img;
adapt = light_adapt * adapt + (1.0f - light_adapt) * global;
pow(intensity * adapt, map_key, adapt);
channels[i] = channels[i].mul(1.0f / (adapt + channels[i]));
channels[i] = channels[i].mul(1.0f / (adapt + channels[i]));
}
gray_img.release();
merge(channels, img);
linear->setGamma(gamma);
linear->process(img, img);
}
......@@ -335,8 +335,8 @@ public:
{
fs << "name" << name
<< "gamma" << gamma
<< "intensity" << intensity
<< "light_adapt" << light_adapt
<< "intensity" << intensity
<< "light_adapt" << light_adapt
<< "color_adapt" << color_adapt;
}
......@@ -355,23 +355,23 @@ protected:
float gamma, intensity, light_adapt, color_adapt;
};
Ptr<TonemapReinhardDevlin> createTonemapReinhardDevlin(float gamma, float contrast, float sigma_color, float sigma_space)
Ptr<TonemapReinhard> createTonemapReinhard(float gamma, float contrast, float sigma_color, float sigma_space)
{
return new TonemapReinhardDevlinImpl(gamma, contrast, sigma_color, sigma_space);
return makePtr<TonemapReinhardImpl>(gamma, contrast, sigma_color, sigma_space);
}
class TonemapMantiukImpl : public TonemapMantiuk
{
public:
TonemapMantiukImpl(float gamma, float scale, float saturation) :
gamma(gamma),
scale(scale),
saturation(saturation),
name("TonemapMantiuk")
TonemapMantiukImpl(float _gamma, float _scale, float _saturation) :
name("TonemapMantiuk"),
gamma(_gamma),
scale(_scale),
saturation(_saturation)
{
}
void process(InputArray _src, OutputArray _dst)
void process(InputArray _src, OutputArray _dst)
{
Mat src = _src.getMat();
CV_Assert(!src.empty());
......@@ -389,8 +389,8 @@ public:
getContrast(log_img, x_contrast, y_contrast);
for(size_t i = 0; i < x_contrast.size(); i++) {
mapContrast(x_contrast[i], scale);
mapContrast(y_contrast[i], scale);
mapContrast(x_contrast[i]);
mapContrast(y_contrast[i]);
}
Mat right(src.size(), CV_32F);
......@@ -442,7 +442,7 @@ public:
{
fs << "name" << name
<< "gamma" << gamma
<< "scale" << scale
<< "scale" << scale
<< "saturation" << saturation;
}
......@@ -468,7 +468,7 @@ protected:
dst = dst.mul(sign);
}
void mapContrast(Mat& contrast, float scale)
void mapContrast(Mat& contrast)
{
const float response_power = 0.4185f;
signedPow(contrast, response_power, contrast);
......@@ -525,7 +525,7 @@ protected:
Ptr<TonemapMantiuk> createTonemapMantiuk(float gamma, float scale, float saturation)
{
return new TonemapMantiukImpl(gamma, scale, saturation);
return makePtr<TonemapMantiukImpl>(gamma, scale, saturation);
}
}
This diff is collapsed.
......@@ -137,14 +137,16 @@ typedef Ptr<StereoSGBM> Ptr_StereoSGBM;
typedef Ptr<Tonemap> Ptr_Tonemap;
typedef Ptr<TonemapDrago> Ptr_TonemapDrago;
typedef Ptr<TonemapReinhardDevlin> Ptr_TonemapReinhardDevlin;
typedef Ptr<TonemapReinhard> Ptr_TonemapReinhard;
typedef Ptr<TonemapDurand> Ptr_TonemapDurand;
typedef Ptr<TonemapMantiuk> Ptr_TonemapMantiuk;
typedef Ptr<AlignMTB> Ptr_AlignMTB;
typedef Ptr<CalibrateDebevec> Ptr_CalibrateDebevec;
typedef Ptr<CalibrateRobertson> Ptr_CalibrateRobertson;
typedef Ptr<MergeDebevec> Ptr_MergeDebevec;
typedef Ptr<MergeRobertson> Ptr_MergeRobertson;
typedef Ptr<MergeMertens> Ptr_MergeMertens;
typedef Ptr<MergeRobertson> Ptr_MergeRobertson;
typedef Ptr<cv::softcascade::ChannelFeatureBuilder> Ptr_ChannelFeatureBuilder;
typedef Ptr<CLAHE> Ptr_CLAHE;
......
......@@ -7,21 +7,9 @@
using namespace cv;
using namespace std;
void loadExposureSeq(String path, vector<Mat>& images, vector<float>& times)
{
path += "/";
ifstream list_file((path + "list.txt").c_str());
string name;
float val;
while(list_file >> name >> val) {
Mat img = imread(path + name);
images.push_back(img);
times.push_back(1 / val);
}
list_file.close();
}
void loadExposureSeq(String, vector<Mat>&, vector<float>&);
int main(int argc, char**argv)
int main(int, char**argv)
{
vector<Mat> images;
vector<float> times;
......@@ -38,14 +26,28 @@ int main(int argc, char**argv)
Mat ldr;
Ptr<TonemapDurand> tonemap = createTonemapDurand(2.2f);
tonemap->process(hdr, ldr);
Mat fusion;
Mat fusion;
Ptr<MergeMertens> merge_mertens = createMergeMertens();
merge_mertens->process(images, fusion);
imwrite("fusion.png", fusion * 255);
imwrite("ldr.png", ldr * 255);
imwrite("hdr.hdr", hdr);
return 0;
}
\ No newline at end of file
}
void loadExposureSeq(String path, vector<Mat>& images, vector<float>& times)
{
path = path + std::string("/");
ifstream list_file((path + "list.txt").c_str());
string name;
float val;
while(list_file >> name >> val) {
Mat img = imread(path + name);
images.push_back(img);
times.push_back(1 / val);
}
list_file.close();
}
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