基于OpenCV的图像模糊与否检测

本文用以记录,图像模糊与否的一种检测方法,该方法主要采用图像的拉普拉斯卷积操作。

源码

blur_detection.h

#pragma once
#ifndef BLUR_DETECTION_H
#define BLUR_DETECTION_H

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <sys/types.h>

#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui_c.h"
#include "opencv2/imgproc/imgproc_c.h"

double variance_of_laplacian(const IplImage* img);

void show_image(const char* winname, const IplImage* img, float waittime);

void draw_and_show_image(const IplImage* img, char* content, float waittime);

void delete_duplicates_image(const char* imgpath);

/*C substring function: It returns a pointer to the substring */
char *substring(char *string, int position, int length);

bool isImageFile(const char* img_name);

#endif //!< BLUR_DETECTION_H

blur_detection.cpp

#include "blur_detection.h"

void show_image(const char* winname, const IplImage* img, float waittime)
{
    cvNamedWindow(winname, CV_WINDOW_AUTOSIZE);
    cvShowImage(winname, img);
    int timedelay = (int)(waittime * 1000);
    cvWaitKey(timedelay);
    cvDestroyWindow(winname);
}

void draw_and_show_image(const IplImage* img, char* content, float waittime)
{
    IplImage* draw = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 3);
    if (img->nChannels == 1)
    {
        cvCvtColor(img, draw, CV_GRAY2BGR);
    }
    else
    {
        cvCopy(img, draw, NULL);
    }

    CvPoint org;
    org.x = 10;
    org.y = 30;
    CvFont font;
    cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 1.0, 1.0, 0, 2, 8);
    cvPutText(draw, content, org, &font, CV_RGB(255, 255, 0));
    show_image("label", draw, waittime);
    cvReleaseImage(&draw);
}

double variance_of_laplacian(const IplImage* img)
{
    if (img == NULL)
    {
        return 0.0;
    }
    const int imgrows = img->height;
    const int imgcols = img->width;
    IplImage* gray = cvCreateImage(cvSize(imgcols, imgrows), IPL_DEPTH_8U, 1);
    if (img->nChannels == 3)
    {
        cvCvtColor(img, gray, CV_BGR2GRAY);
    }
    else if (img->nChannels == 1)
    {
        cvCopy(img, gray, NULL);
    }
    else
    {
        cvCvtColor(img, gray, CV_BGRA2GRAY);
    }

    IplImage* lap = cvCreateImage(cvSize(imgcols, imgrows), IPL_DEPTH_64F, 1);
    cvLaplace(gray, lap, 3);
    cvReleaseImage(&gray);

    CvScalar lap_mean, lap_stddev;
    cvAvgSdv(lap, &lap_mean, &lap_stddev, NULL);
    cvReleaseImage(&lap);

    return lap_stddev.val[0];
}

void delete_duplicates_image(const char* imgpath)
{
    int status;
    status = remove(imgpath);
    if (status == 0)
    {
        printf("%s file deleted successfully.\n", imgpath);
    }
    else
    {
        printf("Unable to delete the file\n");
        perror("Error");
    }
}


char *substring(char *string, int position, int length)
{
    char *pointer = NULL;
    pointer = malloc(length + 1);
    if (pointer == NULL)
    {
        printf("Unable to allocate memory.\n");
        exit(1);
    }
    int c = 0;
    for (c = 0; c < length; c++)
    {
        *(pointer + c) = *(string + position - 1);
        string++;
    }
    *(pointer + c) = '\0';
    return pointer;
}

