美文网首页
图像色偏检测

图像色偏检测

作者: 一包辣 | 来源:发表于2018-07-05 10:02 被阅读0次

    色偏检测

    1 CIE LAB空间

    • L分量用于表示像素的亮度,取值范围是[0,100],表示从纯黑到纯白;
    • a表示从红色到绿色的范围,取值范围是[-128,127];
    • b表示从黄色到蓝色的范围,取值范围是[-128,127]。


      图片.png

    2 检测原理

    通常存在色偏的图像,在a和b分量上的均值会偏离原点很远,方差也会偏小;通过计算图像在a和b分量上的均值和方差,就可评估图像是否存在色偏。

    L分量的取值范围为[0,100],A和B分量都为[-128,127],为了与RGB颜色空间同一范围,OpenCV将L拉升至[0,255],把A,B位移至于[0,255],就可以同RGB颜色空间表达为同一个范围了。即使这样映射后,一般来说,LAB各分量的结果仍为浮点数,这个和RGB不同,但是在很多情况下,为了速度计效率,我们这需结果的取整部分,得到类似于RGB空间的布局。

    • 计算圆心位置:相当于计算均值,在计算过程中,要考虑将CIE Lab空间还原成(-127,124]范围(这样才能体现距离原点的距离);
    • 计算半径:相当于计算各点距离圆心的距离的均值,在计算半径时使用一个数组统计a,b的分布,也要记得将Lab空间还原;
    • 定义色差因子:色差值cast用于衡量图片色差的程度,色差值=圆心距中性点距离/半径,距中性点(均值)越大并且半径越小则色差程度越高。
        Mat BGRimg = imread("D:/20.jpg");
        Mat LABimg;
        cvtColor(BGRimg, LABimg, CV_BGR2Lab);
        float a = 0, b = 0;     // 用于记录a/b轴的平均值
        int HistA[256], HistB[256];     // 用于记录a/b轴每个色度的出现次数
        for (int i = 0; i < 256; i++)
        {
            HistA[i] = 0;
            HistB[i] = 0;
        }
        for (int i = 0; i < LABimg.rows; i++)
        {
            for (int j = 0; j < LABimg.cols; j++)
            {
                // 注意将Lab空间取值范围还原成(-127,127]
                a += (float(LABimg.at<Vec3b>(i, j)[1]) - 128);
                b += (float(LABimg.at<Vec3b>(i, j)[2]) - 128);
                // x表示在a轴的色度值
                int x = LABimg.at<Vec3b>(i, j)[1];
                int y = LABimg.at<Vec3b>(i, j)[2];
                HistA[x]++;
                HistB[x]++;
            }
        }
        // 计算圆心坐标/均值
        // da大于0,表示偏红;da小于0表示偏绿;db大于0,表示偏黄;db小于0表示偏蓝
        float da = a / float(LABimg.rows*LABimg.cols);
        float db = b / float(LABimg.rows*LABimg.cols);
        // 计算半径
        float ma = 0, mb = 0, r = 0;
        for (int i = 0; i < 256; i++)
        {
            ma += abs(i - 128 - da)*HistA[i];
            mb += abs(i - 128 - db)*HistB[i];
        }
        ma /= float(LABimg.cols*LABimg.rows);
        mb /= float(LABimg.cols*LABimg.rows);
        r = sqrt(ma * ma + mb * mb);
        float K = float(sqrt(da*da + db * db)) / float(r);
        cout << K << endl;
    

    TODO

    • 半径太大有许多半径很大但是出现次数较少对结果影响很大 尝试忽略这些干扰点

    相关文章

      网友评论

          本文标题:图像色偏检测

          本文链接:https://www.haomeiwen.com/subject/pngsuftx.html