1. 程式人生 > >影象清晰度檢測程式

影象清晰度檢測程式

在抓拍人臉時,為丟掉抓拍質量不高的資料。寫了一個程式來測試三種清晰度檢測的演算法。

程式的主要功能是,依次讀取圖片資料夾中的圖片,進行清晰度檢測,每張圖片會得到一個清晰度打分結果。為了提高程式執行速度,將清晰度的閾值寫在cpg檔案裡,讓程式去讀cpg檔案裡的閾值,與每張圖片的打分結果比較,低於此閾值的將放入這個路徑的子資料夾(命名為threshold1)中。

並且將每張圖片的打分結果,寫入txt檔案中,視覺化打分結果。

》首先需注意的是,為了保證程式在不同閾值下正確執行,需要在每次執行時先清空掉threshold1資料夾,並將其中的圖片重新放回遍歷到的資料夾中。

這裡採用rename方式,將圖片路徑名改變,使得threshold1資料夾內的圖片移出。

》程式主體部分

FindFirstFileAFindNextFileA遍歷圖片資料夾內的檔案。

如果圖片資料夾中還有子資料夾,則遞迴操作。

獲得圖片路徑後再加上圖片名稱,就可以放入計算清晰度的函式中。

這裡清晰度檢測有三種方法,sobel laplacian,和meanvalue

得到清晰度值後,進入對清晰度值進行判斷操作部分。

如果小於閾值,就呼叫rename函式,將圖片移到threshold1資料夾中。

參考:

#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);
}