相机清晰度评价几种方式-code

//
// Created by sy on 19-5-15.
//

#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
#include <sys/types.h>
#include <dirent.h>

/**        常用的清晰度评价算法有:
"          频域函数  :对焦越好、高频部分越多,细节越多,图像越清晰.
"          灰度函数  :对焦越好,和周围相邻灰度点差值越大,边缘越清晰,图像越清晰。
"          信息熵函数:对焦越好,图像包含的信息熵越大,包含信息量更大,图像越清晰。
"          统计学函数:对焦越好,直方图多样性越好,图像越清晰。
 */

double pixAssement(cv::Mat src, double &time){
    cv::Mat gray,sobel,mean,image_x,image_y;
    cv::cvtColor(src,gray,CV_RGB2GRAY);
    double start,end;
    start=cv::getTickCount();
// Tenengrad 梯度
    cv::Sobel(gray,sobel,CV_16U,1,1);   //2ms
// 拉普拉斯算子;
//    cv::Laplacian(gray,sobel,CV_16U);   //3ms
// Brenner 相邻灰度差的平方
//    cv::meanStdDev(src,mean,sobel);       //0.15ms

//    cv::Mat kernel_x(3,3,CV_32F,cv::Scalar(0));
//    kernel_x.at<float>(1,2)=-1.0;
//    kernel_x.at<float>(1,1)=1.0;
//    cv::Mat kernel_y(3,3,CV_32F,cv::Scalar(0));
//    kernel_y.at<float>(0,1)=-1.0;
//    kernel_y.at<float>(1,1)=1.0;
//
//    cv::filter2D(gray,image_x,gray.depth(),kernel_x);
//    cv::filter2D(gray,image_y,gray.depth(),kernel_y);


//    SMD 灰度方差    1.2ms
//    image_x=cv::abs(image_x);
//    image_y=cv::abs(image_y);
//    sobel=image_x+image_y;

//   SMD2 灰度方差乘积  1.2ms
//    image_x=cv::abs(image_x);
//    image_y=cv::abs(image_y);
//    cv::multiply(image_x,image_y,sobel);

//   能量梯度函数  1.25ms
//    cv::multiply(image_x,image_x,image_x);
//    cv::multiply(image_y,image_y,image_y);
//    sobel=image_x+image_y;


    end=cv::getTickCount();
    std::cout << "the exe time filter : " << (end - start) / (cv::getTickFrequency())<<" s"<< std::endl;

    time=end-start;

    double meanValue=cv::mean(sobel)[0];
    return meanValue;
}
// 峰值信噪比 返回一个float30~50 越大相符程度越高
double PSNR(cv::Mat &ref,cv::Mat& src){  //2~3ms
    double psnr= cv::PSNR(ref, src);
    return psnr;
}

// 信噪比
double SNR(cv::Mat &src){

}

// 结构相似性 返回一个0~1之间的浮点数,越大越高,该算法对每一个通道有值
cv::Scalar  SSIM( cv::Mat & ref,  cv::Mat& src){
    const double C1=6.5025,C2=58.5225;
    cv::Mat average1,average2,sigma1_2,sigma2_2,sigma12,t1,t2,t3;

    ref.convertTo(ref,CV_32F);
    src.convertTo(src,CV_32F);
    cv::Mat I1_2=ref.mul(ref);
    cv::Mat I2_2=src.mul(src);
    cv::Mat I1_I2=ref.mul(src);

    cv::GaussianBlur(ref,average1,cv::Size(11,11),1.5);
    cv::GaussianBlur(src,average2,cv::Size(11,11),1.5);

    cv::Mat average1_2=average1.mul(average1);
    cv::Mat average2_2=average2.mul(average2);
    cv::Mat average12=average1.mul(average2);

    cv::GaussianBlur(I1_2,sigma1_2,cv::Size(11,11),1.5);
    sigma1_2-=average1_2;
    cv::GaussianBlur(I2_2,sigma2_2,cv::Size(11,11),1.5);
    sigma2_2-=average2_2;
    cv::GaussianBlur(I1_I2,sigma12,cv::Size(11,11),1.5);
    sigma12-=average12;

    t1=2*average12+C1;
    t2=2*sigma12+C2;
    t3=t1.mul(t2);

    t1=average1_2+average2_2+C1;
    t2=sigma1_2+sigma2_2+C2;
    t1=t1.mul(t2);

    cv::Mat SSIM;
    cv::divide(t3,t1,SSIM);
    cv::Scalar mssim=cv::mean(SSIM);
    return mssim;
}

