modified grabCut: noise is added only if covariance determinant = 0
This commit is contained in:
parent
ef3171dc65
commit
762cf182ef
@ -51,35 +51,6 @@ This is implementation of image segmentation algorithm GrabCut described in
|
|||||||
Carsten Rother, Vladimir Kolmogorov, Andrew Blake.
|
Carsten Rother, Vladimir Kolmogorov, Andrew Blake.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Noise3DGenerator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Noise3DGenerator( float var=0.1f ) : rng(theRNG())
|
|
||||||
{
|
|
||||||
var = std::min( std::max( 0.01f, var ), 1.f ) ;
|
|
||||||
|
|
||||||
double meanData[] = { 0., 0., 0. };
|
|
||||||
double covData[] = { var, 0., 0.,
|
|
||||||
0., var, 0.,
|
|
||||||
0., 0., var };
|
|
||||||
Mat( 1, 3, CV_64FC1, meanData ).copyTo( mean );
|
|
||||||
Mat( 3, 3, CV_64FC1, covData ).copyTo( cov );
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec3d generateNoise()
|
|
||||||
{
|
|
||||||
Mat noise( 1, 3, CV_64FC1 );
|
|
||||||
rng.fill( noise, RNG::NORMAL, Scalar::all(0.0), Scalar(1.0) );
|
|
||||||
noise = noise * cov + mean;
|
|
||||||
return Vec3d( noise.ptr<double>() );
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
RNG& rng;
|
|
||||||
Mat mean;
|
|
||||||
Mat cov;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
GMM - Gaussian Mixture Model
|
GMM - Gaussian Mixture Model
|
||||||
*/
|
*/
|
||||||
@ -111,8 +82,6 @@ private:
|
|||||||
double prods[componentsCount][3][3];
|
double prods[componentsCount][3][3];
|
||||||
int sampleCounts[componentsCount];
|
int sampleCounts[componentsCount];
|
||||||
int totalSampleCount;
|
int totalSampleCount;
|
||||||
|
|
||||||
Noise3DGenerator noiseGenerator;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GMM::GMM( Mat& _model )
|
GMM::GMM( Mat& _model )
|
||||||
@ -194,17 +163,17 @@ void GMM::initLearning()
|
|||||||
|
|
||||||
void GMM::addSample( int ci, const Vec3d color )
|
void GMM::addSample( int ci, const Vec3d color )
|
||||||
{
|
{
|
||||||
Vec3d nClr = color + noiseGenerator.generateNoise();
|
sums[ci][0] += color[0]; sums[ci][1] += color[1]; sums[ci][2] += color[2];
|
||||||
sums[ci][0] += nClr[0]; sums[ci][1] += nClr[1]; sums[ci][2] += nClr[2];
|
prods[ci][0][0] += color[0]*color[0]; prods[ci][0][1] += color[0]*color[1]; prods[ci][0][2] += color[0]*color[2];
|
||||||
prods[ci][0][0] += nClr[0]*nClr[0]; prods[ci][0][1] += nClr[0]*nClr[1]; prods[ci][0][2] += nClr[0]*nClr[2];
|
prods[ci][1][0] += color[1]*color[0]; prods[ci][1][1] += color[1]*color[1]; prods[ci][1][2] += color[1]*color[2];
|
||||||
prods[ci][1][0] += nClr[1]*nClr[0]; prods[ci][1][1] += nClr[1]*nClr[1]; prods[ci][1][2] += nClr[1]*nClr[2];
|
prods[ci][2][0] += color[2]*color[0]; prods[ci][2][1] += color[2]*color[1]; prods[ci][2][2] += color[2]*color[2];
|
||||||
prods[ci][2][0] += nClr[2]*nClr[0]; prods[ci][2][1] += nClr[2]*nClr[1]; prods[ci][2][2] += nClr[2]*nClr[2];
|
|
||||||
sampleCounts[ci]++;
|
sampleCounts[ci]++;
|
||||||
totalSampleCount++;
|
totalSampleCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMM::endLearning()
|
void GMM::endLearning()
|
||||||
{
|
{
|
||||||
|
const double variance = 0.01;
|
||||||
for( int ci = 0; ci < componentsCount; ci++ )
|
for( int ci = 0; ci < componentsCount; ci++ )
|
||||||
{
|
{
|
||||||
int n = sampleCounts[ci];
|
int n = sampleCounts[ci];
|
||||||
@ -222,6 +191,15 @@ void GMM::endLearning()
|
|||||||
c[3] = prods[ci][1][0]/n - m[1]*m[0]; c[4] = prods[ci][1][1]/n - m[1]*m[1]; c[5] = prods[ci][1][2]/n - m[1]*m[2];
|
c[3] = prods[ci][1][0]/n - m[1]*m[0]; c[4] = prods[ci][1][1]/n - m[1]*m[1]; c[5] = prods[ci][1][2]/n - m[1]*m[2];
|
||||||
c[6] = prods[ci][2][0]/n - m[2]*m[0]; c[7] = prods[ci][2][1]/n - m[2]*m[1]; c[8] = prods[ci][2][2]/n - m[2]*m[2];
|
c[6] = prods[ci][2][0]/n - m[2]*m[0]; c[7] = prods[ci][2][1]/n - m[2]*m[1]; c[8] = prods[ci][2][2]/n - m[2]*m[2];
|
||||||
|
|
||||||
|
double dtrm = c[0]*(c[4]*c[8]-c[5]*c[7]) - c[1]*(c[3]*c[8]-c[5]*c[6]) + c[2]*(c[3]*c[7]-c[4]*c[6]);
|
||||||
|
if( dtrm < std::numeric_limits<double>::epsilon() )
|
||||||
|
{
|
||||||
|
// Adds the white noise to avoid singular covariance matrix.
|
||||||
|
c[0] += variance;
|
||||||
|
c[4] += variance;
|
||||||
|
c[8] += variance;
|
||||||
|
}
|
||||||
|
|
||||||
calcInverseCovAndDeterm(ci);
|
calcInverseCovAndDeterm(ci);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user