You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
3.9 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <vector>
#include <iostream>
#include <exception>
#include <opencv2/opencv.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/video.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/video/background_segm.hpp>
#include <sys/time.h>
#include "ImageDetectConfig.h"
#include "log_manager.h"
using namespace std;
using namespace cv;
// cast 计算出的偏差值小于1.0表示比较正常大于1.0表示存在亮度异常;
// 当cast异常时da大于0表示过亮da小于0表示过暗。
void detect_brightness(cv::Mat input_img, float& cast, float& da)
{
cv::Mat gray_img;
cv::cvtColor(input_img, gray_img, COLOR_BGR2GRAY);
float a = 0, Ma = 0;
int hist[256] = { 0 };
for (int i = 0; i < gray_img.rows; i++)
{
for (int j = 0; j < gray_img.cols; j++) {
a += float(gray_img.at<uchar>(i, j) - 128); // 在计算过程中考虑128为亮度均值点
hist[gray_img.at<uchar>(i, j)]++;
}
}
da = a / float(gray_img.total());
for (int i = 0; i < 256; i++) {
Ma += abs(i - 128 - da) * hist[i];
}
Ma /= float(gray_img.total());
cast = abs(da) / abs(Ma);
}
void detect_saturation(cv::Mat input_img, float& satu)
{
Mat dstImage1;
cvtColor(input_img, dstImage1, COLOR_RGB2HSV);
vector<Mat> channels;
split(dstImage1, channels);//分离HSV
Scalar mean; //均值
Scalar stddev; //标准差
meanStdDev( channels[1], mean, stddev ); //计算均值和标准差
satu = mean.val[0];
}
void detect_graydiff(cv::Mat img, float& CON, float& ASM, float& ENT, float& MEAN)
{
Mat mi;
int row = img.rows;
int col = img.cols;
//CON=i*i*P(I)
//计算i
mi.create(row, col, img.type());
for (int i = 0; i < row-1; i++)
for (int j = 0; j < col; j++)
{
//cout << "BEF" << int(img.ptr<uchar>(i)[j]) << endl;
mi.at<Vec3b>(i, j) = img.at<Vec3b>(i + 1, j) - img.at<Vec3b>(i, j);
//cout << "IMF:" << int(mi.ptr<uchar>(i)[j]) << endl;
}
//计算p(I) 差值的概率
int new_cols = mi.cols;
int new_rows = mi.rows;
int gray[256] = { 0 };
double gray_prob[256] = { 0 };
int num = 0;// 像素的总个数
//统计直方图各个像素灰度值
for (int i = 0; i < mi.rows; i++)
{
uchar *p = mi.ptr<uchar>(i);
for (int j = 0; j < mi.cols; j++)
{
int value = p[j];
gray[value]++;
num++;
}
}
//计算直方图概率分布
for (int i = 0; i < 256; i++)
{
gray_prob[i] = ((double)gray[i] / num);
}
CON = 0.0;
ASM = 0.0;
ENT = 0.0;
MEAN = 0.0;
double v = 1.0/ 255.0;
for (int i = 0; i <= 255; i++)
{
CON += i*i*gray_prob[i];//计算CON
ASM += gray_prob[i] * gray_prob[i];//计算角度方向二阶矩
if (gray_prob[i]!=0)
ENT += (0-gray_prob[i] * log10(gray_prob[i]));//计算熵
MEAN += v*i*gray_prob[i];//计算平均值
}
return;
}
void detect_definition(cv::Mat input_img, float& sb, float& lap, float& dev)
{
Mat imgGray, imgSobel, imgLap, imgDev, meanValueImage;
cvtColor(input_img, imgGray, CV_BGR2GRAY);
Sobel(imgGray, imgSobel, CV_16U, 1, 1);
Laplacian(imgGray, imgLap, CV_16U);
meanStdDev(imgGray,meanValueImage,imgDev);
sb = mean(imgSobel)[0];
lap = mean(imgLap)[0];
dev = mean(imgDev)[0];
}
int main(int argc, char *argv[])
{
Mat img = imread(argv[1]);
float cast, da, satu, CON, ASM, ENT, MEAN, sb, lap, dev;
Mat img_brightness = img.clone();
detect_brightness(img_brightness, cast, da);
Mat img_saturation = img.clone();
detect_saturation(img_saturation, satu);
Mat img_graydiff = img.clone();
detect_graydiff(img_graydiff, CON, ASM, ENT, MEAN);
Mat img_definition = img.clone();
detect_definition(img_definition, sb, lap, dev);
cout<<cast<<"||"<<da<<"||"<<satu<<"||"<<CON<<"||"<<ASM<<"||"<<ENT<<"||"<<MEAN<<"||"<<sb<<"||"<<lap<<"||"<<dev;
return 0;
}