Remove ghost removal
This commit is contained in:
parent
89508bf7ab
commit
b1af5cc478
@ -288,63 +288,6 @@ public:
|
|||||||
|
|
||||||
CV_EXPORTS_W Ptr<MergeRobertson> createMergeRobertson();
|
CV_EXPORTS_W Ptr<MergeRobertson> createMergeRobertson();
|
||||||
|
|
||||||
class CV_EXPORTS_W Ghostbuster : public Algorithm
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst, std::vector<float>& 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<float>& 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<GhostbusterOrder> 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<float>& times, Mat response) = 0;
|
|
||||||
CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst, std::vector<float>& 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<GhostbusterPredict> 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<float>& 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<GhostbusterBitmap> createGhostbusterBitmap(int exclude = 4);
|
|
||||||
|
|
||||||
} // cv
|
} // cv
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -263,284 +263,5 @@ Ptr<AlignMTB> createAlignMTB(int max_bits, int exclude_range, bool cut)
|
|||||||
return new AlignMTBImpl(max_bits, exclude_range, cut);
|
return new AlignMTBImpl(max_bits, exclude_range, cut);
|
||||||
}
|
}
|
||||||
|
|
||||||
class floatIndexCmp {
|
|
||||||
public:
|
|
||||||
floatIndexCmp(std::vector<float> data) :
|
|
||||||
data(data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator() (int i,int j)
|
|
||||||
{
|
|
||||||
return data[i] < data[j];
|
|
||||||
}
|
|
||||||
protected:
|
|
||||||
std::vector<float> 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<float>& times, Mat response)
|
|
||||||
{
|
|
||||||
process(src, dst);
|
|
||||||
}
|
|
||||||
|
|
||||||
void process(InputArrayOfArrays src, OutputArray dst)
|
|
||||||
{
|
|
||||||
std::vector<Mat> unsorted_images;
|
|
||||||
src.getMatVector(unsorted_images);
|
|
||||||
checkImageDimensions(unsorted_images);
|
|
||||||
|
|
||||||
std::vector<Mat> 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<Mat> splitted(channels);
|
|
||||||
split(images[0], splitted);
|
|
||||||
for(size_t i = 0; i < images.size() - 1; i++) {
|
|
||||||
|
|
||||||
std::vector<Mat> 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<Mat>& images, std::vector<Mat>& sorted)
|
|
||||||
{
|
|
||||||
std::vector<int>indices(images.size());
|
|
||||||
std::vector<float>means(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<GhostbusterOrder> 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<float>& times, Mat response)
|
|
||||||
{
|
|
||||||
std::vector<Mat> 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<Mat> splitted(channels);
|
|
||||||
split(radiance, splitted);
|
|
||||||
std::vector<Mat> resp_split(channels);
|
|
||||||
split(response, resp_split);
|
|
||||||
for(size_t i = 0; i < images.size() - 1; i++) {
|
|
||||||
|
|
||||||
std::vector<Mat> 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<float>& times)
|
|
||||||
{
|
|
||||||
Mat response = linearResponse(3);
|
|
||||||
response.at<Vec3f>(0) = response.at<Vec3f>(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<GhostbusterPredict> 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<float>& times, Mat response)
|
|
||||||
{
|
|
||||||
process(src, dst);
|
|
||||||
}
|
|
||||||
|
|
||||||
void process(InputArrayOfArrays src, OutputArray dst)
|
|
||||||
{
|
|
||||||
std::vector<Mat> 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<AlignMTB> 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<GhostbusterBitmap> createGhostbusterBitmap(int exclude)
|
|
||||||
{
|
|
||||||
return new GhostbusterBitmapImpl(exclude);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user