OpenCV每日函数 Image Quality Analysis (IQA) API 图像质量分析相关函数

一、概述

        各种图像质量分析(IQA)算法的实现:

        均方误差 (MSE)、峰值信噪比 (PSNR)、结构相似性 (SSIM)、梯度幅度相似度偏差 (GMSD)、无参考图像空间质量评估 (BRISQUE)

        一般来说,GMSD 算法应该产生最好的全参考 IQA 结果。

        所有算法都可以通过更简单的静态compute方法访问,或者通过静态create方法创建的实例访问。

        实例方法被设计为在比较一个源文件和多个比较文件时具有更高的性能,因为每次调用都不需要对源文件进行特定于算法的预处理。

        出于性能原因,建议(但不是必需)此模块的用户在处理之前将输入图像转换为灰度图像。SSIM 和 GMSD 最初由各自的研究人员在灰度 uint8 图像上进行测试,但如果用户愿意,此实现将计算每个通道的值。

        BRISQUE 是一种 NR-IQA 算法(无参考),不需要参考图像。

二、类参考

        图像质量分析各算法类继承结构如下

三、OpenCV源码

1、源码路径

opencv_contrib\modules\quality\src\qualitymse.cpp
opencv_contrib\modules\quality\src\qualityssim.cpp
opencv_contrib\modules\quality\src\qualitygmsd.cpp
opencv_contrib\modules\quality\src\qualitybrisque.cpp

2、源码代码

        MSE算法

#include "precomp.hpp"
#include "opencv2/quality/qualitymse.hpp"
#include "opencv2/quality/quality_utils.hpp"

namespace
{
    using namespace cv;
    using namespace cv::quality;

    using mse_mat_type = UMat;
    using _quality_map_type = mse_mat_type;

    // computes mse and quality map for single frame
    std::pair<cv::Scalar, _quality_map_type> compute(const mse_mat_type& lhs, const mse_mat_type& rhs)
    {
        std::pair<cv::Scalar, _quality_map_type> result;

        cv::subtract( lhs, rhs, result.second );

        // cv::pow(diff, 2., diff);
        cv::multiply(result.second, result.second, result.second); // slightly faster than pow2

        result.first = cv::mean(result.second);

        return result;
    }
}

// static
Ptr<QualityMSE> QualityMSE::create( InputArray ref )
{
    return Ptr<QualityMSE>(new QualityMSE(quality_utils::expand_mat<mse_mat_type>(ref)));
}

// static
cv::Scalar QualityMSE::compute( InputArray ref_, InputArray cmp_, OutputArray qualityMap )
{
    auto ref = quality_utils::expand_mat<mse_mat_type>(ref_);
    auto cmp = quality_utils::expand_mat<mse_mat_type>(cmp_);

    auto result = ::compute(ref, cmp);

    if (qualityMap.needed())
        qualityMap.assign(result.second);

    return result.first;
}

cv::Scalar QualityMSE::compute( InputArray cmp_ )
{
    auto cmp = quality_utils::expand_mat<mse_mat_type>(cmp_);
    auto result = ::compute( this->_ref, cmp );
    OutputArray(this->_qualityMap).assign(result.second);
    return result.first;
}

        SSIM算法 

// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.

#include "precomp.hpp"
#include "opencv2/quality/qualityssim.hpp"
#include "opencv2/imgproc.hpp"  // GaussianBlur
#include "opencv2/quality/quality_utils.hpp"

namespace
{
    using namespace cv;
    using namespace cv::quality;

    using _mat_type = UMat;
    using _quality_map_type = _mat_type;

    // SSIM blur function
    _mat_type blur(const _mat_type& mat)
    {
        _mat_type result = {};
        cv::GaussianBlur( mat, result, cv::Size(11, 11), 1.5 );
        return result;
    }
}   // ns

QualitySSIM::_mat_data::_mat_data( const _mat_type& mat )
{
    this->I = mat;
    cv::multiply(this->I, this->I, this->I_2);
    this->mu = ::blur(this->I);
    cv::multiply(this->mu, this->mu, this->mu_2);
    this->sigma_2 = ::blur(this->I_2);    // blur the squared img, subtract blurred_squared
    cv::subtract(this->sigma_2, this->mu_2, this->sigma_2);
}

QualitySSIM::_mat_data::_mat_data(InputArray arr )
    : _mat_data( quality_utils::expand_mat<mat_type>(arr) )    // delegate
{}

// static
Ptr<QualitySSIM> QualitySSIM::create( InputArray ref )
{
    return Ptr<QualitySSIM>(new QualitySSIM( _mat_data( ref )));
}

// static
cv::Scalar QualitySSIM::compute( InputArray ref, InputArray cmp, OutputArray qualityMap )
{
    auto result = _mat_data::compute( _mat_data(ref), _mat_data(cmp) );

    if (qualityMap.needed())
        qualityMap.assign(result.second);

    return result.first;
}

cv::Scalar QualitySSIM::compute( InputArray cmp )
{
    auto result = _mat_data::compute(
        this->_refImgData
        , _mat_data(cmp)
    );

    OutputArray(this->_qualityMap).assign(result.second);
    return result.first;
}

