对于模糊人脸图片和原图的清晰度评估——sobel算子
来源:互联网 发布:js事件绑定和事件委托 编辑:程序博客网 时间:2024/06/05 18:55
评估图像清晰度是一个常见的问题。写了c和matlab两个版本的简单代码,日后可以拿来就用。
模糊的图片一般可以分为两种,动态模糊或者对焦模糊。顾名思义,动态模糊就相当于一个头在你面前晃啊晃的看不清,对焦模糊就是你离远点把眼睛摘了看人(视力好的人请按alt+f4)。
上面三个,中间是原图,左边是动态模糊,右边是对焦模糊。
质量评价也简单,你只要给清晰的图片打分高于模糊图片,只要分差明显,随便用点数学公式就可以换算到任何评分标准体系了。
处理这种问题其实很简单。就是sobel算子的一个应用问题。因为模糊的图片必然比清晰的原图具有更加不清楚的边缘。所以你提取不出来啊,做个边缘提取之后,原图肯定留下更多的1,所以这个时候再算个平均值,就搞定了。
别废话上代码:
这个c的函数,就是输入一个灰度值数组,和图片长宽,返回一个评价值。
float estimate(unsigned char *pData, int width, int height){int i = 0, j = 0;unsigned char *pixel;int *image0,*image90,*image45,*image135;int a1,a2,a3,b1,b2,b3,c1,c2,c3;int threshold = 100;float *image;float sum=0.0;pixel = (unsigned char*)malloc(sizeof(unsigned char)*(width*height));image0 = (int*)malloc(sizeof(int)*(width*height));image45 = (int*)malloc(sizeof(int)*(width*height));image90 = (int*)malloc(sizeof(int)*(width*height));image135 = (int*)malloc(sizeof(int)*(width*height));image = (float*)malloc(sizeof(float)*(width*height));//initefor(i=0; i < height; i++)for(j = 0; j <width; j++){pixel[i*width+j] = pData[i*width+j];}// a1 a2 a3// b1 b2 b3// c1 c2 c3// replicate for the bounds, the nearest onefor(i = 0; i < height; i++)for(j = 0; j< width; j++){if(i == 0){//upper line, left-up and right-up corners if(j == 0){//left-up cornera1 = pixel[0];a2 = pixel[0];a3 = pixel[1];b1 = pixel[0];b2 = pixel[0];b3 = pixel[1];c1 = pixel[width];c2 = pixel[width];c3 = pixel[width+1];}else if(j == (width-1)){//left-right cornera1 = pixel[width-2];a2 = pixel[width-1];a3 = pixel[width-1];b1 = pixel[width-2];b2 = pixel[width-1];b3 = pixel[width]-1;c1 = pixel[2*width-2];c2 = pixel[2*width-1];c3 = pixel[2*width-1];}else{a1 = pixel[j-1];a2 = pixel[j];a3 = pixel[j+1];b1 = a1;b2 = a2;b3 = a3;c1 = pixel[width+j-1];c2 = pixel[width+j];c3 = pixel[width+j+1];}}else if(j == 0){//left row and left-down cornerif(i == (height-1)){//left-down cornera1 = pixel[(i-1)*width];a2 = a1;a3 = pixel[(i-1)*width + 1];b1 = pixel[i*width];b2 = b1;b3 = pixel[i*width + 1];c1 = b2;c2 = b2;c3 = b3;}else{a1 = pixel[(i-1)*width];a2 = a1;a3 = pixel[(i-1)*width + 1];b1 = pixel[i*width];b2 = b1;b3 = pixel[i*width + 1];c1 = pixel[(i+1)*width];c2 = c1;c3 = pixel[(i+1)*width + 1];}}else if(i == (height-1)){//down line and down-right cornerif(j == (width-1)){//down-right cornera1 = pixel[(i-1)*width + j-1];a2 = pixel[(i-1)*width + j];a3 = a2;b1 = pixel[i*width + j-1];b2 = pixel[i*width + j];b3 = b2;c1 = b1;c2 = b2;c3 = b2;}else{a1 = pixel[(i-1)*width + j-1];a2 = pixel[(i-1)*width + j];a3 = pixel[(i-1)*width + j+1];b1 = pixel[i*width + j-1];b2 = pixel[i*width + j];b3 = pixel[i*width + j+1];c1 = b1;c2 = b2;c3 = b3;}}else if(j == (width-1)){//right rowa1 = pixel[(i-1)*width + j-1];a2 = pixel[(i-1)*width + j];a3 = a2;b1 = pixel[i*width + j-1];b2 = pixel[i*width + j];b3 = b2;c1 = pixel[(i+1)*width-1];c2 = pixel[(i+1)*width-1];c3 = c2;}else{a1 = pixel[(i-1)*width + j-1];a2 = pixel[(i-1)*width + j];a3 = pixel[(i-1)*width + j+1];b1 = pixel[i*width + j-1];b2 = pixel[i*width + j];b3 = pixel[i*width + j+1];c1 = pixel[(i+1)*width+ j-1];c2 = pixel[(i+1)*width+ j];c3 = pixel[(i+1)*width+ j+1];}//corr// 0:-1 0 1 45:-2 -1 0 90:1 2 1 135:0 -1 -2// -2 0 2 -1 0 1 0 0 0 1 0 -1// -1 0 1 0 1 2 -1 -2 -1 2 1 0image0[i*width+j] = -a1 + a3 -2*b1 + 2*b3 -c1 + c3;if (image0[i*width+j] < 100)image0[i*width+j] = 0;else image0[i*width+j] = 1;image45[i*width+j] = -2*a1 - a2 - b1 + b3 + c2 + 2*c3;if (image45[i*width+j] < 100)image45[i*width+j] = 0;else image45[i*width+j] = 1;image90[i*width+j] = a1 + 2*a2 + a3 - c1 - 2*c2 - c3;if (image90[i*width+j] < 100)image90[i*width+j] = 0;else image90[i*width+j] = 1;image135[i*width+j] = -a2 - 2*a3 + b1 - b3 + 2*c1 + c2;if (image135[i*width+j] < 100)image135[i*width+j] = 0;else image135[i*width+j] = 1;}//combinationfor(i=0; i <height-1; i++)for(j=0; j < width-1; j++)image[i*width+j] = (float)(image0[i*width+j]+image45[i*width+j]+image90[i*width+j]+image135[i*width+j])/4;//return the average gary valuefor(i=0; i <height-1; i++)for(j=0; j < width-1; j++)sum = (float)sum + image[i*width+j];sum =(float) sum/(height*width);return sum;}
matlab的代码同时读两个图片,编号0是原图,编号1是模糊图。最后两个图的值同时给出来。有一些冗余代码,别介意。
%45°和135°角边缘检测;用于那些边界不明显的图片sobel45=[-2 -1 0; -1 0 1; 0 1 2];sobel135=[0 -1 -2; 1 0 -1; 2 1 0];sobel0=[-1 0 1; -2 0 2; -1 0 1];sobel90=[1 2 1; 0 0 0; -1 -2 -1];SourcePic1 = imread('/home/ydt/桌面/m22.jpg');SourcePic0 = imread('/home/ydt/桌面/m21.jpg');subplot(6, 2, 1); imshow(SourcePic0),title('origin'); %subplot(211);subplot(6,2,2);imshow(SourcePic1),title('dynamic'); grayPic0 = rgb2gray(SourcePic0);grayPic1 = rgb2gray(SourcePic1);%grayPic0 = im2double(grayPic0);%grayPic1 = im2double(grayPic1);subplot(6, 2, 3); imshow(grayPic0),title('origin-gray'); subplot(6, 2, 4); imshow(grayPic1),title('dynamic-gray');Threshold1 = 100;SFST45 = imfilter(grayPic0,sobel45,'replicate');SFST45=SFST45>=Threshold1; I01 = SFST45;subplot(625); imshow(SFST45),title('45') ;SFST45=imfilter(grayPic1,sobel45,'replicate');SFST45=SFST45>=Threshold1; I11 = SFST45;subplot(626); imshow(SFST45),title('45') ; Threshold2 = 100;SFST135 = imfilter(grayPic0,sobel135,'replicate');SFST135=SFST135>=Threshold2; I02 = SFST135;subplot(627); imshow(SFST135),title('135') ;SFST135 = imfilter(grayPic1,sobel135,'replicate');SFST135=SFST135>=Threshold2; I12 = SFST135;subplot(628); imshow(SFST135),title('135') ;Threshold3 = 100;SFST0 = imfilter(grayPic0,sobel0,'replicate');SFST0=SFST0>=Threshold3; I03 = SFST0;subplot(629); imshow(SFST0),title('90') ;SFST0 = imfilter(grayPic1,sobel0,'replicate');SFST0=SFST0>=Threshold3; I13 = SFST0;subplot(6,2,10); imshow(SFST0),title('90') ;Threshold4 = 100;SFST90 = imfilter(grayPic0,sobel90,'replicate');SFST90=SFST90>=Threshold4; I04 = SFST90;subplot(6,2,11); imshow(SFST90),title('0') ;SFST90 = imfilter(grayPic1,sobel90,'replicate');SFST90=SFST90>=Threshold4; I14 = SFST90;subplot(6,2,12); imshow(SFST90),title('0') ;I0 = (I01 + I02 + I03 + I04)/4;I1 = (I11 + I12 + I13 + I14)/4;subplot(2,1,1);imshow(I0),title('origin') ;subplot(2,1,2);imshow(I1),title('motion') ;[M0,N0] = size(I0);[M1,N1] = size(I1);%I = (I0 + I1)/2;% subplot(111);% imshow(I),title('sobel') ;% sum = 0;% for i=1:M0*N0% sum = I(i)+sum;% end% m=sum/M0/N0;sum = 0;for i=1:M0*N0 sum = I0(i)+sum;endsum1 = sum/(M0*N0);%c0 = 1- abs(sum1-m);sum = 0;for i=1:M1*N1 sum = I1(i)+sum;endsum2 = sum/(M1*N1);%c1 = 1- abs(sum2-m);fprintf('Average gray value after sobel detecting, Origin: %12.6f\n', sum1);fprintf('Average gray value after sobel detecting, Motion: %12.6f\n', sum2);
总的来说,有一个局限性。就是只能保证同一个人的图片,清晰的比模糊的强。这只是一个相对的结果,自行设定模糊与清晰的分界线,但是并不是说在绝对的情况下,任何低于这个值的都是模糊。非常简单的一个算法。
0 0
- 对于模糊人脸图片和原图的清晰度评估——sobel算子
- Sobel和Roberts算子的推导过程
- Sobel和Roberts算子的推导过程
- sobel和laplace算子
- Sobel算子的理解
- 边缘检测——Sobel算子
- 图像处理——sobel算子
- imgproc模块—Sobel边缘检测算子
- EasyPR--开发详解(3)高斯模糊、灰度化和Sobel算子
- EasyPR--开发详解(3)高斯模糊、灰度化和Sobel算子
- OpenCV2.4.9的jpeg解码和sobel算子函数剥离
- MATLAB的Roberts算子与Sobel算子
- 边缘检测综合示例——Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑
- 我的CUDA学习之旅4——Sobel算子图像边缘检测CUDA实现
- iOS 截屏图片模糊,提高清晰度
- 图像处理算法4——Sobel 边缘检测算子
- Sobel算子
- Sobel算子
- Fitnesse使用系列一
- asp中利用setcookie和getcookie传值
- 规律数组打印
- notepad++必要插件
- Effective java7——异常
- 对于模糊人脸图片和原图的清晰度评估——sobel算子
- 字典相关
- 分支界定法 branch-and-bound 分析与实现
- listview多种形式item
- Mongodb与spring集成 配置
- 黑马程序员:day03笔记
- try...catch...finally中的return
- mysql的on delete restrict与on ordelete cascade区别
- 谈谈几个月以来开发android蓝牙4.0 BLE低功耗应用的感受