Commit 56f7e54c authored by Alexey Spizhevoy's avatar Alexey Spizhevoy

added GC_COLOR_GRAD cost function type into opencv_stitching

parent 8e377767
......@@ -45,6 +45,7 @@
using namespace std;
using namespace cv;
using namespace cv::gpu;
Ptr<ExposureCompensator> ExposureCompensator::createDefault(int type)
......@@ -53,6 +54,8 @@ Ptr<ExposureCompensator> ExposureCompensator::createDefault(int type)
return new NoExposureCompensator();
if (type == OVERLAP)
return new OverlapExposureCompensator();
if (type == SEGMENT)
return new SegmentExposureCompensator();
CV_Error(CV_StsBadArg, "unsupported exposure compensation method");
return NULL;
}
......@@ -61,13 +64,15 @@ Ptr<ExposureCompensator> ExposureCompensator::createDefault(int type)
void OverlapExposureCompensator::feed(const vector<Point> &corners, const vector<Mat> &images,
const vector<Mat> &masks)
{
CV_Assert(corners.size() == images.size() && images.size() == masks.size());
const int num_images = static_cast<int>(images.size());
Mat_<int> N(num_images, num_images); N.setTo(0);
Mat_<double> I(num_images, num_images); I.setTo(0);
Rect dst_roi = resultRoi(corners, images);
Mat subimg1, subimg2;
Mat_<uchar> submask1, submask2, overlap;
Mat_<uchar> submask1, submask2, intersect;
for (int i = 0; i < num_images; ++i)
{
......@@ -81,9 +86,9 @@ void OverlapExposureCompensator::feed(const vector<Point> &corners, const vector
submask1 = masks[i](Rect(roi.tl() - corners[i], roi.br() - corners[i]));
submask2 = masks[j](Rect(roi.tl() - corners[j], roi.br() - corners[j]));
overlap = submask1 & submask2;
intersect = submask1 & submask2;
N(i, j) = N(j, i) = countNonZero(overlap);
N(i, j) = N(j, i) = countNonZero(intersect);
double Isum1 = 0, Isum2 = 0;
for (int y = 0; y < roi.height; ++y)
......@@ -92,7 +97,7 @@ void OverlapExposureCompensator::feed(const vector<Point> &corners, const vector
const Point3_<uchar>* r2 = subimg2.ptr<Point3_<uchar> >(y);
for (int x = 0; x < roi.width; ++x)
{
if (overlap(y, x))
if (intersect(y, x))
{
Isum1 += sqrt(static_cast<double>(sqr(r1[x].x) + sqr(r1[x].y) + sqr(r1[x].z)));
Isum2 += sqrt(static_cast<double>(sqr(r2[x].x) + sqr(r2[x].y) + sqr(r2[x].z)));
......@@ -122,7 +127,7 @@ void OverlapExposureCompensator::feed(const vector<Point> &corners, const vector
}
}
solve(A, b, gains_, DECOMP_SVD);
solve(A, b, gains_);
}
......@@ -130,3 +135,14 @@ void OverlapExposureCompensator::apply(int index, Point /*corner*/, Mat &image,
{
image *= gains_(index, 0);
}
void SegmentExposureCompensator::feed(const vector<Point> &/*corners*/, const vector<Mat> &/*images*/,
const vector<Mat> &/*masks*/)
{
}
void SegmentExposureCompensator::apply(int /*index*/, Point /*corner*/, Mat &/*image*/, const Mat &/*mask*/)
{
}
\ No newline at end of file
......@@ -48,7 +48,7 @@
class ExposureCompensator
{
public:
enum { NO, OVERLAP };
enum { NO, OVERLAP, SEGMENT };
static cv::Ptr<ExposureCompensator> createDefault(int type);
virtual void feed(const std::vector<cv::Point> &corners, const std::vector<cv::Mat> &images,
......@@ -78,4 +78,12 @@ private:
};
class SegmentExposureCompensator : public ExposureCompensator
{
public:
void feed(const std::vector<cv::Point> &corners, const std::vector<cv::Mat> &images,
const std::vector<cv::Mat> &masks);
void apply(int index, cv::Point corner, cv::Mat &image, const cv::Mat &mask);
};
#endif // __OPENCV_EXPOSURE_COMPENSATE_HPP__
\ No newline at end of file
......@@ -71,7 +71,7 @@ void printUsage()
<< "\t[--wavecorrect (no|yes)]\n"
<< "\t[--warp (plane|cylindrical|spherical)]\n"
<< "\t[--exposcomp (no|overlap)]\n"
<< "\t[--seam (no|voronoi|graphcut)]\n"
<< "\t[--seam (no|voronoi|gc_color|gc_colorgrad)]\n"
<< "\t[--blend (no|feather|multiband)]\n"
<< "\t[--numbands <int>]\n"
<< "\t[--output <result_img>]\n\n";
......@@ -95,7 +95,7 @@ int warp_type = Warper::SPHERICAL;
int expos_comp_type = ExposureCompensator::OVERLAP;
bool user_match_conf = false;
float match_conf = 0.6f;
int seam_find_type = SeamFinder::GRAPH_CUT;
int seam_find_type = SeamFinder::GC_COLOR;
int blend_type = Blender::MULTI_BAND;
int numbands = 5;
string result_name = "result.png";
......@@ -201,6 +201,8 @@ int parseCmdArgs(int argc, char** argv)
expos_comp_type = ExposureCompensator::NO;
else if (string(argv[i + 1]) == "overlap")
expos_comp_type = ExposureCompensator::OVERLAP;
else if (string(argv[i + 1]) == "segment")
expos_comp_type = ExposureCompensator::SEGMENT;
else
{
cout << "Bad exposure compensation method\n";
......@@ -214,8 +216,10 @@ int parseCmdArgs(int argc, char** argv)
seam_find_type = SeamFinder::NO;
else if (string(argv[i + 1]) == "voronoi")
seam_find_type = SeamFinder::VORONOI;
else if (string(argv[i + 1]) == "graphcut")
seam_find_type = SeamFinder::GRAPH_CUT;
else if (string(argv[i + 1]) == "gc_color")
seam_find_type = SeamFinder::GC_COLOR;
else if (string(argv[i + 1]) == "gc_colorgrad")
seam_find_type = SeamFinder::GC_COLOR_GRAD;
else
{
cout << "Bad seam finding method\n";
......
......@@ -65,8 +65,8 @@ namespace
class CpuSurfFeaturesFinder : public FeaturesFinder
{
public:
inline CpuSurfFeaturesFinder(double hess_thresh, int num_octaves, int num_layers,
int num_octaves_descr, int num_layers_descr)
CpuSurfFeaturesFinder(double hess_thresh, int num_octaves, int num_layers,
int num_octaves_descr, int num_layers_descr)
{
detector_ = new SurfFeatureDetector(hess_thresh, num_octaves, num_layers);
extractor_ = new SurfDescriptorExtractor(num_octaves_descr, num_layers_descr);
......@@ -80,20 +80,12 @@ namespace
Ptr<DescriptorExtractor> extractor_;
};
void CpuSurfFeaturesFinder::find(const Mat &image, ImageFeatures &features)
{
Mat gray_image;
CV_Assert(image.depth() == CV_8U);
cvtColor(image, gray_image, CV_BGR2GRAY);
detector_->detect(gray_image, features.keypoints);
extractor_->compute(gray_image, features.keypoints, features.descriptors);
}
class GpuSurfFeaturesFinder : public FeaturesFinder
{
public:
inline GpuSurfFeaturesFinder(double hess_thresh, int num_octaves, int num_layers,
int num_octaves_descr, int num_layers_descr)
GpuSurfFeaturesFinder(double hess_thresh, int num_octaves, int num_layers,
int num_octaves_descr, int num_layers_descr)
{
surf_.keypointsRatio = 0.1f;
surf_.hessianThreshold = hess_thresh;
......@@ -113,6 +105,17 @@ namespace
int num_octaves_descr_, num_layers_descr_;
};
void CpuSurfFeaturesFinder::find(const Mat &image, ImageFeatures &features)
{
Mat gray_image;
CV_Assert(image.depth() == CV_8U);
cvtColor(image, gray_image, CV_BGR2GRAY);
detector_->detect(gray_image, features.keypoints);
extractor_->compute(gray_image, features.keypoints, features.descriptors);
}
void GpuSurfFeaturesFinder::find(const Mat &image, ImageFeatures &features)
{
GpuMat gray_image;
......@@ -132,7 +135,8 @@ namespace
d_descriptors.download(features.descriptors);
}
}
} // anonymous namespace
SurfFeaturesFinder::SurfFeaturesFinder(bool try_use_gpu, double hess_thresh, int num_octaves, int num_layers,
int num_octaves_descr, int num_layers_descr)
......
This diff is collapsed.
......@@ -47,7 +47,7 @@
class SeamFinder
{
public:
enum { NO, VORONOI, GRAPH_CUT };
enum { NO, VORONOI, GC_COLOR, GC_COLOR_GRAD };
static cv::Ptr<SeamFinder> createDefault(int type);
virtual ~SeamFinder() {}
......@@ -66,34 +66,36 @@ public:
class PairwiseSeamFinder : public SeamFinder
{
public:
void find(const std::vector<cv::Mat> &src, const std::vector<cv::Point> &corners,
std::vector<cv::Mat> &masks);
virtual void find(const std::vector<cv::Mat> &src, const std::vector<cv::Point> &corners,
std::vector<cv::Mat> &masks);
protected:
virtual void findInPair(const cv::Mat &img1, const cv::Mat &img2, cv::Point tl1, cv::Point tl2,
cv::Rect roi, cv::Mat &mask1, cv::Mat &mask2) = 0;
virtual void findInPair(size_t first, size_t second, cv::Rect roi) = 0;
std::vector<cv::Mat> images_;
std::vector<cv::Point> corners_;
std::vector<cv::Mat> masks_;
};
class VoronoiSeamFinder : public PairwiseSeamFinder
{
private:
void findInPair(const cv::Mat &img1, const cv::Mat &img2, cv::Point tl1, cv::Point tl2,
cv::Rect roi, cv::Mat &mask1, cv::Mat &mask2);
void findInPair(size_t first, size_t second, cv::Rect roi);
};
class GraphCutSeamFinder : public PairwiseSeamFinder
class GraphCutSeamFinder : public SeamFinder
{
public:
// TODO add COST_COLOR_GRAD support
enum { COST_COLOR };
GraphCutSeamFinder(int cost_type = COST_COLOR, float terminal_cost = 10000.f,
enum { COST_COLOR, COST_COLOR_GRAD };
GraphCutSeamFinder(int cost_type = COST_COLOR_GRAD, float terminal_cost = 10000.f,
float bad_region_penalty = 1000.f);
private:
void findInPair(const cv::Mat &img1, const cv::Mat &img2, cv::Point tl1, cv::Point tl2,
cv::Rect roi, cv::Mat &mask1, cv::Mat &mask2);
void find(const std::vector<cv::Mat> &src, const std::vector<cv::Point> &corners,
std::vector<cv::Mat> &masks);
private:
class Impl;
cv::Ptr<Impl> impl_;
};
......
......@@ -91,10 +91,17 @@ B Graph::walkBreadthFirst(int from, B body) const
//////////////////////////////////////////////////////////////////////////////
// Some auxiliary math functions
static inline
float normL2(const cv::Point3f& a)
{
return a.x * a.x + a.y * a.y + a.z * a.z;
}
static inline
float normL2(const cv::Point3f& a, const cv::Point3f& b)
{
return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y) + (a.z - b.z) * (a.z - b.z);
return normL2(a - b);
}
......
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