vendor: OpenCV 5.0.0 snapshot at 755e50675d97db9b7d449d8bd6b09888646f6c6e

This commit is contained in:
Gitea Mirror Bot
2026-08-22 00:11:13 +08:00
commit 12022378a3
3872 changed files with 2513409 additions and 0 deletions
@@ -0,0 +1,243 @@
#include <fstream>
#include "opencv2/quality.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/ml.hpp"
/*
BRISQUE evaluator using TID2008
TID2008:
http://www.ponomarenko.info/tid2008.htm
[1] N. Ponomarenko, V. Lukin, A. Zelensky, K. Egiazarian, M. Carli,
F. Battisti, "TID2008 - A Database for Evaluation of Full-Reference
Visual Quality Assessment Metrics", Advances of Modern
Radioelectronics, Vol. 10, pp. 30-45, 2009.
[2] N. Ponomarenko, F. Battisti, K. Egiazarian, J. Astola, V. Lukin
"Metrics performance comparison for color image database", Fourth
international workshop on video processing and quality metrics
for consumer electronics, Scottsdale, Arizona, USA. Jan. 14-16, 2009, 6 p.
*/
namespace {
// get ordinal ranks of data, fractional ranks assigned for ties. O(n^2) time complexity
// optional binary predicate used for rank ordering of data elements, equality evaluation
template <typename T, typename PrEqual = std::equal_to<T>, typename PrLess = std::less<T>>
std::vector<float> rank_ordinal(const T* data, std::size_t sz, PrEqual&& eq = {}, PrLess&& lt = {})
{
std::vector<float> result{};
result.resize(sz, -1);// set all ranks to -1, indicating not yet done
int rank = 0;
while (rank < (int)sz)
{
std::vector<int> els = {};
for (int i = 0; i < (int)sz; ++i)
{
if (result[i] < 0)//not yet done
{
if (!els.empty())// already found something
{
if (lt(data[i], data[els[0]]))//found a smaller item, replace existing
{
els.clear();
els.emplace_back(i);
}
else if (eq(data[i], data[els[0]]))// found a tie, add to vector
els.emplace_back(i);
}
else//els.empty==no current item, add it
els.emplace_back(i);
}
}
CV_Assert(!els.empty());
// compute, assign arithmetic mean
const auto assigned_rank = (double)rank + (double)(els.size() - 1) / 2.;
for (auto el : els)
result[el] = (float)assigned_rank;
rank += (int)els.size();
}
return result;
}
template <typename T>
double pearson(const T* x, const T* y, std::size_t sz)
{
// based on https://www.geeksforgeeks.org/program-spearmans-rank-correlation/
double sigma_x = {}, sigma_y = {}, sigma_xy = {}, sigma_xsq = {}, sigma_ysq = {};
for (unsigned i = 0; i < sz; ++i)
{
sigma_x += x[i];
sigma_y += y[i];
sigma_xy += x[i] * y[i];
sigma_xsq += x[i] * x[i];
sigma_ysq += y[i] * y[i];
}
const double
num = (sz * sigma_xy - sigma_x * sigma_y)
, den = std::sqrt(((double)sz*sigma_xsq - sigma_x * sigma_x) * ((double)sz*sigma_ysq - sigma_y * sigma_y))
;
return num / den;
}
// https://en.wikipedia.org/wiki/Spearman%27s_rank_correlation_coefficient
template <typename T>
double spearman(const T* x, const T* y, std::size_t sz)
{
// convert x, y to ranked integral vectors
const auto
x_rank = rank_ordinal(x, sz)
, y_rank = rank_ordinal(y, sz)
;
return pearson(x_rank.data(), y_rank.data(), sz);
}
// returns cv::Mat of columns: { Distortion Type ID, MOS_Score, Brisque_Score }
cv::Mat tid2008_eval(const std::string& root, cv::quality::QualityBRISQUE& alg)
{
const std::string
mos_with_names_path = root + "mos_with_names.txt"
, dist_imgs_root = root + "distorted_images/"
;
cv::Mat result(0, 3, CV_32FC1);
// distortion types we care about
static const std::vector<int> distortion_types = {
10 // jpeg compression
, 11 // jp2k compression
, 1 // additive gaussian noise
, 8 // gaussian blur
};
static const int
num_images = 25 // [I01_ - I25_], file names
, num_distortions = 4 // num distortions per image
;
// load mos_with_names. format: { mos, fname }
std::vector<std::pair<float, std::string>> mos_with_names = {};
std::ifstream mos_file(mos_with_names_path, std::ios::in);
while (true)
{
std::string line;
std::getline(mos_file, line);
if (!line.empty())
{
const auto space_pos = line.find(' ');
CV_Assert(space_pos != line.npos);
mos_with_names.emplace_back(std::make_pair(
(float)std::atof(line.substr(0, space_pos).c_str())
, line.substr(space_pos + 1)
));
}
if (mos_file.peek() == EOF)
break;
};
// foreach image
// foreach distortion type
// foreach distortion level
// distortion type id, mos value, brisque value
for (int i = 0; i < num_images; ++i)
{
for (int ty = 0; ty < (int)distortion_types.size(); ++ty)
{
for (int dist = 1; dist <= num_distortions; ++dist)
{
float mos_val = 0.f;
const std::string img_name = std::string("i")
+ (((i + 1) < 10) ? "0" : "")
+ std::to_string(i + 1)
+ "_"
+ ((distortion_types[ty] < 10) ? "0" : "")
+ std::to_string(distortion_types[ty])
+ "_"
+ std::to_string(dist)
+ ".bmp";
// find mos
bool found = false;
for (const auto& val : mos_with_names)
{
if (val.second == img_name)
{
found = true;
mos_val = val.first;
break;
}
}
CV_Assert(found);
// do brisque
auto img = cv::imread(dist_imgs_root + img_name);
// typeid, mos, brisque
cv::Mat row(1, 3, CV_32FC1);
row.at<float>(0) = (float)distortion_types[ty];
row.at<float>(1) = mos_val;
row.at<float>(2) = (float)alg.compute(img)[0];
result.push_back(row);
}// dist
}//ty
}//i
return result;
}
}
inline void printHelp()
{
using namespace std;
cout << " Demo of comparing BRISQUE quality assessment model against TID2008 database." << endl;
cout << " A. Mittal, A. K. Moorthy and A. C. Bovik, 'No Reference Image Quality Assessment in the Spatial Domain'" << std::endl << std::endl;
cout << " Usage: program <tid2008_path> <brisque_model_path> <brisque_range_path>" << endl << endl;
}
int main(int argc, const char * argv[])
{
using namespace cv::ml;
if (argc != 4)
{
printHelp();
exit(1);
}
std::cout << "Evaluating database at " << argv[1] << "..." << std::endl;
const auto ptr = cv::quality::QualityBRISQUE::create(argv[2], argv[3]);
const auto data = tid2008_eval( std::string( argv[1] ) + "/", *ptr );
// create contiguous mats
const auto mos = data.col(1).clone();
const auto brisque = data.col(2).clone();
// calc srocc
const auto cc = spearman((const float*)mos.data, (const float*)brisque.data, data.rows);
std::cout << "SROCC: " << cc << std::endl;
return 0;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,25 @@
%YAML:1.0
---
range: !!opencv-matrix
rows: 2
cols: 36
dt: f
data: [ 3.44000012e-01, 1.92631185e-02, 2.31999993e-01,
-1.25608176e-01, 1.54766443e-04, 5.36677078e-04, 2.47999996e-01,
-1.25662684e-01, 1.56631286e-04, 5.32896898e-04, 2.64999986e-01,
-1.37013525e-01, 1.69135848e-04, 3.88529879e-04, 2.68999994e-01,
-1.45002097e-01, 1.74277433e-04, 4.11326590e-04, 4.09000009e-01,
1.65343825e-02, 2.17999995e-01, -2.00738415e-01, 1.03299266e-04,
8.17875145e-04, 2.28000000e-01, -1.98958635e-01, 1.15834941e-04,
8.49922828e-04, 2.46000007e-01, -1.55001476e-01, 1.20401361e-04,
3.38587241e-04, 2.47999996e-01, -1.48134664e-01, 1.16321200e-04,
3.34327371e-04, 10., 8.07274520e-01, 1.64100003e+00,
2.02751741e-01, 7.14265108e-01, 4.68011886e-01, 1.63699996e+00,
1.79955900e-01, 7.12509930e-01, 4.68246639e-01, 1.54499996e+00,
1.01060480e-01, 6.86503410e-01, 5.31757474e-01, 1.54900002e+00,
1.00678936e-01, 6.87403798e-01, 5.33775926e-01, 3.73600006e+00,
8.01105976e-01, 1.10699999e+00, 1.75127238e-01, 7.52403796e-01,
4.00098890e-01, 1.09300005e+00, 1.56139076e-01, 7.52328634e-01,
4.06460851e-01, 1.04900002e+00, 9.35277343e-02, 6.23002231e-01,
5.31899512e-01, 1.05200005e+00, 9.37106311e-02, 6.25087202e-01,
5.38609207e-01 ]
@@ -0,0 +1,176 @@
#include <sstream>
#include <iostream>
#include "opencv2/quality.hpp"
#include "opencv2/quality/quality_utils.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/ml.hpp"
/*
BRISQUE Trainer using LIVE DB R2
http://live.ece.utexas.edu/research/Quality/subjective.htm
H.R. Sheikh, Z.Wang, L. Cormack and A.C. Bovik, "LIVE Image Quality Assessment Database Release 2", http://live.ece.utexas.edu/research/quality .
H.R. Sheikh, M.F. Sabir and A.C. Bovik, "A statistical evaluation of recent full reference image quality assessment algorithms", IEEE Transactions on Image Processing, vol. 15, no. 11, pp. 3440-3451, Nov. 2006.
Z. Wang, A.C. Bovik, H.R. Sheikh and E.P. Simoncelli, "Image quality assessment: from error visibility to structural similarity," IEEE Transactions on Image Processing , vol.13, no.4, pp. 600- 612, April 2004.
*/
/*
Copyright (c) 2011 The University of Texas at Austin
All rights reserved.
Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy,
modify, and distribute this code (the source files) and its documentation for
any purpose, provided that the copyright notice in its entirety appear in all copies of this code, and the
original source of this code, Laboratory for Image and Video Engineering (LIVE, http://live.ece.utexas.edu)
and Center for Perceptual Systems (CPS, http://www.cps.utexas.edu) at the University of Texas at Austin (UT Austin,
http://www.utexas.edu), is acknowledged in any publication that reports research using this code. The research
is to be cited in the bibliography as:
1) A. Mittal, A. K. Moorthy and A. C. Bovik, "BRISQUE Software Release",
URL: http://live.ece.utexas.edu/research/quality/BRISQUE_release.zip, 2011
2) A. Mittal, A. K. Moorthy and A. C. Bovik, "No Reference Image Quality Assessment in the Spatial Domain"
submitted
IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT AUSTIN BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS DATABASE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF TEXAS
AT AUSTIN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
THE UNIVERSITY OF TEXAS AT AUSTIN SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE DATABASE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
AND THE UNIVERSITY OF TEXAS AT AUSTIN HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
/* Original Paper: @cite Mittal2 and Original Implementation: @cite Mittal2_software */
namespace {
#define CATEGORIES 5
#define IMAGENUM 982
#define JP2KNUM 227
#define JPEGNUM 233
#define WNNUM 174
#define GBLURNUM 174
#define FFNUM 174
// collects training data from LIVE R2 database
// returns {features, responses}, 1 row per image
std::pair<cv::Mat, cv::Mat> collect_data_live_r2(const std::string& foldername)
{
FILE* fid = nullptr;
//----------------------------------------------------
// class is the distortion category, there are 982 images in LIVE database
std::vector<std::string> distortionlabels;
distortionlabels.push_back("jp2k");
distortionlabels.push_back("jpeg");
distortionlabels.push_back("wn");
distortionlabels.push_back("gblur");
distortionlabels.push_back("fastfading");
int imnumber[5] = { 0,227,460,634,808 };
std::vector<int>categorylabels;
categorylabels.insert(categorylabels.end(), JP2KNUM, 0);
categorylabels.insert(categorylabels.end(), JPEGNUM, 1);
categorylabels.insert(categorylabels.end(), WNNUM, 2);
categorylabels.insert(categorylabels.end(), GBLURNUM, 3);
categorylabels.insert(categorylabels.end(), FFNUM, 4);
int iforg[IMAGENUM];
fid = fopen((foldername + "orgs.txt").c_str(), "r");
for (int itr = 0; itr < IMAGENUM; itr++)
CV_Assert( fscanf(fid, "%d", iforg + itr) > 0);
fclose(fid);
float dmosscores[IMAGENUM];
fid = fopen((foldername + "dmos.txt").c_str(), "r");
for (int itr = 0; itr < IMAGENUM; itr++)
CV_Assert( fscanf(fid, "%f", dmosscores + itr) > 0 );
fclose(fid);
// features vector, 1 row per image
cv::Mat features(0, 0, CV_32FC1);
// response vector, 1 row per image
cv::Mat responses(0, 1, CV_32FC1);
for (int itr = 0; itr < IMAGENUM; itr++)
{
//Dont compute features for original images
if (iforg[itr])
continue;
// append dmos score
float score = dmosscores[itr];
responses.push_back(cv::Mat(1, 1, CV_32FC1, (void*)&score));
// load image, calc features
std::string imname = "";
imname.append(foldername);
imname.append("/");
imname.append(distortionlabels[categorylabels[itr]].c_str());
imname.append("/img");
imname += std::to_string((itr - imnumber[categorylabels[itr]] + 1));
imname.append(".bmp");
cv::Mat im_features;
cv::quality::QualityBRISQUE::computeFeatures(cv::imread(imname), im_features); // outputs a row vector
features.push_back(im_features.row(0)); // append row vector
}
return std::make_pair(std::move(features), std::move(responses));
} // collect_data_live_r2
}
inline void printHelp()
{
using namespace std;
cout << " Demo of training BRISQUE quality assessment model using LIVE R2 database." << endl;
cout << " A. Mittal, A. K. Moorthy and A. C. Bovik, 'No Reference Image Quality Assessment in the Spatial Domain'" << std::endl << std::endl;
cout << " Usage: program <live_r2_db_path> <output_model_path> <output_range_path>" << endl << endl;
}
int main(int argc, const char * argv[])
{
using namespace cv::ml;
if (argc != 4)
{
printHelp();
exit(1);
}
std::cout << "Training BRISQUE on database at " << argv[1] << "..." << std::endl;
// collect data from the data set
auto data = collect_data_live_r2( std::string( argv[1] ) + "/" );
// extract column ranges for features
const auto range = cv::quality::quality_utils::get_column_range(data.first);
// scale all features from -1 to 1
cv::quality::quality_utils::scale<float>(data.first, range, -1.f, 1.f);
// do training, output train file
// libsvm call from original BRISQUE impl: svm-train -s 3 -g 0.05 -c 1024 -b 1 -q train_scale allmodel
auto svm = SVM::create();
svm->setType(SVM::Types::EPS_SVR);
svm->setKernel(SVM::KernelTypes::RBF);
svm->setGamma(0.05);
svm->setC(1024.);
svm->setTermCriteria(cv::TermCriteria(cv::TermCriteria::Type::EPS, 1000, 0.001));
svm->setP(.1);// default p (epsilon) from libsvm
svm->train(data.first, cv::ml::ROW_SAMPLE, data.second);
svm->save( argv[2] ); // save to location specified in argv[2]
// output scale file to argv[3]
cv::Mat range_mat(range);
cv::FileStorage fs(argv[3], cv::FileStorage::WRITE );
fs << "range" << range_mat;
return 0;
}