天天看点

图像清晰度检测程序

在抓拍人脸时,为丢掉抓拍质量不高的数据。写了一个程序来测试三种清晰度检测的算法。

程序的主要功能是,依次读取图片文件夹中的图片,进行清晰度检测,每张图片会得到一个清晰度打分结果。为了提高程序执行速度,将清晰度的阈值写在cpg文件里,让程序去读cpg文件里的阈值,与每张图片的打分结果比较,低于此阈值的将放入这个路径的子文件夹(命名为threshold1)中。

并且将每张图片的打分结果,写入txt文件中,可视化打分结果。

》首先需注意的是,为了保证程序在不同阈值下正确运行,需要在每次运行时先清空掉threshold1文件夹,并将其中的图片重新放回遍历到的文件夹中。

这里采用rename方式,将图片路径名改变,使得threshold1文件夹内的图片移出。

》程序主体部分

用FindFirstFileA和FindNextFileA遍历图片文件夹内的文件。

如果图片文件夹中还有子文件夹,则递归操作。

获得图片路径后再加上图片名称,就可以放入计算清晰度的函数中。

这里清晰度检测有三种方法,sobel laplacian,和meanvalue

得到清晰度值后,进入对清晰度值进行判断操作部分。

如果小于阈值,就调用rename函数,将图片移到threshold1文件夹中。

参考:

OpenCV 图像清晰度评价(相机自动对焦) - CSDN博客

#include <highgui/highgui.hpp>
#include <imgproc/imgproc.hpp>
#include <iostream>
#include <opencv2/opencv.hpp>  
#include <string>
#include <fstream>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <string>
#include <shlwapi.h>
#pragma comment(lib,"shlwapi.lib")
#define INI_FILE _T("cpg.ini")

using namespace cv;
using namespace std;


//int main(int argc, char *argv[])


double calculate(string fileName)
{
	string newfileName, grayFile;
	stringstream meanValueStream;
	string  meanValueString;
	
	Mat imageSource = imread(fileName);
	Mat imageGrey;
	Mat meanValueImage, meanStdValueImage;

	cvtColor(imageSource, imageGrey, CV_RGB2GRAY);
	Mat imageSobel;
	Laplacian(imageGrey, imageSobel, CV_16U, 1, 1);
	//Sobel(imageGrey, imageSobel, CV_16U, 1, 1);
	//求灰度图像的标准差
	/*meanStdDev(imageGrey, meanValueImage, meanStdValueImage);
	double meanValue = 0.0;
	meanValue = meanStdValueImage.at<double>(0, 0);
*/
	//图像的平均灰度
	double meanValue = 0.0;
	meanValue = mean(imageSobel)[0];

	meanValueStream << meanValue;
	meanValueStream >> meanValueString;

	meanValueString = fileName + ": Articulation(Laplacian):" + meanValueString;

	ofstream outfile("路径/ArticulationLaplacianresult.txt", ios::app);

	outfile << meanValueString;
	outfile << endl;
	outfile.close();

	return meanValue;
}
//double to string
void opt(string fileName, string imgname, double meanValue)
{
	char ThresholdValue[260];
	double fThresholdValue;
	string newfileName;
	WIN32_FIND_DATAA winFindData;

	GetPrivateProfileStringA("Threshold", "ThresholdValue", "", ThresholdValue, 260, "D:/AItensor/blurdetector/cpg.ini");

	fThresholdValue = atof(ThresholdValue);

	
	string str1 = winFindData.cFileName;
	newfileName = "路径/" + imgname;

	if (meanValue <= fThresholdValue)
	{
		rename(fileName.c_str(), newfileName.c_str());

	}

}

void judge(const string &strPath)
{
	string fileName, filePath;
	double meanValue;

	string strRawPath = strPath;//传地址
	strRawPath.append("\\");//加分隔符

	string strFindPath = strRawPath;//在新设一个
	strFindPath.append("*.*");//在最外面的目录下查找文件

	WIN32_FIND_DATAA winFindData;

	HANDLE hTemp = FindFirstFileA(strFindPath.c_str(), &winFindData);//c.str是因为这个函数需要cha类型,返回找到的数据

																	 //if (INVALID_HANDLE_VALUE == hTemp)
																	 //	return 0;
	while (FindNextFileA(hTemp, &winFindData))
	{
		string strOldName = winFindData.cFileName;
		if ("." == strOldName || ".." == strOldName)
			continue;
		//如果是目录,则递归继续操作
		if (winFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		{
			string strAgain = strPath;
			strAgain.append("\\");
			strAgain.append(winFindData.cFileName);
			judge(strAgain);
			continue;
		}
		//获得绝对路径
		strOldName = strRawPath;
		//strOldName.append(winFindData.cFileName);
		filePath = strRawPath;
		string fileName = strOldName + winFindData.cFileName;
		//string strNewName = strOldName;
		string imgname = winFindData.cFileName;
		meanValue = calculate(fileName);
		opt(fileName, imgname, meanValue);
		//return fileName, filePath, imgname;
	}
	FindClose(hTemp);
}

void rename(const string &strPath, const string &strPathroot)
{
	string fileName, filePath;
	double meanValue;

	string strRawPath = strPath;//传地址
	strRawPath.append("\\");//加分隔符

	string strFindPath = strRawPath;//在新设一个
	strFindPath.append("*.*");//在最外面的目录下查找文件

	WIN32_FIND_DATAA winFindData;

	HANDLE hTemp = FindFirstFileA(strFindPath.c_str(), &winFindData);//c.str是因为这个函数需要cha类型,返回找到的数据

																	 //if (INVALID_HANDLE_VALUE == hTemp)
																	 //	return 0;
	while (FindNextFileA(hTemp, &winFindData))
	{
		string imgname = winFindData.cFileName;
		//newfilePath = strRawPath;
		string fileName = strRawPath + winFindData.cFileName;
		//string strNewName = strOldName;
		string newfileName = strPathroot + winFindData.cFileName;
		rename(fileName.c_str(), newfileName.c_str());
		//return fileName, filePath, imgname;
	}
	FindClose(hTemp);
}

int main(int argc, char *argv[])
{
	string thresholdName = "路径/threshold1";
	string newthresholdName = "路径/";
	rename(thresholdName, newthresholdName);
	string path = "路径";
	judge(path);
}
           

继续阅读