00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #ifndef __OPENCV_VIDEOSTAB_FAST_MARCHING_INL_HPP__
00044 #define __OPENCV_VIDEOSTAB_FAST_MARCHING_INL_HPP__
00045
00046 #include "opencv2/videostab/fast_marching.hpp"
00047
00048 namespace cv
00049 {
00050 namespace videostab
00051 {
00052
00053 template <typename Inpaint>
00054 Inpaint FastMarchingMethod::run(const cv::Mat &mask, Inpaint inpaint)
00055 {
00056 using namespace std;
00057 using namespace cv;
00058
00059 CV_Assert(mask.type() == CV_8U);
00060
00061 static const int lut[4][2] = {{-1,0}, {0,-1}, {1,0}, {0,1}};
00062
00063 mask.copyTo(flag_);
00064 flag_.create(mask.size());
00065 dist_.create(mask.size());
00066 index_.create(mask.size());
00067 narrowBand_.clear();
00068 size_ = 0;
00069
00070
00071 for (int y = 0; y < flag_.rows; ++y)
00072 {
00073 for (int x = 0; x < flag_.cols; ++x)
00074 {
00075 if (flag_(y,x) == KNOWN)
00076 dist_(y,x) = 0.f;
00077 else
00078 {
00079 int n = 0;
00080 int nunknown = 0;
00081
00082 for (int i = 0; i < 4; ++i)
00083 {
00084 int xn = x + lut[i][0];
00085 int yn = y + lut[i][1];
00086
00087 if (xn >= 0 && xn < flag_.cols && yn >= 0 && yn < flag_.rows)
00088 {
00089 n++;
00090 if (flag_(yn,xn) != KNOWN)
00091 nunknown++;
00092 }
00093 }
00094
00095 if (n>0 && nunknown == n)
00096 {
00097 dist_(y,x) = inf_;
00098 flag_(y,x) = INSIDE;
00099 }
00100 else
00101 {
00102 dist_(y,x) = 0.f;
00103 flag_(y,x) = BAND;
00104 inpaint(x, y);
00105
00106 narrowBand_.push_back(DXY(0.f,x,y));
00107 index_(y,x) = size_++;
00108 }
00109 }
00110 }
00111 }
00112
00113
00114 for (int i = size_/2-1; i >= 0; --i)
00115 heapDown(i);
00116
00117
00118 while (size_ > 0)
00119 {
00120 int x = narrowBand_[0].x;
00121 int y = narrowBand_[0].y;
00122 heapRemoveMin();
00123
00124 flag_(y,x) = KNOWN;
00125 for (int n = 0; n < 4; ++n)
00126 {
00127 int xn = x + lut[n][0];
00128 int yn = y + lut[n][1];
00129
00130 if (xn >= 0 && xn < flag_.cols && yn >= 0 && yn < flag_.rows && flag_(yn,xn) != KNOWN)
00131 {
00132 dist_(yn,xn) = min(min(solve(xn-1, yn, xn, yn-1), solve(xn+1, yn, xn, yn-1)),
00133 min(solve(xn-1, yn, xn, yn+1), solve(xn+1, yn, xn, yn+1)));
00134
00135 if (flag_(yn,xn) == INSIDE)
00136 {
00137 flag_(yn,xn) = BAND;
00138 inpaint(xn, yn);
00139 heapAdd(DXY(dist_(yn,xn),xn,yn));
00140 }
00141 else
00142 {
00143 int i = index_(yn,xn);
00144 if (dist_(yn,xn) < narrowBand_[i].dist)
00145 {
00146 narrowBand_[i].dist = dist_(yn,xn);
00147 heapUp(i);
00148 }
00149
00150
00151
00152
00153
00154
00155 }
00156 }
00157 }
00158 }
00159
00160 return inpaint;
00161 }
00162
00163 }
00164 }
00165
00166 #endif