Commit 66b41b67 authored by Alexey Spizhevoy's avatar Alexey Spizhevoy

Added support of GPU in stitching seam estimators

parent 16f5c679
......@@ -51,9 +51,6 @@ namespace detail {
class CV_EXPORTS SeamFinder
{
public:
enum { NO, VORONOI, GC_COLOR, GC_COLOR_GRAD };
static Ptr<SeamFinder> createDefault(int type);
virtual ~SeamFinder() {}
virtual void find(const std::vector<Mat> &src, const std::vector<Point> &corners,
std::vector<Mat> &masks) = 0;
......@@ -89,10 +86,16 @@ private:
};
class CV_EXPORTS GraphCutSeamFinder : public SeamFinder
class CV_EXPORTS GraphCutSeamFinderBase
{
public:
enum { COST_COLOR, COST_COLOR_GRAD };
};
class CV_EXPORTS GraphCutSeamFinder : public GraphCutSeamFinderBase, public SeamFinder
{
public:
GraphCutSeamFinder(int cost_type = COST_COLOR_GRAD, float terminal_cost = 10000.f,
float bad_region_penalty = 1000.f);
......@@ -105,6 +108,33 @@ private:
Ptr<Impl> impl_;
};
#ifndef ANDROID
class CV_EXPORTS GraphCutSeamFinderGpu : public GraphCutSeamFinderBase, public PairwiseSeamFinder
{
public:
GraphCutSeamFinderGpu(int cost_type = COST_COLOR_GRAD, float terminal_cost = 10000.f,
float bad_region_penalty = 1000.f)
: cost_type_(cost_type), terminal_cost_(terminal_cost),
bad_region_penalty_(bad_region_penalty) {}
void find(const std::vector<cv::Mat> &src, const std::vector<cv::Point> &corners,
std::vector<cv::Mat> &masks);
void findInPair(size_t first, size_t second, Rect roi);
private:
void setGraphWeightsColor(const cv::Mat &img1, const cv::Mat &img2, const cv::Mat &mask1, const cv::Mat &mask2,
cv::Mat &terminals, cv::Mat &leftT, cv::Mat &rightT, cv::Mat &top, cv::Mat &bottom);
void setGraphWeightsColorGrad(const cv::Mat &img1, const cv::Mat &img2, const cv::Mat &dx1, const cv::Mat &dx2,
const cv::Mat &dy1, const cv::Mat &dy2, const cv::Mat &mask1, const cv::Mat &mask2,
cv::Mat &terminals, cv::Mat &leftT, cv::Mat &rightT, cv::Mat &top, cv::Mat &bottom);
std::vector<Mat> dx_, dy_;
int cost_type_;
float terminal_cost_;
float bad_region_penalty_;
};
#endif
} // namespace detail
} // namespace cv
......
This diff is collapsed.
......@@ -63,16 +63,17 @@ Stitcher Stitcher::createDefault(bool try_use_gpu)
{
stitcher.setFeaturesFinder(new detail::SurfFeaturesFinderGpu());
stitcher.setWarper(new SphericalWarperGpu());
stitcher.setSeamFinder(new detail::GraphCutSeamFinderGpu());
}
else
#endif
{
stitcher.setFeaturesFinder(new detail::SurfFeaturesFinder());
stitcher.setWarper(new SphericalWarper());
stitcher.setSeamFinder(new detail::GraphCutSeamFinder());
}
stitcher.setExposureCompenstor(new detail::BlocksGainCompensator());
stitcher.setSeamFinder(new detail::GraphCutSeamFinder());
stitcher.setBlender(new detail::MultiBandBlender(try_use_gpu));
return stitcher;
......
......@@ -132,7 +132,7 @@ std::string save_graph_to;
string warp_type = "spherical";
int expos_comp_type = ExposureCompensator::GAIN_BLOCKS;
float match_conf = 0.65f;
int seam_find_type = SeamFinder::GC_COLOR;
string seam_find_type = "gc_color";
int blend_type = Blender::MULTI_BAND;
float blend_strength = 5;
string result_name = "result.jpg";
......@@ -262,14 +262,11 @@ int parseCmdArgs(int argc, char** argv)
}
else if (string(argv[i]) == "--seam")
{
if (string(argv[i + 1]) == "no")
seam_find_type = SeamFinder::NO;
else if (string(argv[i + 1]) == "voronoi")
seam_find_type = SeamFinder::VORONOI;
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;
if (string(argv[i + 1]) == "no" ||
string(argv[i + 1]) == "voronoi" ||
string(argv[i + 1]) == "gc_color" ||
string(argv[i + 1]) == "gc_colorgrad")
seam_find_type = argv[i + 1];
else
{
cout << "Bad seam finding method\n";
......@@ -550,7 +547,35 @@ int main(int argc, char* argv[])
Ptr<ExposureCompensator> compensator = ExposureCompensator::createDefault(expos_comp_type);
compensator->feed(corners, images_warped, masks_warped);
Ptr<SeamFinder> seam_finder = SeamFinder::createDefault(seam_find_type);
Ptr<SeamFinder> seam_finder;
if (seam_find_type == "no")
seam_finder = new detail::NoSeamFinder();
else if (seam_find_type == "voronoi")
seam_finder = new detail::VoronoiSeamFinder();
else if (seam_find_type == "gc_color")
{
#ifndef ANDROID
if (try_gpu)
seam_finder = new detail::GraphCutSeamFinderGpu(GraphCutSeamFinderBase::COST_COLOR);
else
#endif
seam_finder = new detail::GraphCutSeamFinder(GraphCutSeamFinderBase::COST_COLOR);
}
else if (seam_find_type == "gc_colorgrad")
{
#ifndef ANDROID
if (try_gpu)
seam_finder = new detail::GraphCutSeamFinderGpu(GraphCutSeamFinderBase::COST_COLOR_GRAD);
else
#endif
seam_finder = new detail::GraphCutSeamFinder(GraphCutSeamFinderBase::COST_COLOR_GRAD);
}
if (seam_finder.empty())
{
cout << "Can't create the following seam finder '" << seam_find_type << "'\n";
return 1;
}
seam_finder->find(images_warped_f, corners, masks_warped);
// Release unused memory
......
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