diff --git a/modules/photo/include/opencv2/photo.hpp b/modules/photo/include/opencv2/photo.hpp index ca3975f12..f48df802b 100644 --- a/modules/photo/include/opencv2/photo.hpp +++ b/modules/photo/include/opencv2/photo.hpp @@ -288,63 +288,6 @@ public: CV_EXPORTS_W Ptr createMergeRobertson(); -class CV_EXPORTS_W Ghostbuster : public Algorithm -{ -public: - CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst, std::vector& times, Mat response) = 0; -}; - -// "Ghost Detection and Removal in High Dynamic Range Images", Sidibe et al., 2009 - -class CV_EXPORTS_W GhostbusterOrder : public Ghostbuster -{ -public: - CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst, std::vector& times, Mat response) = 0; - CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst) = 0; - - CV_WRAP virtual int getUnderexp() = 0; - CV_WRAP virtual void setUnderexp(int value) = 0; - - CV_WRAP virtual int getOverexp() = 0; - CV_WRAP virtual void setOverexp(int value) = 0; -}; - -CV_EXPORTS_W Ptr createGhostbusterOrder(int underexp = 20, int overexp = 240); - -// "Fast and Robust High Dynamic Range Image Generation with Camera and Object Movement", Grosch, 2006 - -class CV_EXPORTS_W GhostbusterPredict : public Ghostbuster -{ -public: - CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst, std::vector& times, Mat response) = 0; - CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst, std::vector& times) = 0; - - CV_WRAP virtual int getThreshold() = 0; - CV_WRAP virtual void setThreshold(int value) = 0; - - CV_WRAP virtual int getUnderexp() = 0; - CV_WRAP virtual void setUnderexp(int value) = 0; - - CV_WRAP virtual int getOverexp() = 0; - CV_WRAP virtual void setOverexp(int value) = 0; -}; - -CV_EXPORTS_W Ptr createGhostbusterPredict(int thresh = 10, int underexp = 20, int overexp = 240); - -// "Bitmap Movement Detection: HDR for Dynamic Scenes", Pece, Kautz, 2010 - -class CV_EXPORTS_W GhostbusterBitmap : public Ghostbuster -{ -public: - CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst, std::vector& times, Mat response) = 0; - CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst) = 0; - - CV_WRAP virtual int getExclude() = 0; - CV_WRAP virtual void setExclude(int value) = 0; -}; - -CV_EXPORTS_W Ptr createGhostbusterBitmap(int exclude = 4); - } // cv #endif diff --git a/modules/photo/src/align.cpp b/modules/photo/src/align.cpp index 295fea350..35c949172 100644 --- a/modules/photo/src/align.cpp +++ b/modules/photo/src/align.cpp @@ -263,284 +263,5 @@ Ptr createAlignMTB(int max_bits, int exclude_range, bool cut) return new AlignMTBImpl(max_bits, exclude_range, cut); } -class floatIndexCmp { -public: - floatIndexCmp(std::vector data) : - data(data) - { - } - - bool operator() (int i,int j) - { - return data[i] < data[j]; - } -protected: - std::vector data; -}; - -class GhostbusterOrderImpl : public GhostbusterOrder -{ -public: - GhostbusterOrderImpl(int underexp, int overexp) : - underexp(underexp), - overexp(overexp), - name("GhostbusterOrder") - { - } - - void process(InputArrayOfArrays src, OutputArray dst, std::vector& times, Mat response) - { - process(src, dst); - } - - void process(InputArrayOfArrays src, OutputArray dst) - { - std::vector unsorted_images; - src.getMatVector(unsorted_images); - checkImageDimensions(unsorted_images); - - std::vector images; - sortImages(unsorted_images, images); - - int channels = images[0].channels(); - dst.create(images[0].size(), CV_8U); - - Mat res = Mat::zeros(images[0].size(), CV_8U); - - std::vector splitted(channels); - split(images[0], splitted); - for(size_t i = 0; i < images.size() - 1; i++) { - - std::vector next_splitted(channels); - split(images[i + 1], next_splitted); - - for(int c = 0; c < channels; c++) { - Mat exposed = (splitted[c] >= underexp) & (splitted[c] <= overexp); - exposed &= (next_splitted[c] >= underexp) & (next_splitted[c] <= overexp); - Mat ghost = (splitted[c] > next_splitted[c]) & exposed; - res |= ghost; - } - splitted = next_splitted; - } - res.copyTo(dst.getMat()); - } - - int getUnderexp() {return underexp;} - void setUnderexp(int value) {underexp = value;} - - int getOverexp() {return overexp;} - void setOverexp(int value) {overexp = value;} - - void write(FileStorage& fs) const - { - fs << "name" << name - << "overexp" << overexp - << "underexp" << underexp; - } - - void read(const FileNode& fn) - { - FileNode n = fn["name"]; - CV_Assert(n.isString() && String(n) == name); - overexp = fn["overexp"]; - underexp = fn["underexp"]; - } - -protected: - int overexp, underexp; - String name; - - void sortImages(std::vector& images, std::vector& sorted) - { - std::vectorindices(images.size()); - std::vectormeans(images.size()); - for(size_t i = 0; i < images.size(); i++) { - indices[i] = i; - means[i] = mean(mean(images[i]))[0]; - } - sort(indices.begin(), indices.end(), floatIndexCmp(means)); - sorted.resize(images.size()); - for(size_t i = 0; i < images.size(); i++) { - sorted[i] = images[indices[i]]; - } - } -}; - -Ptr createGhostbusterOrder(int underexp, int overexp) -{ - return new GhostbusterOrderImpl(underexp, overexp); -} - -class GhostbusterPredictImpl : public GhostbusterPredict -{ -public: - GhostbusterPredictImpl(int thresh, int underexp, int overexp) : - thresh(thresh), - underexp(underexp), - overexp(overexp), - name("GhostbusterPredict") - { - } - - void process(InputArrayOfArrays src, OutputArray dst, std::vector& times, Mat response) - { - std::vector images; - src.getMatVector(images); - checkImageDimensions(images); - - int channels = images[0].channels(); - dst.create(images[0].size(), CV_8U); - - Mat res = Mat::zeros(images[0].size(), CV_8U); - - Mat radiance; - LUT(images[0], response, radiance); - std::vector splitted(channels); - split(radiance, splitted); - std::vector resp_split(channels); - split(response, resp_split); - for(size_t i = 0; i < images.size() - 1; i++) { - - std::vector next_splitted(channels); - LUT(images[i + 1], response, radiance); - split(radiance, next_splitted); - - for(int c = 0; c < channels; c++) { - - Mat predicted = splitted[c] / times[i] * times[i + 1]; - - Mat low = max(thresh, next_splitted[c]) - thresh; - Mat high = min(255 - thresh, next_splitted[c]) + thresh; - low.convertTo(low, CV_8U); - high.convertTo(high, CV_8U); - LUT(low, resp_split[c], low); - LUT(high, resp_split[c], high); - - Mat exposed = (splitted[c] >= underexp) & (splitted[c] <= overexp); - exposed &= (next_splitted[c] >= underexp) & (next_splitted[c] <= overexp); - - Mat ghost = (low < predicted) & (predicted < high); - ghost &= exposed; - res |= ghost; - } - splitted = next_splitted; - } - res.copyTo(dst.getMat()); - } - - virtual void process(InputArrayOfArrays src, OutputArray dst, std::vector& times) - { - Mat response = linearResponse(3); - response.at(0) = response.at(1); - process(src, dst, times, response); - } - - CV_WRAP virtual int getThreshold() {return thresh;} - CV_WRAP virtual void setThreshold(int value) {thresh = value;} - - int getUnderexp() {return underexp;} - void setUnderexp(int value) {underexp = value;} - - int getOverexp() {return overexp;} - void setOverexp(int value) {overexp = value;} - - void write(FileStorage& fs) const - { - fs << "name" << name - << "overexp" << overexp - << "underexp" << underexp - << "thresh" << thresh; - } - - void read(const FileNode& fn) - { - FileNode n = fn["name"]; - CV_Assert(n.isString() && String(n) == name); - overexp = fn["overexp"]; - underexp = fn["underexp"]; - thresh = fn["thresh"]; - } - -protected: - int thresh, underexp, overexp; - String name; -}; - -Ptr createGhostbusterPredict(int thresh, int underexp, int overexp) -{ - return new GhostbusterPredictImpl(thresh, underexp, overexp); -} - -class GhostbusterBitmapImpl : public GhostbusterBitmap -{ -public: - GhostbusterBitmapImpl(int exclude) : - exclude(exclude), - name("GhostbusterBitmap") - { - } - - void process(InputArrayOfArrays src, OutputArray dst, std::vector& times, Mat response) - { - process(src, dst); - } - - void process(InputArrayOfArrays src, OutputArray dst) - { - std::vector images; - src.getMatVector(images); - checkImageDimensions(images); - - int channels = images[0].channels(); - dst.create(images[0].size(), CV_8U); - - Mat res = Mat::zeros(images[0].size(), CV_8U); - - Ptr MTB = createAlignMTB(); - MTB->setExcludeRange(exclude); - - for(size_t i = 0; i < images.size(); i++) { - Mat gray; - if(channels == 1) { - gray = images[i]; - } else { - cvtColor(images[i], gray, COLOR_RGB2GRAY); - } - - Mat tb, eb; - MTB->computeBitmaps(gray, tb, eb); - tb &= eb & 1; - res += tb; - } - res = (res > 0) & (res < images.size()); - res.copyTo(dst.getMat()); - } - - int getExclude() {return exclude;} - void setExclude(int value) {exclude = value;} - - void write(FileStorage& fs) const - { - fs << "name" << name - << "exclude" << exclude; - } - - void read(const FileNode& fn) - { - FileNode n = fn["name"]; - CV_Assert(n.isString() && String(n) == name); - exclude = fn["exclude"]; - } - -protected: - int exclude; - String name; -}; - -Ptr createGhostbusterBitmap(int exclude) -{ - return new GhostbusterBitmapImpl(exclude); -} - }