@@ -39,7 +39,7 @@ BackgroundContrast::BackgroundContrast()
39
39
}
40
40
BackgroundContrast::~BackgroundContrast (){};
41
41
42
- Mat BackgroundContrast::saliencyMapGenerator ( const Mat img )
42
+ Mat BackgroundContrast::saliencyMapGenerator ( const Mat img, const Mat fgImg, int option )
43
43
{
44
44
Mat idxImg, adjcMatrix, colDistM, posDistM, bdProb, wCtr, saliency;
45
45
superpixelSplit (img, idxImg, adjcMatrix);
@@ -54,7 +54,31 @@ Mat BackgroundContrast::saliencyMapGenerator( const Mat img )
54
54
}
55
55
getColorPosDis (img, idxImg, colDistM, posDistM, adjcMatrix.size [0 ]);
56
56
boundaryConnectivity (adjcMatrix, colDistM, bdProb, bdIds);
57
- getWeightedContrast (colDistM, posDistM, bdProb, wCtr);
57
+
58
+ if ( option == 0 )
59
+ {
60
+ getWeightedContrast (colDistM, posDistM, bdProb, wCtr);
61
+
62
+ }
63
+ else
64
+ {
65
+ Mat temp = fgImg.clone ();
66
+ resize (temp, temp, img.size ());
67
+ vector<int > szOfSP = vector<int >(adjcMatrix.size [0 ], 0 );
68
+ for ( int i = 0 ; i < img.size [0 ]; i++ )
69
+ {
70
+ for ( int j = 0 ; j < img.size [1 ]; j++ )
71
+ {
72
+ szOfSP[idxImg.at <unsigned >(i, j)]++;
73
+ wCtr.at <double >(idxImg.at <unsigned >(i, j), 0 ) += temp.at <double >(i, j);
74
+ }
75
+ }
76
+ for ( unsigned i = 0 ; i < szOfSP.size (); i++ )
77
+ {
78
+ wCtr.at <double >(i, 0 ) /= szOfSP[i];
79
+ }
80
+ }
81
+ saliencyOptimize (adjcMatrix, colDistM, bdProb, wCtr, wCtr);
58
82
saliency = Mat (img.size [0 ], img.size [1 ], CV_64F, Scalar::all (0.0 ));
59
83
for (int i = 0 ; i < img.size [0 ]; i++)
60
84
{
@@ -64,7 +88,59 @@ Mat BackgroundContrast::saliencyMapGenerator( const Mat img )
64
88
}
65
89
}
66
90
return saliency;
67
- return img;
91
+ }
92
+
93
+ void BackgroundContrast::saliencyOptimize ( const Mat adjcMatrix, const Mat colDistM, const Mat bgWeight, const Mat fgWeight, Mat& saliencyOptimized, double neiSigma, double bgLambda )
94
+ {
95
+
96
+ Mat smoothWeight = colDistM.clone ();
97
+ Mat smoothDeri = Mat (smoothWeight.size [0 ], smoothWeight.size [1 ], CV_64F, Scalar::all (0.0 ));
98
+ Mat bgWeightDig = Mat (smoothWeight.size [0 ], smoothWeight.size [1 ], CV_64F, Scalar::all (0.0 ));
99
+ Mat fgWeightDig = Mat (smoothWeight.size [0 ], smoothWeight.size [1 ], CV_64F, Scalar::all (0.0 ));
100
+ Mat temp;
101
+
102
+ double mi = 0 , ma = 0 ;
103
+ minMaxLoc ( fgWeight, &mi, &ma );
104
+ Mat fg = fgWeight.clone ();
105
+ fg -= mi;
106
+ fg /= ( ma - mi + 0.000001 );
107
+ fg *= 255 ;
108
+ fg.convertTo (fg, CV_8U);
109
+ threshold (fg, fg, 0 , 255 , THRESH_TOZERO | THRESH_OTSU);
110
+ fg.convertTo (fg, CV_64F);
111
+ fg /= 255 ; // clean fore ground cue
112
+
113
+ minMaxLoc ( smoothWeight, NULL , &ma );
114
+ for ( int i = 0 ; i < smoothWeight.size [0 ]; i++ )
115
+ {
116
+ for ( int j = 0 ; j < smoothWeight.size [1 ]; j++ )
117
+ {
118
+ if ( adjcMatrix.at <uchar>(i, j) == 0 )
119
+ {
120
+ smoothWeight.at <double >(i, j) = ma * adjcMatrix.size [0 ];
121
+ }
122
+ }
123
+ }
124
+
125
+ dist2WeightMatrix (smoothWeight, smoothWeight, neiSigma);
126
+ adjcMatrix.convertTo (temp, CV_64F);
127
+ smoothWeight += temp * 0.1 ;// add small coefficients for regularization term
128
+ reduce (smoothWeight, temp, 0 , REDUCE_SUM);
129
+ for ( int i = 0 ; i < smoothDeri.size [0 ]; i++ )
130
+ {
131
+ smoothDeri.at <double >(i, i) = temp.at <double >(0 , i);
132
+ }
133
+ for ( int i = 0 ; i < bgWeightDig.size [0 ]; i++ )
134
+ {
135
+ bgWeightDig.at <double >(i, i) = bgWeight.at <double >(i, 0 ) * bgLambda;
136
+ }
137
+ for ( int i = 0 ; i < fgWeightDig.size [0 ]; i++ )
138
+ {
139
+ fgWeightDig.at <double >(i, i) = fg.at <double >(i, 0 );
140
+ }
141
+ // temp = (smoothDeri - smoothWeight + bgWeightDig + fgWeightDig);
142
+ // saliencyOptimized = temp.inv() * fgWeight;
143
+ solve ((smoothDeri - smoothWeight + bgWeightDig + fgWeightDig), fg, saliencyOptimized, DECOMP_NORMAL);
68
144
}
69
145
70
146
bool BackgroundContrast::computeSaliencyImpl ( InputArray image, OutputArray saliencyMap )
@@ -75,7 +151,7 @@ bool BackgroundContrast::computeSaliencyImpl( InputArray image, OutputArray sali
75
151
void BackgroundContrast::superpixelSplit ( const Mat img, Mat& idxImg, Mat& adjcMatrix)
76
152
{
77
153
Ptr<SuperpixelSEEDS> seeds;
78
- seeds = createSuperpixelSEEDS ( img.size ().width , img.size ().height , img.channels (), min (img.size ().width * img.size ().height / 600 , 3000 ), 4 , 2 , 5 , false );
154
+ seeds = createSuperpixelSEEDS ( img.size ().width , img.size ().height , img.channels (), min (img.size ().width * img.size ().height / 600 , 600 ), 4 , 2 , 5 , false );
79
155
seeds->iterate( img, 4 );
80
156
Mat mask;
81
157
adjcMatrix = Mat::eye ( seeds->getNumberOfSuperpixels (), seeds->getNumberOfSuperpixels (), CV_8U );
@@ -194,7 +270,7 @@ void BackgroundContrast::boundaryConnectivity(const Mat adjcMatrix, const Mat co
194
270
}
195
271
}
196
272
}
197
- for ( int k = 0 ; k < adjcMatrix.size [0 ]; k++ )
273
+ for ( int k = 0 ; k < adjcMatrix.size [0 ]; k++ ) // floyd algorithm, you can replace it with johnson algorithm but it's too long
198
274
{
199
275
for ( int i = 0 ; i < adjcMatrix.size [0 ]; i++ )
200
276
{
0 commit comments