问题描述
我正在尝试使用以下代码检测人脸图像的模糊率.
cv::Mat greyMat;cv::Mat laplacianImage;cv::Mat imageClone = LapMat.clone();cv::resize(imageClone, imageClone, cv::Size(150, 150), 0, 0, cv::INTER_CUBIC);cv::cvtColor(imageClone,greyMat,CV_BGR2GRAY);Laplacian(greyMat, laplacianImage, CV_64F);cv::标量均值,标准差;//0:1 通道、1:2 通道和 2:3 通道meanStdDev(laplacianImage, mean, stddev, cv::Mat());双方差 = stddev.val[0] * stddev.val[0];
cv::Mat M = (cv::Mat_(3, 1) <
cv::Mat Lx;cv::sepFilter2D(LapMat, Lx, CV_64F, M, G);简历::垫李;cv::sepFilter2D(LapMat, Ly, CV_64F, G, M);cv::Mat FM = cv::abs(Lx) + cv::abs(Ly);double focusMeasure = cv::mean(FM).val[0];返回焦点测量;
有时效果不佳,如附图所示.
是否有检测模糊人脸的最佳实践方法?我附上了一个示例图像,该图像得分很高,上面的代码是错误的.
最佳
我不知道你如何解释你的结果.要测量模糊度,您通常采用Blur Detector 的输出(一个数字)并将其与阈值进行比较,然后确定输入实际上是否模糊.我在你的代码中没有看到这样的比较.
有几种方法可以衡量模糊度",或者更确切地说,是清晰度.我们来看一个.它涉及计算拉普拉斯算子的方差,然后将其与预期值进行比较.这是代码:
//读取图像并将其转换为灰度:cv::Mat inputImage = cv::imread("dog.png");简历::垫灰色;cv::cvtColor(输入图像,灰色,cv::COLOR_RGB2GRAY);//很酷,让我们计算灰度图像的拉普拉斯算子:cv::Mat laplacianImage;cv::Laplacian(灰色,laplacianImage,CV_64F);//准备计算拉普拉斯算子的均值和标准差:cv::标量均值,标准差;cv::meanStdDev(laplacianImage, mean, stddev, cv::Mat() );//让我们计算方差:双方差 = stddev.val[0] * stddev.val[0];
到目前为止,我们已经有效地计算了拉普拉斯算子的方差,但我们仍然需要与阈值进行比较:
double blurThreshold = 300;如果(方差 <= blurThreshold ){std::cout<<输入图像模糊!"<<std::endl;} 别的 {std::cout<
让我们看看结果.
I am trying to detect blur rate of the face images with below code.
cv::Mat greyMat;
cv::Mat laplacianImage;
cv::Mat imageClone = LapMat.clone();
cv::resize(imageClone, imageClone, cv::Size(150, 150), 0, 0, cv::INTER_CUBIC);
cv::cvtColor(imageClone, greyMat, CV_BGR2GRAY);
Laplacian(greyMat, laplacianImage, CV_64F);
cv::Scalar mean, stddev; // 0:1st channel, 1:2nd channel and 2:3rd channel
meanStdDev(laplacianImage, mean, stddev, cv::Mat());
double variance = stddev.val[0] * stddev.val[0];
cv::Mat M = (cv::Mat_(3, 1) << -1, 2, -1); cv::Mat G = cv::getGaussianKernel(3, -1, CV_64F);
cv::Mat Lx;
cv::sepFilter2D(LapMat, Lx, CV_64F, M, G);
cv::Mat Ly;
cv::sepFilter2D(LapMat, Ly, CV_64F, G, M);
cv::Mat FM = cv::abs(Lx) + cv::abs(Ly);
double focusMeasure = cv::mean(FM).val[0];
return focusMeasure;
it some times gives not good results as attached picture.
Is there a best practice way to detect blurry faces ?I attached an example image which is high scored with above code which is false.
Best
I'm not sure how are you interpreting your results. To measure blur, you usually take the output of the Blur Detector (a number) and compare it against a threshold value, then determine if the input is, in fact, blurry or not. I don't see such a comparison in your code.
There are several ways to measure "blurriness", or rather, sharpness. Let's take a look at one. It involves computing the variance of the Laplacian and then comparing it to an expected value. This is the code:
//read the image and convert it to grayscale:
cv::Mat inputImage = cv::imread( "dog.png" );
cv::Mat gray;
cv::cvtColor( inputImage, gray, cv::COLOR_RGB2GRAY );
//Cool, let's compute the laplacian of the gray image:
cv::Mat laplacianImage;
cv::Laplacian( gray, laplacianImage, CV_64F );
//Prepare to compute the mean and standard deviation of the laplacian:
cv::Scalar mean, stddev;
cv::meanStdDev( laplacianImage, mean, stddev, cv::Mat() );
//Let’s compute the variance:
double variance = stddev.val[0] * stddev.val[0];
Up until this point, we've effectively calculated the variance of the Laplacian, but we still need to compare against a threshold:
double blurThreshold = 300;
if ( variance <= blurThreshold ) {
std::cout<<"Input image is blurry!"<<std::endl;
} else {
std::cout<<"Input image is sharp"<<std::endl;
}
Let’s check out the results. These are my test images. I've printed the variance value in the lower-left corner of the images. The threshold value is 300
, blue text is within limits, red text is below.
这篇关于如何在C++中有效地检测人脸的模糊率?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!