【问题标题】:Treshold face images in various light各种光线下的阈值人脸图像
【发布时间】:2013-12-11 21:32:56
【问题描述】:

我想问一些与二值化相关的想法/学习材料。我正在尝试创建检测人类情绪的系统。我能够获得眉毛、眼睛、鼻子、嘴巴等区域,但随后进入另一个阶段 -> 处理......

我的照片是在不同的地方/一天中的时间/天气条件下拍摄的。在二值化过程中存在问题,具有相同的阈值,一张图像是全黑的,其他看起来很好,并为我提供了我想要的信息。

我想问你的是:
1)如果有已知的方法如何使所有图像达到相同的亮度水平?
2) 如何在图像上创建阈值和亮度之间的依赖关系?

我现在尝试的是标准化图像......但没有效果,也许我做错了什么。我正在使用 OpenCV(适用于 android)

Core.normalize(cleanFaceMatGRAY, cleanFaceMatGRAY,0, 255, Core.NORM_MINMAX, CvType.CV_8U);

编辑:

我尝试了自适应阈值,OTSU - 它们对我不起作用。我在 Android 中使用 CLAHE 时遇到问题,但我设法实现了 Niblack 算法。

Core.normalize(cleanFaceMatGRAY, cleanFaceMatGRAY,0, 255, Core.NORM_MINMAX, CvType.CV_8U);
nibelBlackTresholding(cleanFaceMatGRAY, -0.2);  

private void nibelBlackTresholding(Mat image, double parameter) {
    Mat meanPowered = image.clone();
    Core.multiply(image, image, meanPowered);

    Scalar mean = Core.mean(image);
    Scalar stdmean = Core.mean(meanPowered);

    double tresholdValue = mean.val[0] + parameter * stdmean.val[0];

    int totalRows = image.rows();
    int totalCols = image.cols();

    for (int cols=0; cols < totalCols; cols++) {
        for (int rows=0; rows < totalRows; rows++) {
            if (image.get(rows, cols)[0] > tresholdValue) {
                image.put(rows, cols, 255);
            } else {
                image.put(rows, cols, 0);
            }
        }
    }
}

结果非常好,但对于某些图像仍然不够。我粘贴链接,因为图像很大,我不想占用太多屏幕:

例如,这个非常好:
https://dl.dropboxusercontent.com/u/108321090/a1.png https://dl.dropboxusercontent.com/u/108321090/a.png

但光线不好有时会产生阴影,这会产生以下效果: https://dl.dropboxusercontent.com/u/108321090/b1.png https://dl.dropboxusercontent.com/u/108321090/b.png

您有什么想法可以帮助我提高那些具有高光差(阴影)的图像的阈值吗?

编辑2:

我发现我以前的算法以错误的方式实现。 Std 的计算方式错误。在 Niblack Thresholding 中,平均值是局部值而不是全局值。我按照这个参考修复了http://arxiv.org/ftp/arxiv/papers/1201/1201.5227.pdf

private void niblackThresholding2(Mat image, double parameter, int window) {

    int totalRows = image.rows();
    int totalCols = image.cols();
    int offset = (window-1)/2;

    double tresholdValue = 0;

    double localMean = 0;
    double meanDeviation = 0;

    for (int y=offset+1; y<totalCols-offset; y++) {
        for (int x=offset+1; x<totalRows-offset; x++) {
            localMean = calculateLocalMean(x, y, image, window);
            meanDeviation = image.get(y, x)[0] - localMean;
            tresholdValue = localMean*(1 + parameter * ( (meanDeviation/(1 - meanDeviation)) - 1 ));
            Log.d("QWERTY","TRESHOLD " +tresholdValue);
            if (image.get(y, x)[0] > tresholdValue) {
                image.put(y, x, 255);
            } else {
                image.put(y, x, 0);
            }
        }
    }
}

private double calculateLocalMean(int x, int y, Mat image, int window) {
    int offset = (window-1)/2;

    Mat tempMat;
    Rect tempRect = new Rect();
    Point leftTop, bottomRight;

    leftTop = new Point(x - (offset + 1), y - (offset + 1));
    bottomRight = new Point(x + offset, y + offset);
    tempRect = new Rect(leftTop, bottomRight);
    tempMat = new Mat(image, tempRect);

    return Core.mean(tempMat).val[0];
}

7x7 窗口的结果并在参考 k 参数 = 0.34 中提出:我仍然无法摆脱脸上的阴影。
https://dl.dropboxusercontent.com/u/108321090/b2.png
https://dl.dropboxusercontent.com/u/108321090/b1.png

【问题讨论】:

    标签: android opencv image-processing signal-processing


    【解决方案1】:
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-30
    • 2011-04-02
    • 2014-02-24
    • 2018-09-16
    • 1970-01-01
    • 1970-01-01
    • 2012-03-08
    相关资源
    最近更新 更多