bool isImageFile(const char* img_name)
{
    // find last '.' of img_name
    int lastIdx = 0;
    int lenStr = strlen(img_name);
    int len = lenStr;
    while (--len)
    {
        char c = img_name[len];
        if (c == '.')
        {
            lastIdx = len;
            break;
        }
    }

    // substr
    char* imgpox = substring(img_name, lastIdx + 2, lenStr - lastIdx + 1);
    int r1 = strcmp(imgpox, "jpg");
    int r2 = strcmp(imgpox, "JPG");
    int r3 = strcmp(imgpox, "jpeg");
    int r4 = strcmp(imgpox, "JPEG");

    if (r1 == 0 || r2 == 0 || r3 == 0 || r4 == 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}

main.cpp

#include "blur_detection.h"
#include <dirent.h>
#include <locale.h>

int main(int argc, char* argv[])
{
    if (argc != 2)
    {
        printf("Usage:\n*.exe <image path>\n");
        return -1;
    }

    setlocale(LC_CTYPE, "");  // 处理中文命名的图像名称
    const char* img_path = argv[1];

    if (isImageFile(img_path))
    {
        // detect the blurness of image
        IplImage* img = cvLoadImage(img_path, 1);
        double stdv = variance_of_laplacian(img);
        char* rest = NULL;
        if (stdv <= 50)
        {
            rest = "blur ";
        }
        else
        {
            rest = "not blur ";
        }
        char buffer[10];
        snprintf(buffer, 10, "%.2f", stdv);
        char content[50];
        strcpy(content, rest);
        strcat(content, buffer);
        draw_and_show_image(img, content, 0);
        cvReleaseImage(&img);
    }
    return 0;
}

测试

测试图像

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

测试结果

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

参考

  • 7
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 15
    评论
### 回答1: 在Java中,可以使用OpenCV库来进行图像模糊检测。首先,我们需要将要检测图像读取为OpenCV的`Mat`对象。然后,可以使用OpenCV的`blur`函数来对图像进行模糊处理。 `blur`函数的使用方法如下: ```java Imgproc.blur(src, dst, ksize); ``` 其中,`src`是输入图像的`Mat`对象,`dst`是输出图像的`Mat`对象,`ksize`是模糊核的大小。模糊核的大小越大,图像模糊程度越高。 在进行模糊检测时,可以通过计算输入图像模糊后的图像之间的差异来判断图像是否模糊。一种常用的方法是计算图像的梯度值,然后判断梯度值的平均值是否小于某个阈值。 下面是一个简单的示例代码: ```java import org.opencv.core.Core; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.core.MatOfFloat; import org.opencv.core.Scalar; import org.opencv.core.Size; import org.opencv.core.CvException; import org.opencv.core.Canny; import org.opencv.core.Sobel; import org.opencv.highgui.HighGui; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; public class ImageBlurDetection { public static void main(String[] args) { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); // 读取图像 Mat image = Imgcodecs.imread("path_to_image"); // 对图像进行模糊处理 Mat blurredImage = new Mat(); Imgproc.blur(image, blurredImage, new Size(3, 3)); // 计算图像的梯度 Mat gradX = new Mat(); Mat gradY = new Mat(); Mat gradient = new Mat(); Imgproc.Sobel(blurredImage, gradX, CvType.CV_32F, 1, 0, 3, 1, 0, Core.BORDER_DEFAULT); Imgproc.Sobel(blurredImage, gradY, CvType.CV_32F, 0, 1, 3, 1, 0, Core.BORDER_DEFAULT); Core.subtract(gradX, gradY, gradient); // 计算梯度的平均值 Scalar meanGradient = Core.mean(gradient); double averageGradient = (meanGradient.val[0] + meanGradient.val[1] + meanGradient.val[2]) / 3.0; // 判断图像是否模糊 double blurThreshold = 50.0; if (averageGradient < blurThreshold) { System.out.println("图像模糊"); } else { System.out.println("图像清晰"); } } } ``` 以上代码首先加载了OpenCV库,并导入了必要的类。然后通过`Imgcodecs.imread`函数读取图像,并使用`blur`函数对图像进行模糊处理。 接下来,使用`Sobel`函数计算模糊图像的梯度,并通过`Core.subtract`函数计算梯度之差。然后,使用`Core.mean`函数计算梯度的平均值。 最后,判断平均梯度是否小于某个阈值,如果小于阈值,则图像模糊;否则,图像清晰。 需要注意的是,以上只是一个简单的示例代码,实际应用中可能需要根据实际情况进行调整和优化。 ### 回答2: Java OpenCV可以用于图像模糊检测模糊检测图像处理中常用的技术,用于检测图像中的模糊区域。 在使用Java OpenCV进行图像模糊检测前,首先需要加载图像并将其转换为灰度图像。可以使用OpenCV的灰度转换方法将彩色图像转换为灰度图像。 接下来,可以使用OpenCV中的高斯模糊方法对图像进行模糊处理。高斯模糊是一种常用的模糊滤波技术,它可以平滑图像并减少图像中的噪声。 在对图像进行高斯模糊后,可以计算图像中每个像素的梯度。梯度表示了图像中每个像素的变化情况,而模糊区域通常具有较小的梯度值。 通过对图像的梯度进行阈值处理,可以得到模糊区域的二进制掩码。该掩码可以用于标记图像中的模糊区域。 最后,可以通过对图像的二进制掩码进行形态学操作,如膨胀和腐蚀,来进一步增强模糊区域的检测效果。 使用Java OpenCV进行图像模糊检测可以帮助我们自动识别模糊图像,从而改进图像质量和视觉感受。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Digital2Slave

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值