Ubuntu下使用opencv进行图片模糊检测

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wyansai/article/details/81043636

一、编译opencv

1、依赖安装

sudo apt-get install build-essential
sudo apt-get install cmake git libgtk2.0-dev pkg-config
sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev liblapacke-dev
sudo apt-get install libxvidcore-dev libx264-dev
sudo apt-get install libatlas-base-dev gfortran
sudo apt-get install ffmpeg

2、源码下载

wget https://github.com/opencv/opencv/archive/3.2.0.zip
wget https://github.com/opencv/opencv_contrib/archive/3.2.0.zip

3、解压,并编译

cd opencv-3.2.0
mkdir build
cd build

cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/home/php/opencvLib -D INSTALL_PYTHON_EXAMPLES=ON -D INSTALL_C_EXAMPLES=OFF -D OPENCV_EXTRA_MODULES_PATH=/home/php/opencv_contrib-3.2.0/modules -D PYTHON_EXCUTABLE=/home/php/opencvLib/bin/python -D WITH_TBB=ON -D WITH_V4L=ON -D WITH_GTK=ON -D WITH_OPENGL=ON -D BUILD_EXAMPLES=ON ..

make -j4
sudo make install
sudo /bin/bash -c 'echo "/home/php/opencvLib" > /etc/ld.so.conf.d/opencv.conf'
sudo ldconfig

PS:也可以直接使用下面的apt-get安装,不需要编译

sudo apt-get install libopencv-dev python-opencv

二、编写测试文件

1、编译命令:

g++ main.cpp -I /home/php/opencvLib/include -L /home/php/opencvLib/lib -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_imgcodecs -o main

2、源码如下:

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace cv;
using namespace std;

bool blurDetect(Mat srcImage);
int VideoBlurDetect(const cv::Mat &srcimg);
int aHash(Mat matSrc1, Mat matSrc2);

int main(int argc, char* argv[])
{
	//图片模糊度检测
	Mat img1 = imread("/home/php/setup/7.jpg");

	double time = (double)getTickCount();
	int flag = VideoBlurDetect(img1);
	time = ((double)getTickCount() - time) / getTickFrequency();
	cout << "模糊度:" << flag << "\n所用时间为:" << time << "s" << endl;
	return 0;
	
/*	Mat img1 = imread("D:/1.jpg");
	Mat img2 = imread("D:/3.jpg");

	int flag = aHash(img1, img2);

	cout << "差别度:" << flag << endl;
	system("pause");
	return 0;*/
}

