影象清晰度檢測程式
阿新 • • 發佈:2019-01-01
在抓拍人臉時,為丟掉抓拍質量不高的資料。寫了一個程式來測試三種清晰度檢測的演算法。
程式的主要功能是,依次讀取圖片資料夾中的圖片,進行清晰度檢測,每張圖片會得到一個清晰度打分結果。為了提高程式執行速度,將清晰度的閾值寫在cpg檔案裡,讓程式去讀cpg檔案裡的閾值,與每張圖片的打分結果比較,低於此閾值的將放入這個路徑的子資料夾(命名為threshold1)中。
並且將每張圖片的打分結果,寫入txt檔案中,視覺化打分結果。
》首先需注意的是,為了保證程式在不同閾值下正確執行,需要在每次執行時先清空掉threshold1資料夾,並將其中的圖片重新放回遍歷到的資料夾中。
這裡採用rename方式,將圖片路徑名改變,使得threshold1資料夾內的圖片移出。
》程式主體部分
用FindFirstFileA和FindNextFileA遍歷圖片資料夾內的檔案。
如果圖片資料夾中還有子資料夾,則遞迴操作。
獲得圖片路徑後再加上圖片名稱,就可以放入計算清晰度的函式中。
這裡清晰度檢測有三種方法,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); }