无参考图像质量评价兵分两路,一部分是rank的方法,用不同图像之间质量的差别来打分,我觉得rank方法考虑到了人类视觉特性就是对两张图像质量差别很小时要通过比较才能判断出谁质量好,看这个iccv2017的论文RankIQA: learning from rankings for no-reference image quality assessment,用siamese network弄的。还有一部分提取每一副图的特征来评价质量,因为人眼也可以直接给出一幅图是好是坏,只是这个评价比较粗略,如果加上与其他图片比较的方法更精确。不过,至少,人眼可以直接给出一副图的质量。
微软有个交流讲座里说,识别的过程是由粗到细。就是第一眼能把握这个图的全局,再仔细看才能看到图的细节。如果目的达到了,就只需要把握全局,人眼就不会再看细节了。格式塔也说视觉是有目的性的活动等等。在看一幅失真图像时,离得越远越不能察觉到它质量的不好。如下图所示:
可能图像质量评价是图像识别任务的一个副产品,首先看到的是全局的内容,但是再往下细看时,清晰图像仍然可以看到新的内容,失真图像只能看到很少的新内容,或者说细看失真图像时与粗看时的理解发生了变化,不再是想象中的那样在原有粗看时信息的叠加,而是在细看时信息获取受阻。(好像也和自然图像的自相似有关系)
patch recurrence图像先验,Zontak的 Separating Signal from Noise using Patch Recurrence Across Scales提到的在图像的不同尺度搜索无噪声图像块,好像也与本博客相关。如图所示:
感觉人眼观察的多尺度特性让图像即使在图像细节收影响的情况下仍然能最大程度地满足视觉任务,而不是现在的神经网络比较不能适应图像的失真,看到有好几篇论文说这个事,找不到了。现在又看到一篇Image Quality Assessment Guided Deep Neural Networks Training,好像是用ssim改变cifar训练时的损失函数,就是softmax出来的概率分布,如果图像质量差,那个概率分布就不对label类那个专一。平滑label。
说了那么多,其实是想只用人眼多尺度特性来处理图像质量评价,因为我觉得图像质量评价能进行就是因为人眼又粗到精地识别过程。不考虑美学质量评价等等的话(也许……)。而现在的图像识别神经网络对失真图像识别不是太好,好像是它们没有多尺度特性。就是如果图像不清晰了,它可能就识别成了完全是其他不相关的种类。
所以就用不同缩放程度的失真图像输入VGG16,比较不同尺度图像的各层feature map间差别(我用互相关弄的),如果差别很大,说明神经网络滴对图像内容的理解完全发生了变化,很可能就是失真图像了。就像层层漏勺,把与图像内容无关的漏掉,把内容相关的保留,但对失真图像,如果失真的东西很多,很可能把失真也误认为是内容,所以漏勺保留了失真,以为失真是内容。如果图像缩小一点,原本是内容的东西联系比较紧密,不容易被漏勺漏掉,而失真的东西就被衰减了,比较容易被漏勺漏掉。
但是漏勺在漏小图像的时候很可能把真正的图像内容也漏掉了,所以在各个feature map层之后也要缩放。就像第二层漏勺功能比较强大,更容易漏,就要先放大一下,保留住第一层漏勺留下来的胜利果实。
Zeiler的Visualizing and Understanding Convolutional Networks里说,平移旋转缩放变换对前面层影响大一些,对后面层影响不大。我觉得就是前面的漏勺能力比较弱,后面的漏勺漏的能力(排除不相关特征的能力)比较强。
如上图,前面层提取的是线,中间是圆,后面是复杂的结构。额,线漏勺保留了线,虽然线短;后面的圆漏勺是线的平方(额。。。),所以要对第一次漏勺结果放大保住成果,否则线的平方的漏勺能力比较强就会把短线组成的圆(缩小了的图像内容)漏掉。。。感觉好牵强,哈哈
总之,我就把不同大小缩放的失真图像塞进了用于图像识别的训练好的VGG16里,比较不同尺度feature map的差别,然后用svm对66个特征train一下,测试。
其实我觉得这是动态的过程,你发现尺度放大以后不对劲了,就会停留在前面尺度的印象。以后学一下增强学习再看吧。。。
就像淘沙子淘金子:
河边,用不同大小网眼的网淘金子,沙子被冲走了。。。哈哈
我提取特征用MatConvnet弄的,主要代码如下:
net1.layers=layers(1);net2.layers=layers(2:3);net3.layers=layers(4:6);
net4.layers=layers(7:8);net5.layers=layers(9:11);net6.layers=layers(12:13);
net7.layers=layers(14:15);net8.layers=layers(16:18);net9.layers=layers(19:20);
net10.layers=layers(21:22);net11.layers=layers(23:25);
%%
corrMat=zeros(6,11,779);
scaleMat=[416 416 202 202 94 94 94 41 41 41 14;...
352 352 172 172 82 82 82 37 37 37 14;...
288 288 142 142 69 69 69 32 32 32 14;...
224 224 112 112 56 56 56 28 28 28 14;...
160 160 82 82 43 43 43 24 24 24 14;...
96 96 52 52 30 30 30 19 19 19 14;...
32 32 22 22 18 18 18 15 15 15 14];
for k=1:779
tic
i0m0=disMat(:,:,:,k);
i1m0=imresize(i0m0,[352 352]);
i2m0=imresize(i0m0,[288 288]);
i3m0=imresize(i0m0,[224 224]);
i4m0=imresize(i0m0,[160 160]);
i5m0=imresize(i0m0,[96 96]);
i6m0=imresize(i0m0,[32 32]);
for j=1:11
a=sprintf('%d',j);
b=sprintf('%d',j-1);
eval(['res=vl_simplenn(net',a,',i0m',b,');'])
eval(['i0m',a,'=res(end).x;'])
eval(['i0m',a,'=imresize(i0m',a,',[scaleMat(1,j) scaleMat(1,j)]);'])
eval(['clear i0m',b,' res;'])
for i=1:6
c=sprintf('%d',i);
eval(['res=vl_simplenn(net',a,',i',c,'m',b,');'])
eval(['i',c,'m',a,'=res(end).x;'])
eval(['i',c,'m',a,'=imresize(i',c,'m',a,',[scaleMat(i+1,j) scaleMat(i+1,j)]);'])
eval(['clear i',c,'m',b,' res;'])
%
eval(['[m,n,~,~]=size(i',c,'m',a,');'])
eval(['temp=imresize(i0m',a,',[m,n]);'])
tempa=temp.*temp;
eval(['tempb=i',c,'m',a,'.*i',c,'m',a,';'])
eval(['corr=sum(temp(:).*i',c,'m',a,'(:))./((sum(tempa(:)).^0.5)*(sum(tempb(:)).^0.5));'])
corrMat(i,j,k)=corr;
end
end
toc
display(k)
end
用LIVE库测试了一下,效果比较差,哈哈。
不过我只用了图像尺度这个先验,而且也没用神经网络训练,也就是说可能这个方法适用性比较好,不像其他IQA方法用各项同性什么的,所以想再LIVE Wild Challenge数据集上测一下。。要是也是这个相关性,那就比较好了。。但是不想弄了。。IQA到此结束我要搞别的了