0
点赞
收藏
分享

微信扫一扫

Java中的lambda表达式与Stream API:高效的函数式编程

接上篇:

信息熵

我还尝试了使用信息熵的方式:

图像也可以采用信息熵的方式来计算图像中的信息多少。

  • 基本概念:图像信息熵是一种特征的统计形式,反映了图像中平均信息量的多少。它表示图像灰度分布的聚集特征所包含的信息量。图像信息熵通常用来衡量图像的“繁忙”程度或复杂性。较高的熵值通常意味着图像具有更高的细节和复杂度,而较低的熵值则可能表明图像较为简单或模糊。
  • 计算方法:图像信息熵可以通过灰度直方图来计算。对于灰度图像,首先计算每个灰度值出现的概率,然后根据这些概率使用公式计算熵。熵的计算公式为:H(x) = ∑ p(i) log2 p(i),其中p(i)是灰度值为i的像素出现的概率。

代码:

double calcImageEntropy(cv::Mat img)
{
    if (img.channels() == 3)
    {
        cv::cvtColor(img, img, cv::COLOR_RGB2GRAY);
    }

    cv::Mat hist;
    int histSize = 256;
    float range[] = { 0, 256 };
    const float* histRange = { range };

    cv::calcHist(&img, 1, 0, cv::Mat(), hist, 1, &histSize, &histRange);

    vector<float> p_hist;
    float total = 0.0f, total_result = 0.0f;

    for (int i = 0; i < histSize; i++)
    {
        total += hist.at<int>(i, 0);
    }


    for (int i = 0; i < histSize; i++)
    {
        float p = hist.at<int>(i, 0) / total;
        float logP = 0.0f;

        if (p == 0)
        {
            logP = 0.0f;
        }
        else
        {
            logP = log2(p);
        }
        
        total_result += p * logP;
    }

    return total_result;
}

效果不明显。

高斯模糊

有一个思路是,如果一个图像是清晰的,那么抗模糊能力也是相对较强。可以针对图像做两个不同kernel size的高斯模糊,然后两者相减,得到的就是相对清晰的高频分量。谁的分量留的多,谁就更清晰。

代码:

double calcGaussVariance(cv::Mat img) 
{
    cv::Mat gaussKernel_3, guassKernel_7, divMat, mean, std;

    if (img.channels() == 3)
    { 
        cv::cvtColor(img, img, cv::COLOR_RGB2GRAY);
    }

    cv::GaussianBlur(img, gaussKernel_3, cv::Size(3, 3), 50, 50);

    cv::GaussianBlur(img, guassKernel_7, cv::Size(7, 7), 50, 50);

    divMat = guassKernel_7 - gaussKernel_3;

    cv::meanStdDev(divMat, mean, std);

    return std.at<double>(0, 0);
}

代码中的meanStdDev是计算方差的opencv库函数。

经过试验,该方法有效。

举报

相关推荐

0 条评论