Simple image blur detection based on Laplacian

Posted by info@ipfaces.org on Thu, 09 Dec 2021 17:53:39 +0100

pexels-dinnow-9469740.jpg

Business background

Since the end of last year, our team has been making an intelligent hardware that can automatically take pictures of e-commerce products. After taking photos, the set of pictures of commodities will be displayed on the e-commerce platform.

For the commodity pictures to be displayed, we have high requirements for the quality of the pictures themselves. For example, ambiguous pictures cannot be displayed. Therefore, we need a method of image blur detection, which is convenient for us to screen the available images.

We use Laplacian based algorithm to detect whether the image is blurred. It's easier to call because OpenCV has a built-in Laplacian function.

Laplacian operator

The mapping to find the second derivative of multivariate functions is called Laplacian operator, which is equivalent to the derivative of second-order Sobel operator.

Definition of Laplacian operator:

Laplacian operator

We obtain the Laplace operator of discrete function by making difference on the second derivative of Laplace operator in X and Y directions.

Take the x direction as an example: First order difference: f'(x) = f(x) - f(x - 1) Second order difference: f''(x) = f'(x+1) - f'(x) = (f(x + 1) - f(x)) - (f(x) - f(x - 1)) After simplification: F '' (x) = f (x - 1) - 2 (f (x)) + F (x + 1)

Extract the previous coefficient: [1, - 2, 1]

Similarly, the coefficients in the y direction [1, - 2,1] can be obtained

The Laplace matrix is obtained by superposition

laplacian matrix

Laplace 3x3 convolution kernel.

Image blur detection algorithm

The main idea of the algorithm: first convert the image into a gray image, and then the gray image of a single channel will get a response map after being calculated by the Laplace 3x3 convolution kernel just calculated, and finally calculate the variance of the response map.

Based on the variance and the threshold set according to experience, whether the image is blurred can be determined. For the same type of commodity pictures, the same threshold can be used. The threshold may need to be adjusted for pictures taken in different commodities and different environments.

bool isImageBlurry(cv::Mat& img, double threshold)
{
    cv::Mat matImageGray;
    cv::cvtColor(img, matImageGray, COLOR_BGR2GRAY);
    cv::Mat dst, abs_dst;
    cv::Laplacian(matImageGray, dst, CV_16S, 3);
    cv::convertScaleAbs( dst, abs_dst );
    cv::Mat tmp_m, tmp_sd;
    double sd = 0;
    cv::meanStdDev(dst, tmp_m, tmp_sd);
    sd = tmp_sd.at<double>(0,0); // variance
    return ((sd * sd) <= threshold);
}

Find a blurred picture and write a simple example to test

test.jpeg

using namespace std;
using namespace cv;

bool isImageBlurry(cv::Mat& img, double threshold=49.0);

int main(int argc,char *argv[])
{
    String imageName;
    cout << "Enter the image file name: " << endl;
    cin >> imageName;
    // read the image
    Mat image = imread(imageName);

    double time = (double)getTickCount();

    bool result = isImageBlurry(image);
    time = ((double)getTickCount() - time) / getTickFrequency();
    cout << "The time taken is:" << time << "s" << endl;
    cout << "result: " << result << endl;
    return 0;
}

bool isImageBlurry(cv::Mat& img, double threshold)
{
    cv::Mat matImageGray;
    cv::cvtColor(img, matImageGray, COLOR_BGR2GRAY);
    cv::Mat dst, abs_dst;
    cv::Laplacian(matImageGray, dst, CV_16S, 3);
    cv::convertScaleAbs( dst, abs_dst );
    cv::Mat tmp_m, tmp_sd;
    double m = 0, sd = 0;
    cv::meanStdDev(dst, tmp_m, tmp_sd);
    m = tmp_m.at<double>(0,0); 
    sd = tmp_sd.at<double>(0,0);
    std::cout << "sd * sd: " << sd * sd << std::endl;
    return ((sd * sd) <= threshold);
}

Execution results:

Enter the image file name: 
test.jpeg
sd * sd: 31.0646
 Time taken: 0.0219034s
result: 1

It can be determined that the picture is blurred through the above procedure.

Finally, the main language used by our team is Java/Kotlin, and we need to write a jni to call the function.

summary

Laplacian is a common method of image blur detection without reference image. In addition, Brenner, Tenengrad, SMD, SMD2, etc. can also be used.