// static.  computes ssim and quality map for single frame
// based on https://docs.opencv.org/2.4/doc/tutorials/highgui/video-input-psnr-ssim/video-input-psnr-ssim.html
std::pair<cv::Scalar, _mat_type> QualitySSIM::_mat_data::compute(const _mat_data& lhs, const _mat_data& rhs)
{
    const double
        C1 = 6.5025
        , C2 = 58.5225
        ;

    mat_type
        I1_I2
        , mu1_mu2
        , t1
        , t2
        , t3
        , sigma12
        ;

    cv::multiply(lhs.I, rhs.I, I1_I2);
    cv::multiply(lhs.mu, rhs.mu, mu1_mu2);
    cv::subtract(::blur(I1_I2), mu1_mu2, sigma12);

    // t3 = ((2*mu1_mu2 + C1).*(2*sigma12 + C2))
    cv::multiply(mu1_mu2, 2., t1);
    cv::add(t1, C1, t1);// t1 += C1

    cv::multiply(sigma12, 2., t2);
    cv::add(t2, C2, t2);// t2 += C2

    // t3 = t1 * t2
    cv::multiply(t1, t2, t3);

    // t1 =((mu1_2 + mu2_2 + C1).*(sigma1_2 + sigma2_2 + C2))
    cv::add(lhs.mu_2, rhs.mu_2, t1);
    cv::add(t1, C1, t1);

    cv::add(lhs.sigma_2, rhs.sigma_2, t2);
    cv::add(t2, C2, t2);

    // t1 *= t2
    cv::multiply(t1, t2, t1);

    // quality map: t3 /= t1
    cv::divide(t3, t1, t3);

    return {
        cv::mean(t3)
        , std::move(t3)
    };
}   // compute

3、c++参考代码

        完整参考 IQA 算法(MSE、PSNR、SSIM、GMSD)

    #include <opencv2/quality.hpp>
    cv::Mat img1, img2; /* your cv::Mat images to compare */
    cv::Mat quality_map;  /* output quality map (optional) */
    /* compute MSE via static method */
    cv::Scalar result_static = quality::QualityMSE::compute(img1, img2, quality_map);  /* or cv::noArray() if not interested in output quality maps */
    /* alternatively, compute MSE via instance */
    cv::Ptr<quality::QualityBase> ptr = quality::QualityMSE::create(img1);
    cv::Scalar result = ptr->compute( img2 );  /* compute MSE, compare img1 vs img2 */
    ptr->getQualityMap(quality_map);  /* optionally, access output quality maps */

        无参考 IQA 算法 (BRISQUE)

    #include <opencv2/quality.hpp>
    cv::Mat img = cv::imread("/path/to/my_image.bmp"); // path to the image to evaluate
    cv::String model_path = "path/to/brisque_model_live.yml"; // path to the trained model
    cv::String range_path = "path/to/brisque_range_live.yml"; // path to range file
    /* compute BRISQUE quality score via static method */
    cv::Scalar result_static = quality::QualityBRISQUE::compute(img,
model_path, range_path);
    /* alternatively, compute BRISQUE via instance */
    cv::Ptr<quality::QualityBase> ptr = quality::QualityBRISQUE::create(model_path, range_path);
    cv::Scalar result = ptr->compute(img); /* computes BRISQUE score for img */

4、python参考代码

        完整参考 IQA 算法(MSE、PSNR、SSIM、GSMD)

    import cv2
    # read images
    img1 = cv2.imread(img1, 1) # specify img1
    img2 = cv2.imread(img2_path, 1) # specify img2_path
    # compute MSE score and quality maps via static method
    result_static, quality_map = cv2.quality.QualityMSE_compute(img1, img2)
    # compute MSE score and quality maps via Instance
    obj = cv2.quality.QualityMSE_create(img1)
    result = obj.compute(img2)
    quality_map = obj.getQualityMap()

        无参考 IQA 算法 (BRISQUE)

    import cv2
    # read image
    img = cv2.imread(img_path, 1) # mention img_path
    # compute brisque quality score via static method
    score = cv2.quality.QualityBRISQUE_compute(img, model_path,
range_path) # specify model_path and range_path
    # compute brisque quality score via instance
    # specify model_path and range_path
    obj = cv2.quality.QualityBRISQUE_create(model_path, range_path)
    score = obj.compute(img)

四、效果图像示例

        MSE、PSNR、SSIM、GMSD算法需要两张图片

         BRISQUE算法需要一张图片,上面图片得分28,下面图片得分69。

 五、其它相关参考

Opencv学习笔记 均方误差(MSE)、结构相似度指数(SSIM)_坐望云起的博客-CSDN博客_图像均方误差https://skydance.blog.csdn.net/article/details/108920559数字图像处理 离散余弦变换(DCT)和峰值信噪比(PSNR)_坐望云起的博客-CSDN博客_图像dct离散余弦变换,在(声音、图像)数据压缩中得到了广泛的使用。求输入图像和经过离散余弦变换之后的图像的峰值信噪比。并求出离散余弦逆变换的比特率。https://skydance.blog.csdn.net/article/details/121437383

猜你喜欢

转载自blog.csdn.net/bashendixie5/article/details/125292625
今日推荐