本文用以记录,图像模糊与否的一种检测方法,该方法主要采用图像的拉普拉斯卷积操作。
源码
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);
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)
{
int lastIdx =
0;
int lenStr =
strlen(img_name);
int len = lenStr;
while (--len)
{
char c = img_name[len];
if (c ==
'.')
{
lastIdx = len;
break;
}
}
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))
{
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;
}
测试
测试图像
测试结果
参考
blur-detection-with-opencv