本文中實作模糊檢測的原理如下:
對采集到的人臉圖像進行如下處理:
1.高斯模糊去噪,
2.轉換灰階圖,
3.在此圖像上利用拉普拉斯算子濾波,
4.直方圖歸一化映射到0-255,
5.求均值,
檢測方法:若該均值大于給定門檻值,則認為是清晰照片,否則,是模糊照片。
實驗結果表明:
正常人臉圖檔經處理後均值在500以上,而模糊人臉隻有幾十到兩三百,很難使用拉普拉斯算子提取到有效邊緣。
(數值可能不對,讀者可親測)
缺陷 :隻對運動模糊人臉有效,且圖檔未經美圖處理
代碼如下:
//模糊檢測,如果原圖像是模糊圖像,傳回0,否則傳回1
bool blurDetect(Mat srcImage, double &blurPer){
Mat srcBlur, gray1, gray2, gray3, dstImage;
double thre = ; //控制門檻值
//pyrDown(srcImage, dstImage, Size(srcImage.cols/2, srcImage.rows/2));
GaussianBlur(srcImage, srcBlur, Size(, ), , , BORDER_DEFAULT); //高斯濾波
//imshow("sas", srcBlur);
//imshow("ssas", srcImage);
convertScaleAbs(srcBlur, srcImage); //使用線性變換轉換輸入數組元素成8位無符号整型 歸一化為0-255
if (srcImage.channels() != )
{
//進行灰階化
cvtColor(srcImage, gray1, CV_BGR2GRAY);
} else
{
gray1 = srcImage.clone();
}
Mat tmp_m1, tmp_sd1; //用來存儲均值和方差
double m1 = , sd1 = ;
//使用3x3的Laplacian算子卷積濾波
//imshow("Lap千", gray1);
//waitKey(0);
Laplacian(gray1, gray2, CV_16S, , , , BORDER_DEFAULT);
/*double minVal, maxVal;
minMaxLoc(gray2, &minVal, &maxVal);
double alpha = 255 / (maxVal - minVal), beta = -255 * minVal / (maxVal - minVal);*/
////歸到0~255
convertScaleAbs(gray2, gray3);
//imshow("Lap", gray3);
//計算均值和方差
meanStdDev(gray3, tmp_m1, tmp_sd1);
//imshow("Lap後", gray3);
//waitKey(0);
m1 = tmp_m1.at<double>(, ); //均值
sd1 = tmp_sd1.at<double>(, ); //标準差
//cout << "原圖像:" << endl;
//cout << "均值: " << m1 << " , 方差: " << sd1*sd1 << endl;
blurPer = sd1*sd1; //方差
//waitKey(0);
if (blurPer < thre) return ;
else return ;
}
結果如下:
從上向下圖檔分别為:
其中前兩張為模糊人臉