OpenCV4Android - calcCovarMatrix for image averages

asked 2016-04-13 16:13:19 -0500

Silberlicht gravatar image

updated 2016-04-14 12:34:37 -0500

So I have two RBG averages that I want to get a Mahalanobis distance for. The Mahalanobis function requires an inverse co-variance matrix. My question is how do I create a inverse co-variance matric for averages?

The averages would just be two 1x3 vectors but those averages come from a single image that's 27x27.

The image looks similar to this: enter image description here

One of the averages is for an estimate of the average RBG values for inside the circle and the other is outside the RBG values outside the circle. Is it as simple as creating two images one with the inside of the circle and filling the background with my average circle values and another with the background and filling in the circle with my average background values? From what I've read the inverse co-variance matrix would need to be a 3x3 so I don't think that can work...

Mat coloredImage = colorImage.clone();
Mat threshedImage = threshImage.clone();
Mat mask = new Mat(coloredImage.size(), CvType.CV_8UC1, Scalar.all(255));

Core.circle(mask, new Point(mask.rows() / 2, mask.cols() / 2), (int) mR, Scalar.all(0), -1, 8, 0);

Bitmap gridBitmap = Bitmap.createBitmap(mask.width(), mask.height(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(mask, gridBitmap);

double externalRed = 0;
double externalGreen = 0;
double externalBlue = 0;
int externalCount = 0;

double internalRed = 0;
double internalGreen = 0;
double internalBlue = 0;
int internalCount = 0;

//FIXME: Revisit when I have a better understanding of masks in OpenCV - Masks appear to only effect 1 channel
for (int column=0; column<mask.cols(); column++)
{
    for (int row=0; row<mask.rows(); row++)
    {
        double[] maskValue = mask.get(row, column);
        double[] value = coloredImage.get(row, column);

        if (maskValue[0] == 255)
        {
            externalRed = externalRed + value[0];
            externalGreen = externalGreen + value[1];
            externalBlue = externalBlue + value[2];
            externalCount++;
        }
        else
        {
            internalRed = internalRed + value[0];
            internalGreen = internalGreen + value[1];
            internalBlue = internalBlue + value[2];
            internalCount++;
        }
    }
}

int externalAvgRed = (int)(externalRed / externalCount);
int externalAvgGreen = (int)(externalGreen / externalCount);
int externalAvgBlue = (int)(externalBlue / externalCount);

int internalAvgRed = (int)(internalRed / internalCount);
int internalAvgGreen = (int)(externalGreen / internalCount);
int internalAvgBlue = (int)(externalBlue / internalCount);

Mat smallColoredImage = new Mat();
Mat mean = new Mat();
Mat covar = new Mat();
MatOfFloat invcovar = new MatOfFloat(3,3);

Imgproc.resize(coloredImage, smallColoredImage, new Size(3, 3));

Core.calcCovarMatrix(smallColoredImage, covar, mean, Core.COVAR_NORMAL+Core.COVAR_ROWS, -1);

Core.invert(covar, invcovar, Core.DECOMP_SVD);

MatOfFloat mu0 = new MatOfFloat(3,1);
MatOfFloat mu1 = new MatOfFloat(3,1);

mu0.put(0, 0, externalAvgRed);
mu0.put(1, 0, externalAvgGreen);
mu0.put(2, 0, externalAvgGreen);

mu1.put(0, 0, internalAvgRed);
mu1.put(1, 0, internalAvgGreen);
mu1.put(2, 0, internalAvgBlue);

double d2 = Core.Mahalanobis(mu1, mu0, invcovar);
edit retag flag offensive close merge delete