照明标准化不返回预期结果

时间:2013-12-31 13:23:37

标签: java android c++ opencv image-processing

我正在使用OpenCV4Android处理我的图片。我想通过这项工作预先形成与我联系的照明规范化:

http://lear.inrialpes.fr/pubs/2007/TT07/Tan-amfg07a.pdf

此外,我在C ++(OpenCV)中获得了完整的实现:

https://github.com/bytefish/opencv/blob/master/misc/tan_triggs.cpp

我试图重写这段代码做Java,但我认为某处可能存在错误。所以,我从这个算法得到的结果是接近但不够好。检查上面PDF上的预期结果,例如12.这就是我得到的:

https://dl.dropboxusercontent.com/u/108321090/a1.png https://dl.dropboxusercontent.com/u/108321090/Screenshot_2013-12-31-14-09-25.png

因此背景和脸部特征之间仍然存在太多噪音,但我认为这是我的错。这是我的代码:

//GET IMAGE URI
Uri selectedImage = imageReturnedIntent.getData();

//CREATE BITMAP FROM IT
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;      

Bitmap bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), 
                        null, bmpFactoryOptions);

//CREATE OPENCV MAT OBJECT
Mat imageMat = new Mat();
Utils.bitmapToMat(bmp, imageMat);

//CONVERT TO GRAYSCALE
Mat grayMat = new Mat();
Imgproc.cvtColor(imageMat, grayMat, Imgproc.COLOR_BGR2GRAY);

//CUT OUT FACE FROM WHOLE IMAGE
(...) face detection cascades localize face and writes the region where face is located 
in array, then I create mat with only face in it:

Mat cleanFaceMatGRAY = new Mat();
cleanFaceMatGRAY = new Mat(faceDetectMatGRAY, facesArray[0]);

//PROCESSING OF MAT WITH FACE (alghorithm from PDF & .cpp file)
Mat I = tan_triggs_preprocessing(cleanFaceMatGRAY);
Core.normalize(I, I,0, 255, Core.NORM_MINMAX, CvType.CV_8UC1);

//DISPLAY MAT IN IMAGEVIEW
ivPickedPhoto.setImageBitmap(AppTools.createBitmapFromMat(I, Bitmap.Config.ARGB_8888));

使用算法的方法(因为你可以看到它从.cpp文件到OpenCV4Android的编辑/重写方法的总复制粘贴):

private Mat tan_triggs_preprocessing(Mat image) {
    float alpha = 0.1f; 
    float tau = 10.0f;
    float gamma = 0.2f; 
    int sigma0 = 1;
    int sigma1 = 2;

    // Convert to floating point:
    Mat X = image;
    X.convertTo(X, CvType.CV_32FC1);
    // Start preprocessing:
    Mat I = new Mat();
    Core.pow(X, gamma, I);
    // Calculate the DOG Image:
    {
        Mat gaussian0 = new Mat();
        Mat gaussian1 = new Mat();
        // Kernel Size:
        int kernel_sz0 = (3*sigma0);
        int kernel_sz1 = (3*sigma1);
        // Make them odd for OpenCV:
        kernel_sz0 += ((kernel_sz0 % 2) == 0) ? 1 : 0;
        kernel_sz1 += ((kernel_sz1 % 2) == 0) ? 1 : 0;
        Size ksize1 = new Size(kernel_sz0,kernel_sz0);
        Size ksize2 = new Size(kernel_sz1,kernel_sz1);
        Imgproc.GaussianBlur(I, gaussian0, ksize1, sigma0, sigma0, Imgproc.BORDER_CONSTANT);
        Imgproc.GaussianBlur(I, gaussian1, ksize2, sigma1, sigma1, Imgproc.BORDER_CONSTANT);
        Core.subtract(gaussian0, gaussian1, I);
    }

    {
        double meanI = 0.0;
        {
            Mat tmp = new Mat();
            Mat abstmp = new Mat();
            Core.absdiff(I, new Scalar(0), abstmp);
            Core.pow(abstmp, alpha, tmp);
            meanI = Core.mean(tmp).val[0];
        }
        Core.divide( Math.pow(meanI, 1.0/alpha), I, I);
    }

    {
        double meanI = 0.0;
        {
            Mat tmp = new Mat(); 
            Mat abstmp = new Mat();
            Mat mintmp = new Mat();
            Core.absdiff(I, new Scalar(0), abstmp);
            Core.min(abstmp, new Scalar(tau), mintmp);
            Core.pow(mintmp, alpha, tmp);
            meanI = Core.mean(tmp).val[0];
        }
        Core.divide( Math.pow(meanI, 1.0/alpha), I, I);
    }

    // Squash into the tanh:
    {
        for(int r = 0; r < I.rows(); r++) {
            for(int c = 0; c < I.cols(); c++) {
                I.get(r,c)[0] = Math.tanh(I.get(r,c)[0]) / tau;
            }
        }
        Core.multiply(I,new Scalar(tau), I);
    }
    return I;
}

当我重写这段代码时,我不明白的是对矩阵的迭代。在.cpp中有

I.at<float>(r,c)

我用以下内容替换它:

I.get(r,c)[0]

你认为我可能在这里丢失了一些数据,这就是为什么图像是阴暗的吗?

0 个答案:

没有答案