@@ -128,18 +128,21 @@ class GuidedFilterImpl : public GuidedFilter
128
128
{
129
129
public:
130
130
131
- static Ptr <GuidedFilterImpl> create (InputArray guide, int radius, double eps);
131
+ static Ptr <GuidedFilterImpl> create (InputArray guide, int radius, double eps, double scale );
132
132
133
133
void filter (InputArray src, OutputArray dst, int dDepth = -1 ) CV_OVERRIDE;
134
134
135
135
protected:
136
136
137
137
int radius;
138
138
double eps;
139
+ double scale;
139
140
int h, w;
141
+ int hOriginal, wOriginal;
140
142
141
143
vector<Mat> guideCn;
142
144
vector<Mat> guideCnMean;
145
+ vector<Mat> guideCnOriginal;
143
146
144
147
SymArray2D<Mat> covarsInv;
145
148
@@ -149,7 +152,7 @@ class GuidedFilterImpl : public GuidedFilter
149
152
150
153
GuidedFilterImpl () {}
151
154
152
- void init (InputArray guide, int radius, double eps);
155
+ void init (InputArray guide, int radius, double eps, double scale );
153
156
154
157
void computeCovGuide (SymArray2D<Mat>& covars);
155
158
@@ -167,6 +170,16 @@ class GuidedFilterImpl : public GuidedFilter
167
170
src.convertTo (dst, CV_32F);
168
171
}
169
172
173
+ inline void subsample (Mat& src, Mat& dst)
174
+ {
175
+ resize (src, dst, Size (w, h), 0 , 0 , INTER_NEAREST);
176
+ }
177
+
178
+ inline void upsample (Mat& src, Mat& dst)
179
+ {
180
+ resize (src, dst, Size (wOriginal, hOriginal), 0 , 0 , INTER_LINEAR);
181
+ }
182
+
170
183
private: /* Routines to parallelize boxFilter and convertTo*/
171
184
172
185
typedef void (GuidedFilterImpl::*TransformFunc)(Mat& src, Mat& dst);
@@ -203,6 +216,20 @@ class GuidedFilterImpl : public GuidedFilter
203
216
parallel_for_ (pb.getRange (), pb);
204
217
}
205
218
219
+ template <typename V>
220
+ void parSubsample (V &src, V &dst)
221
+ {
222
+ GFTransform_ParBody pb (*this , src, dst, &GuidedFilterImpl::subsample);
223
+ parallel_for_ (pb.getRange (), pb);
224
+ }
225
+
226
+ template <typename V>
227
+ void parUpsample (V &src, V &dst)
228
+ {
229
+ GFTransform_ParBody pb (*this , src, dst, &GuidedFilterImpl::upsample);
230
+ parallel_for_ (pb.getRange (), pb);
231
+ }
232
+
206
233
private: /* Parallel body classes*/
207
234
208
235
inline void runParBody (const ParallelLoopBody& pb)
@@ -582,7 +609,7 @@ void GuidedFilterImpl::ApplyTransform_ParBody::operator()(const Range& range) co
582
609
{
583
610
float *_g[4 ];
584
611
for (int gi = 0 ; gi < gf.gCnNum ; gi++)
585
- _g[gi] = gf.guideCn [gi].ptr <float >(i);
612
+ _g[gi] = gf.guideCnOriginal [gi].ptr <float >(i);
586
613
587
614
float *betaDst, *g, *a;
588
615
for (int si = 0 ; si < srcCnNum; si++)
@@ -593,7 +620,7 @@ void GuidedFilterImpl::ApplyTransform_ParBody::operator()(const Range& range) co
593
620
a = alpha[si][gi].ptr <float >(i);
594
621
g = _g[gi];
595
622
596
- add_mul (betaDst, a, g, gf.w );
623
+ add_mul (betaDst, a, g, gf.wOriginal );
597
624
}
598
625
}
599
626
}
@@ -666,28 +693,42 @@ void GuidedFilterImpl::getWalkPattern(int eid, int &cn1, int &cn2)
666
693
cn2 = wdata[6 * 2 * (gCnNum -1 ) + 6 + eid];
667
694
}
668
695
669
- Ptr <GuidedFilterImpl> GuidedFilterImpl::create (InputArray guide, int radius, double eps)
696
+ Ptr <GuidedFilterImpl> GuidedFilterImpl::create (InputArray guide, int radius, double eps, double scale )
670
697
{
671
698
GuidedFilterImpl *gf = new GuidedFilterImpl ();
672
- gf->init (guide, radius, eps);
699
+ gf->init (guide, radius, eps, scale );
673
700
return Ptr <GuidedFilterImpl>(gf);
674
701
}
675
702
676
- void GuidedFilterImpl::init (InputArray guide, int radius_, double eps_)
703
+ void GuidedFilterImpl::init (InputArray guide, int radius_, double eps_, double scale_ )
677
704
{
678
705
CV_Assert ( !guide.empty () && radius_ >= 0 && eps_ >= 0 );
679
706
CV_Assert ( (guide.depth () == CV_32F || guide.depth () == CV_8U || guide.depth () == CV_16U) && (guide.channels () <= 3 ) );
707
+ CV_Assert ( scale_ >= 1.0 );
680
708
681
709
radius = radius_;
682
710
eps = eps_;
711
+ scale = scale_;
683
712
684
- splitFirstNChannels (guide, guideCn, 3 );
685
- gCnNum = (int )guideCn.size ();
686
- h = guideCn[0 ].rows ;
687
- w = guideCn[0 ].cols ;
713
+ splitFirstNChannels (guide, guideCnOriginal, 3 );
714
+ gCnNum = (int )guideCnOriginal.size ();
715
+ hOriginal = guideCnOriginal[0 ].rows ;
716
+ wOriginal = guideCnOriginal[0 ].cols ;
717
+ h = int (hOriginal / scale);
718
+ w = int (wOriginal / scale);
719
+
720
+ parConvertToWorkType (guideCnOriginal, guideCnOriginal);
721
+ if (scale > 1.0 )
722
+ {
723
+ guideCn.resize (gCnNum );
724
+ parSubsample (guideCnOriginal, guideCn);
725
+ }
726
+ else
727
+ {
728
+ guideCn = guideCnOriginal;
729
+ }
688
730
689
731
guideCnMean.resize (gCnNum );
690
- parConvertToWorkType (guideCn, guideCn);
691
732
parMeanFilter (guideCn, guideCnMean);
692
733
693
734
SymArray2D<Mat> covars;
@@ -712,7 +753,7 @@ void GuidedFilterImpl::computeCovGuide(SymArray2D<Mat>& covars)
712
753
void GuidedFilterImpl::filter (InputArray src, OutputArray dst, int dDepth /* = -1*/ )
713
754
{
714
755
CV_Assert ( !src.empty () && (src.depth () == CV_32F || src.depth () == CV_8U) );
715
- if (src.rows () != h || src.cols () != w )
756
+ if (src.rows () != hOriginal || src.cols () != wOriginal )
716
757
{
717
758
CV_Error (Error::StsBadSize, " Size of filtering image must be equal to size of guide image" );
718
759
return ;
@@ -725,6 +766,11 @@ void GuidedFilterImpl::filter(InputArray src, OutputArray dst, int dDepth /*= -1
725
766
vector<Mat>& srcCnMean = srcCn;
726
767
split (src, srcCn);
727
768
769
+ if (scale > 1.0 )
770
+ {
771
+ parSubsample (srcCn, srcCn);
772
+ }
773
+
728
774
if (src.depth () != CV_32F)
729
775
{
730
776
parConvertToWorkType (srcCn, srcCn);
@@ -749,7 +795,13 @@ void GuidedFilterImpl::filter(InputArray src, OutputArray dst, int dDepth /*= -1
749
795
parMeanFilter (beta, beta);
750
796
parMeanFilter (alpha, alpha);
751
797
752
- runParBody (ApplyTransform_ParBody (*this , alpha, beta));
798
+ if (scale > 1.0 )
799
+ {
800
+ parUpsample (beta, beta);
801
+ parUpsample (alpha, alpha);
802
+ }
803
+
804
+ parallel_for_ (Range (0 , hOriginal), ApplyTransform_ParBody (*this , alpha, beta));
753
805
if (dDepth != CV_32F)
754
806
{
755
807
for (int i = 0 ; i < srcCnNum; i++)
@@ -782,15 +834,15 @@ void GuidedFilterImpl::computeCovGuideAndSrc(vector<Mat>& srcCn, vector<Mat>& sr
782
834
// ////////////////////////////////////////////////////////////////////////
783
835
784
836
CV_EXPORTS_W
785
- Ptr <GuidedFilter> createGuidedFilter (InputArray guide, int radius, double eps)
837
+ Ptr <GuidedFilter> createGuidedFilter (InputArray guide, int radius, double eps, double scale )
786
838
{
787
- return Ptr <GuidedFilter>(GuidedFilterImpl::create (guide, radius, eps));
839
+ return Ptr <GuidedFilter>(GuidedFilterImpl::create (guide, radius, eps, scale ));
788
840
}
789
841
790
842
CV_EXPORTS_W
791
- void guidedFilter (InputArray guide, InputArray src, OutputArray dst, int radius, double eps, int dDepth)
843
+ void guidedFilter (InputArray guide, InputArray src, OutputArray dst, int radius, double eps, int dDepth, double scale )
792
844
{
793
- Ptr <GuidedFilter> gf = createGuidedFilter (guide, radius, eps);
845
+ Ptr <GuidedFilter> gf = createGuidedFilter (guide, radius, eps, scale );
794
846
gf->filter (src, dst, dDepth);
795
847
}
796
848
0 commit comments