int main(){
    cv::Mat draw=cv::Mat::zeros(cv::Size(840,680),CV_8UC3);
    for (int i = 0; i < draw.cols * draw.rows * draw.channels(); ++i) {
       draw.data[i]=255;
    }
//    cv::imshow("draw",draw);
//    cv::waitKey();


    std::string filedir="/home/sy/data/work/assement/clearness/123/";
    const char *fileDir=filedir.c_str();
    int num=0; // 文件个数;
    std::vector<float>value;
    float maxValue=0;
    double time_total=0;

    DIR * dir;
    dir =opendir(fileDir);
    struct dirent*ptr;
    while (ptr=readdir(dir)){
        if(ptr->d_name[0]=='.'){
            continue;
        }
//        char * fileDir=(char*)malloc(strlen(filedir)+strlen(ptr->d_name)+1);
//        for (int i = 0; filedir[i] !='\0' ; ++i) {
//            fileDir[i]=filedir[i];
//        }
//        for (int j = 0; ptr->d_name[j]!='\0' ; ++j) {
//            fileDir[j+strlen(filedir)]=ptr->d_name[j];
//        }
//        fileDir[strlen(filedir)+strlen(ptr->d_name)]='\0';
//        cv::Mat src=cv::imread(fileDir);
//        double value_=pixAssement(src);
//        value[num]=value_;
        num++;
    }
    for (int i = 0; i < num-1; ++i) {
        std::string filename=filedir+"image"+std::to_string(i+1)+".jpg";
        cv::Mat src=cv::imread(filename);
        double time=0;
        double value_p=pixAssement(src,time);
        time_total=time_total+time;
        value.push_back(value_p);
        if(value_p>maxValue){
            maxValue=value_p;
        }
    }

    float col_step=draw.cols/(num+1);
    float row_step=draw.rows/(maxValue+1);

    for (int k = 0; k <num-1 ; ++k) {
        std::cout<<value[k]<<std::endl;
        cv::Point p1(k*col_step,draw.rows-value[k]*row_step);
        cv::Point p2((k+1)*col_step,draw.rows-value[k+1]*row_step);
        cv::line(draw,p1,p2,cv::Scalar(255,0,0),1);
        cv::putText(draw,std::to_string(value[k]),p1,CV_FONT_HERSHEY_COMPLEX,0.3,cv::Scalar(0,0,255),1);
    }

    std::cout<<"total time:"<<time_total<<std::endl;

    std::stringstream meanValueStream;
    std::string meanValueString;
    meanValueStream >>meanValueString;
//    energy gradient
    meanValueString=" Tenengrad: average time-"+std::to_string(time_total/(num*cv::getTickFrequency()))+"s";
    cv::putText(draw,meanValueString,cv::Point(20,620),CV_FONT_HERSHEY_COMPLEX,0.6,cv::Scalar(255,0,255),2);

    std::string drawName=filedir+"assement/Tenengrad.jpg";
    cv::imwrite(drawName,draw);
    cv::imshow("draw",draw);
    cv::waitKey();
}

the best algorithm from

    cv::Mat kernel, src_32f, dst;
    float data[8][8] = {
            {-1, -1, -1, -1, -1, -1, -1, -1},
            {-1, -1, -1, -1, -1, -1, -1, -1},
            {-1, -1, 3,  3,  3,  3,  -1, -1},
            {-1, -1, 3,  3,  3,  3,  -1, -1},
            {-1, -1, 3,  3,  3,  3,  -1, -1},
            {-1, -1, 3,  3,  3,  3,  -1, -1},
            {-1, -1, -1, -1, -1, -1, -1, -1},
            {-1, -1, -1, -1, -1, -1, -1, -1}
    };
    kernel = cv::Mat(8, 8, CV_32F, data);
    gray.convertTo(src_32f, CV_32F);
    cv::filter2D(src_32f, dst, -1, kernel);
    double power = 0, score = 0;
    const int FOCUS_SCORE_50PERCENT = 60;
    for (int row = 0; row < dst.rows; ++row) {
        for (int col = 0; col < dst.cols; ++col) {
            power += abs(dst.at<float>(row, col));
        }
    }
    power = power / (dst.cols * dst.rows);
    score = ((power * power) / (power * power + FOCUS_SCORE_50PERCENT * FOCUS_SCORE_50PERCENT) * 100.0f + 0.5f);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值