/*检测模糊度
返回值为模糊度,值越大越模糊,越小越清晰,范围在0到几十,10以下相对较清晰,一般为5。
调用时可在外部设定一个阀值,具体阈值根据实际情况决定,返回值超过阀值当作是模糊图片。
算法所耗时间在1毫秒内
*/
int VideoBlurDetect(const cv::Mat &srcimg)
{
	cv::Mat img;
	cv::cvtColor(srcimg, img, CV_BGR2GRAY); // 将输入的图片转为灰度图,使用灰度图检测模糊度

	//图片每行字节数及高  
	int width = img.cols;
	int height = img.rows;
	ushort* sobelTable = new ushort[width*height];
	memset(sobelTable, 0, width*height*sizeof(ushort));

	int i, j, mul;
	//指向图像首地址  
	uchar* udata = img.data;
	for (i = 1, mul = i*width; i < height - 1; i++, mul += width)
	for (j = 1; j < width - 1; j++)

		sobelTable[mul + j] = abs(udata[mul + j - width - 1] + 2 * udata[mul + j - 1] + udata[mul + j - 1 + width] - \
		udata[mul + j + 1 - width] - 2 * udata[mul + j + 1] - udata[mul + j + width + 1]);

	for (i = 1, mul = i*width; i < height - 1; i++, mul += width)
	for (j = 1; j < width - 1; j++)
	if (sobelTable[mul + j] < 50 || sobelTable[mul + j] <= sobelTable[mul + j - 1] || \
		sobelTable[mul + j] <= sobelTable[mul + j + 1]) sobelTable[mul + j] = 0;

	int totLen = 0;
	int totCount = 1;

	uchar suddenThre = 50;
	uchar sameThre = 3;
	//遍历图片  
	for (i = 1, mul = i*width; i < height - 1; i++, mul += width)
	{
		for (j = 1; j < width - 1; j++)
		{
			if (sobelTable[mul + j])
			{
				int   count = 0;
				uchar tmpThre = 5;
				uchar max = udata[mul + j] > udata[mul + j - 1] ? 0 : 1;

				for (int t = j; t > 0; t--)
				{
					count++;
					if (abs(udata[mul + t] - udata[mul + t - 1]) > suddenThre)
						break;

					if (max && udata[mul + t] > udata[mul + t - 1])
						break;

					if (!max && udata[mul + t] < udata[mul + t - 1])
						break;

					int tmp = 0;
					for (int s = t; s > 0; s--)
					{
						if (abs(udata[mul + t] - udata[mul + s]) < sameThre)
						{
							tmp++;
							if (tmp > tmpThre) break;
						}
						else break;
					}

					if (tmp > tmpThre) break;
				}

				max = udata[mul + j] > udata[mul + j + 1] ? 0 : 1;

				for (int t = j; t < width; t++)
				{
					count++;
					if (abs(udata[mul + t] - udata[mul + t + 1]) > suddenThre)
						break;

					if (max && udata[mul + t] > udata[mul + t + 1])
						break;

					if (!max && udata[mul + t] < udata[mul + t + 1])
						break;

					int tmp = 0;
					for (int s = t; s < width; s++)
					{
						if (abs(udata[mul + t] - udata[mul + s]) < sameThre)
						{
							tmp++;
							if (tmp > tmpThre) break;
						}
						else break;
					}

					if (tmp > tmpThre) break;
				}
				count--;

				totCount++;
				totLen += count;
			}
		}
	}
	//模糊度
	float result = (float)totLen / totCount;
	delete[] sobelTable;
	sobelTable = NULL;

	return result;
}

int aHash(Mat matSrc1, Mat matSrc2)
{
	Mat matDst1, matDst2;
	cv::resize(matSrc1, matDst1, cv::Size(8, 8), 0, 0, cv::INTER_CUBIC);
	cv::resize(matSrc2, matDst2, cv::Size(8, 8), 0, 0, cv::INTER_CUBIC);

	cv::cvtColor(matDst1, matDst1, CV_BGR2GRAY);
	cv::cvtColor(matDst2, matDst2, CV_BGR2GRAY);

	int iAvg1 = 0, iAvg2 = 0;
	int arr1[64], arr2[64];

	for (int i = 0; i < 8; i++)
	{
		uchar* data1 = matDst1.ptr<uchar>(i);
		uchar* data2 = matDst2.ptr<uchar>(i);

		int tmp = i * 8;

		for (int j = 0; j < 8; j++)
		{
			int tmp1 = tmp + j;

			arr1[tmp1] = data1[j] / 4 * 4;
			arr2[tmp1] = data2[j] / 4 * 4;

			iAvg1 += arr1[tmp1];
			iAvg2 += arr2[tmp1];
		}
	}

	iAvg1 /= 64;
	iAvg2 /= 64;

	for (int i = 0; i < 64; i++)
	{
		arr1[i] = (arr1[i] >= iAvg1) ? 1 : 0;
		arr2[i] = (arr2[i] >= iAvg2) ? 1 : 0;
	}

	int iDiffNum = 0;

	for (int i = 0; i < 64; i++)
	if (arr1[i] != arr2[i])
		++iDiffNum;

	return iDiffNum;
}

猜你喜欢

转载自blog.csdn.net/wyansai/article/details/81043636