};\r
\r
\r
-void CV_EXPORTS waveCorrect(std::vector<Mat> &rmats);\r
+enum CV_EXPORTS WaveCorrectKind\r
+{\r
+ WAVE_CORRECT_HORIZ,\r
+ WAVE_CORRECT_VERT\r
+};\r
+\r
+void CV_EXPORTS waveCorrect(std::vector<Mat> &rmats, WaveCorrectKind kind);\r
\r
\r
//////////////////////////////////////////////////////////////////////////////\r
std::vector<Mat> &masks);\r
\r
private:\r
+ // To avoid GCGraph dependency\r
class Impl;\r
Ptr<Impl> impl_;\r
};\r
void detectResultRoi(Point &dst_tl, Point &dst_br);\r
};\r
\r
+\r
#ifndef ANDROID\r
class CV_EXPORTS PlaneWarperGpu : public PlaneWarper\r
{\r
void setBundleAdjuster(Ptr<detail::BundleAdjusterBase> bundle_adjuster)
{ bundle_adjuster_ = bundle_adjuster; }
+ detail::WaveCorrectKind waveCorrectKind() const { return wave_correct_kind_; }
+ void setWaveCorrectKind(detail::WaveCorrectKind kind) { wave_correct_kind_ = kind; }
+
Ptr<WarperCreator> warper() { return warper_; }
const Ptr<WarperCreator> warper() const { return warper_; }
void setWarper(Ptr<WarperCreator> warper) { warper_ = warper; }
Ptr<detail::FeaturesFinder> features_finder_;
Ptr<detail::FeaturesMatcher> features_matcher_;
Ptr<detail::BundleAdjusterBase> bundle_adjuster_;
+ detail::WaveCorrectKind wave_correct_kind_;
Ptr<WarperCreator> warper_;
Ptr<detail::ExposureCompensator> exposure_comp_;
Ptr<detail::SeamFinder> seam_finder_;
\r
//////////////////////////////////////////////////////////////////////////////\r
\r
-void waveCorrect(vector<Mat> &rmats)\r
+void waveCorrect(vector<Mat> &rmats, WaveCorrectKind kind)\r
{\r
LOGLN("Wave correcting...");\r
int64 t = getTickCount();\r
}\r
Mat eigen_vals, eigen_vecs;\r
eigen(moment, eigen_vals, eigen_vecs);\r
- Mat rg1 = eigen_vecs.row(2).t();\r
+\r
+ Mat rg1;\r
+ if (kind == WAVE_CORRECT_HORIZ)\r
+ rg1 = eigen_vecs.row(2).t();\r
+ else if (kind == WAVE_CORRECT_VERT)\r
+ rg1 = eigen_vecs.row(0).t();\r
+ else\r
+ CV_Error(CV_StsBadArg, "unsupported kind of wave correction");\r
\r
Mat img_k = Mat::zeros(3, 1, CV_32F);\r
for (size_t i = 0; i < rmats.size(); ++i)\r
\r
Mat rg2 = rg0.cross(rg1);\r
\r
+ double conf = 0;\r
+ if (kind == WAVE_CORRECT_HORIZ)\r
+ {\r
+ for (size_t i = 0; i < rmats.size(); ++i)\r
+ conf += rg0.dot(rmats[i].col(0));\r
+ if (conf < 0)\r
+ {\r
+ rg0 *= -1;\r
+ rg1 *= -1;\r
+ }\r
+ }\r
+ else if (kind == WAVE_CORRECT_VERT)\r
+ {\r
+ for (size_t i = 0; i < rmats.size(); ++i)\r
+ conf -= rg1.dot(rmats[i].col(0));\r
+ cout << conf << endl;\r
+ if (conf < 0)\r
+ {\r
+ rg0 *= -1;\r
+ rg1 *= -1;\r
+ }\r
+ }\r
+\r
Mat R = Mat::zeros(3, 3, CV_32F);\r
Mat tmp = R.row(0);\r
Mat(rg0.t()).copyTo(tmp);\r
stitcher.setHorizontalStrightening(true);
stitcher.setFeaturesMatcher(new detail::BestOf2NearestMatcher(try_use_gpu));
stitcher.setBundleAdjuster(new detail::BundleAdjusterRay());
+ stitcher.setWaveCorrectKind(detail::WAVE_CORRECT_HORIZ);
#ifndef ANDROID
if (try_use_gpu && gpu::getCudaEnabledDeviceCount() > 0)
vector<Mat> rmats;
for (size_t i = 0; i < cameras.size(); ++i)
rmats.push_back(cameras[i].R);
- detail::waveCorrect(rmats);
+ detail::waveCorrect(rmats, wave_correct_kind_);
for (size_t i = 0; i < cameras.size(); ++i)
cameras[i].R = rmats[i];
}
" <fx><skew><ppx><aspect><ppy>. The default mask is 'xxxxx'. If bundle\n"
" adjustment doesn't support estimation of selected parameter then\n"
" the respective flag is ignored.\n"
- " --wave_correct (no|yes)\n"
- " Perform wave effect correction. The default is 'yes'.\n"
+ " --wave_correct (no|horiz|vert)\n"
+ " Perform wave effect correction. The default is 'horiz'.\n"
" --save_graph <file_name>\n"
" Save matches graph represented in DOT language to <file_name> file.\n"
" Labels description: Nm is number of matches, Ni is number of inliers,\n"
float conf_thresh = 1.f;
string ba_cost_func = "ray";
string ba_refine_mask = "xxxxx";
-bool wave_correct = true;
+bool do_wave_correct = true;
+WaveCorrectKind wave_correct = detail::WAVE_CORRECT_HORIZ;
bool save_graph = false;
std::string save_graph_to;
string warp_type = "spherical";
else if (string(argv[i]) == "--wave_correct")
{
if (string(argv[i + 1]) == "no")
- wave_correct = false;
- else if (string(argv[i + 1]) == "yes")
- wave_correct = true;
+ do_wave_correct = false;
+ else if (string(argv[i + 1]) == "horiz")
+ {
+ do_wave_correct = true;
+ wave_correct = detail::WAVE_CORRECT_HORIZ;
+ }
+ else if (string(argv[i + 1]) == "vert")
+ {
+ do_wave_correct = true;
+ wave_correct = detail::WAVE_CORRECT_VERT;
+ }
else
{
cout << "Bad --wave_correct flag value\n";
nth_element(focals.begin(), focals.begin() + focals.size()/2, focals.end());
float warped_image_scale = static_cast<float>(focals[focals.size() / 2]);
- if (wave_correct)
+ if (do_wave_correct)
{
vector<Mat> rmats;
for (size_t i = 0; i < cameras.size(); ++i)
rmats.push_back(cameras[i].R);
- waveCorrect(rmats);
+ waveCorrect(rmats, wave_correct);
for (size_t i = 0; i < cameras.size(); ++i)
cameras[i].R = rmats[i];
}