对于模糊人脸图片和原图的清晰度评估——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
原创粉丝点击