├── .gitignore ├── LICENSE ├── README.md ├── _config.yml ├── data ├── LIVE2_labels.mat ├── README.md ├── data_generator │ ├── README.md │ ├── distortion_generator.m │ ├── distortion_saver.m │ └── open_bitfield_bmp.m ├── ft_live_test.txt ├── ft_live_train.txt ├── ft_tid2013_test.txt ├── ft_tid2013_train.txt ├── generate_ft_txt_live.py ├── generate_ft_txt_tid2013.py ├── generate_rank_txt_live.py ├── generate_rank_txt_tid2013.py ├── live │ └── README.md ├── live_test.txt ├── live_train.txt ├── rank_live │ └── README.md ├── rank_tid2013 │ ├── BM3D │ │ ├── BM3D-SAPCA │ │ │ ├── BM3DSAPCA2009.p │ │ │ ├── README-BM3D-SAPCA.txt │ │ │ ├── demo_BM3DSAPCA.m │ │ │ ├── function_AnisLPAICI8.p │ │ │ ├── function_CreateLPAKernels.m │ │ │ ├── function_LPAKernelMatrixTheta.m │ │ │ ├── function_WOSFilters.p │ │ │ └── function_Window2D.m │ │ ├── BM3D.m │ │ ├── BM3DDEB.m │ │ ├── BM3DSHARP.m │ │ ├── BM3D_CFA.m │ │ ├── CBM3D.m │ │ ├── CVBM3D.m │ │ ├── ClipComp16b.p │ │ ├── IDDBM3D │ │ │ ├── BM3DDEB_init.m │ │ │ ├── BlockMatch.mexw32 │ │ │ ├── BlockMatch.mexw64 │ │ │ ├── Demo_IDDBM3D.m │ │ │ ├── GroupProcessor.mexw32 │ │ │ ├── GroupProcessor.mexw64 │ │ │ └── IDDBM3D.p │ │ ├── LEGAL_NOTICE.txt │ │ ├── README.txt │ │ ├── VBM3D.m │ │ ├── bm3d_CFA_thr.mexa64 │ │ ├── bm3d_CFA_thr.mexglx │ │ ├── bm3d_CFA_thr.mexmaci64 │ │ ├── bm3d_CFA_thr.mexw32 │ │ ├── bm3d_CFA_thr.mexw64 │ │ ├── bm3d_CFA_wiener.mexa64 │ │ ├── bm3d_CFA_wiener.mexglx │ │ ├── bm3d_CFA_wiener.mexmaci64 │ │ ├── bm3d_CFA_wiener.mexw32 │ │ ├── bm3d_CFA_wiener.mexw64 │ │ ├── bm3d_thr.mexa64 │ │ ├── bm3d_thr.mexglx │ │ ├── bm3d_thr.mexmaci │ │ ├── bm3d_thr.mexmaci64 │ │ ├── bm3d_thr.mexw32 │ │ ├── bm3d_thr.mexw64 │ │ ├── bm3d_thr_color.mexa64 │ │ ├── bm3d_thr_color.mexglx │ │ ├── bm3d_thr_color.mexmaci │ │ ├── bm3d_thr_color.mexmaci64 │ │ ├── bm3d_thr_color.mexw32 │ │ ├── bm3d_thr_color.mexw64 │ │ ├── bm3d_thr_colored_noise.mexa64 │ │ ├── bm3d_thr_colored_noise.mexglx │ │ ├── bm3d_thr_colored_noise.mexmaci │ │ ├── bm3d_thr_colored_noise.mexmaci64 │ │ ├── bm3d_thr_colored_noise.mexw32 │ │ ├── bm3d_thr_colored_noise.mexw64 │ │ ├── bm3d_thr_sharpen_var.mexa64 │ │ ├── bm3d_thr_sharpen_var.mexglx │ │ ├── bm3d_thr_sharpen_var.mexmaci │ │ ├── bm3d_thr_sharpen_var.mexmaci64 │ │ ├── bm3d_thr_sharpen_var.mexw32 │ │ ├── bm3d_thr_sharpen_var.mexw64 │ │ ├── bm3d_thr_video.mexa64 │ │ ├── bm3d_thr_video.mexglx │ │ ├── bm3d_thr_video.mexmaci │ │ ├── bm3d_thr_video.mexmaci64 │ │ ├── bm3d_thr_video.mexw32 │ │ ├── bm3d_thr_video.mexw64 │ │ ├── bm3d_thr_video_c.mexw32 │ │ ├── bm3d_thr_video_c.mexw64 │ │ ├── bm3d_wiener.mexa64 │ │ ├── bm3d_wiener.mexglx │ │ ├── bm3d_wiener.mexmaci │ │ ├── bm3d_wiener.mexmaci64 │ │ ├── bm3d_wiener.mexw32 │ │ ├── bm3d_wiener.mexw64 │ │ ├── bm3d_wiener_color.mexa64 │ │ ├── bm3d_wiener_color.mexglx │ │ ├── bm3d_wiener_color.mexmaci │ │ ├── bm3d_wiener_color.mexmaci64 │ │ ├── bm3d_wiener_color.mexw32 │ │ ├── bm3d_wiener_color.mexw64 │ │ ├── bm3d_wiener_colored_noise.mexa64 │ │ ├── bm3d_wiener_colored_noise.mexglx │ │ ├── bm3d_wiener_colored_noise.mexmaci │ │ ├── bm3d_wiener_colored_noise.mexmaci64 │ │ ├── bm3d_wiener_colored_noise.mexw32 │ │ ├── bm3d_wiener_colored_noise.mexw64 │ │ ├── bm3d_wiener_video.mexa64 │ │ ├── bm3d_wiener_video.mexglx │ │ ├── bm3d_wiener_video.mexmaci │ │ ├── bm3d_wiener_video.mexmaci64 │ │ ├── bm3d_wiener_video.mexw32 │ │ ├── bm3d_wiener_video.mexw64 │ │ ├── bm3d_wiener_video_c.mexw32 │ │ └── bm3d_wiener_video_c.mexw64 │ ├── BlockWise.m │ ├── CA.m │ ├── ColorSaturation.m │ ├── ContrastChange.m │ ├── HighFN.m │ ├── ImageDenoising.m │ ├── MeanShift.m │ ├── MultiGN.m │ ├── QuantizationNoise.m │ ├── README.md │ ├── correlatedGaussianNoise.m │ ├── ghp.m │ ├── gnc.m │ ├── nepn.m │ ├── open_bitfield_bmp.m │ ├── pristine_images │ │ └── 00001.bmp │ ├── tid2013_generator.m │ └── tid2013_main.m ├── ref.txt ├── rename_image_names.py ├── tid2013 │ └── README.md ├── tid2013_test.txt └── tid2013_train.txt ├── figs └── models.png ├── models ├── README.md ├── ft_live │ └── log_live ├── ft_rank_tid2013 │ └── log_tid2013 ├── rank_live │ └── log_live └── rank_tid2013 │ └── log_tid2013 ├── pdf ├── Xialei_IQA_ICCV.pdf └── poster_ICCV_2017.pdf ├── pre-trained └── README.md ├── results └── README.md └── src ├── FT ├── live │ ├── deploy_vgg.prototxt │ ├── solver_live.prototxt │ ├── train_live.prototxt │ └── train_live.sh └── tid2013 │ ├── deploy_vgg.prototxt │ ├── solver_vgg.prototxt │ ├── train_vgg.prototxt │ └── train_vgg.sh ├── MyLossLayer ├── __init__.py ├── netloss_live.py └── netloss_tid2013.py ├── README.md ├── RankIQA ├── live │ ├── deploy_vgg.prototxt │ ├── solver_vgg.prototxt │ ├── train_vgg.prototxt │ └── train_vgg.sh └── tid2013 │ ├── deploy_vgg.prototxt │ ├── solver_vgg.prototxt │ ├── train_vgg.prototxt │ └── train_vgg.sh ├── __init__.py ├── data_layer ├── __init__.py ├── ft_layer_live.py ├── ft_layer_tid2013.py ├── rank_layer_live.py └── rank_layer_tid2013.py ├── eval ├── FT_eval_all_live.py ├── FT_eval_all_tid2013.py ├── FT_eval_each_tid2013.py ├── README.md ├── Rank_eval_all_live.py ├── Rank_eval_all_tid2013.py └── Rank_eval_each_tid2013.py └── tools ├── __init__.py └── layers_ft.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.py~ 3 | .#* 4 | *.swp 5 | *.caffemodel 6 | *~ 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 xialeiliu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RankIQA: Learning from Rankings for No-reference Image Quality Assessment 2 | 3 | The paper will appear in ICCV 2017. An [arXiv pre-print](https://arxiv.org/abs/1707.08347) version and the [supplementary material](./pdf/Xialei_IQA_ICCV.pdf) are available. 4 | 5 | ICCV 2017 open access is [available](http://openaccess.thecvf.com/content_ICCV_2017/papers/Liu_RankIQA_Learning_From_ICCV_2017_paper.pdf) and the poster can be found [here](./pdf/poster_ICCV_2017.pdf). 6 | 7 | The updated version is accepted at IEEE Transactions on Pattern Analysis and Machine Intelligence. Here is [arXiv pre-print version](https://arxiv.org/abs/1902.06285). 8 | 9 | ## Citation 10 | 11 | Please cite our paper if you are inspired by the idea. 12 | 13 | ``` 14 | @InProceedings{Liu_2017_ICCV, 15 | author = {Liu, Xialei and van de Weijer, Joost and Bagdanov, Andrew D.}, 16 | title = {RankIQA: Learning From Rankings for No-Reference Image Quality Assessment}, 17 | booktitle = {The IEEE International Conference on Computer Vision (ICCV)}, 18 | month = {Oct}, 19 | year = {2017} 20 | } 21 | ``` 22 | and 23 | 24 | ``` 25 | @ARTICLE{8642842, 26 | author={X. {Liu} and J. {Van De Weijer} and A. D. {Bagdanov}}, 27 | journal={IEEE Transactions on Pattern Analysis and Machine Intelligence}, 28 | title={Exploiting Unlabeled Data in CNNs by Self-supervised Learning to Rank}, 29 | year={2019}, 30 | pages={1-1}, 31 | doi={10.1109/TPAMI.2019.2899857}, 32 | ISSN={0162-8828}, } 33 | ``` 34 | 35 | ## Authors 36 | 37 | Xialei Liu, Joost van de Weijer and Andrew D. Bagdanov 38 | 39 | ## Institutions 40 | 41 | [Computer Vision Center, Barcelona, Spain](http://www.cvc.uab.es/lamp/) 42 | 43 | Media Integration and Communication Center, University of Florence, Florence, Italy 44 | 45 | ## Abstract 46 | 47 | We propose a no-reference image quality assessment 48 | (NR-IQA) approach that learns from rankings 49 | (RankIQA). To address the problem of limited IQA dataset size, we 50 | train a Siamese Network to rank images in terms of image quality by 51 | using synthetically generated distortions for which relative image 52 | quality is known. These ranked image sets can be automatically 53 | generated without laborious human labeling. We then use 54 | fine-tuning to transfer the knowledge represented in the trained 55 | Siamese Network to a traditional CNN that estimates absolute image 56 | quality from single images. We demonstrate how our approach can be 57 | made significantly more efficient than traditional Siamese Networks 58 | by forward propagating a batch of images through a single network 59 | and backpropagating gradients derived from all pairs of images in 60 | the batch. Experiments on the TID2013 benchmark show that we improve the state-of-the-art by over 5%. Furthermore, on the LIVE benchmark we show that our approach is superior to existing NR-IQA techniques and that we even outperform the state-of-the-art in full-reference IQA (FR-IQA) methods without having to resort to high-quality reference images to infer IQA. 61 | 62 | ## Models 63 | 64 | The main idea of our approach is to address the problem of limited IQA dataset size, which allows us to train a much deeper CNN without overfitting. 65 | 66 | ![Models](./figs/models.png ) 67 | 68 | ## Framework 69 | 70 | All training and testing are done in [Caffe](http://caffe.berkeleyvision.org/) framework. 71 | 72 | ## Pre-trained models 73 | 74 | The pre-trained [models](./pre-trained) are available to download. 75 | 76 | ## Datasets 77 | 78 | ### Ranking datasets 79 | 80 | Using an arbitrary set of images, we synthetically generate deformations of these images over a range of distortion intensities. In this paper, the reference images in [Waterloo](https://ece.uwaterloo.ca/~zduanmu/cvpr16_gmad/) and the validation set of the [Places2](http://places2.csail.mit.edu/) are used as reference images. The details of generated distortions can be found in [supplementary material](./pdf/Xialei_IQA_ICCV.pdf). The source code can be found in this [folder](./data/rank_tid2013). 81 | 82 | ### IQA datasets 83 | 84 | We have reported experimental results on different IQA datasets including [TID2013](http://www.ponomarenko.info/tid2013.htm), [LIVE](http://live.ece.utexas.edu/research/quality/subjective.htm), [CSIQ](http://vision.eng.shizuoka.ac.jp/mod/page/view.php?id=23), [MLIVE](http://live.ece.utexas.edu/research/quality/live_multidistortedimage.html). 85 | 86 | ## Training 87 | 88 | The details can be found in [src](./src). 89 | 90 | ### RankIQA 91 | 92 | Using the set of ranked images, we train a Siamese network and demonstrate how our approach can be made 93 | significantly more efficient than traditional Siamese Networks by forward propagating a batch of images through 94 | a single network and backpropagating gradients derived from all pairs of images in the batch. The result is a 95 | Siamese network that ranks images by image quality. 96 | 97 | ### RankIQA+FT 98 | 99 | Finally, we extract a single branch of the Siamese network (we are interested at this point in the representation learned in the network, and not in the ranking itself), and fine-tune it on available IQA data. This effectively calibrates the network to output IQA measurements. 100 | 101 | 102 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /data/LIVE2_labels.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/LIVE2_labels.mat -------------------------------------------------------------------------------- /data/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## Datasets preparation 3 | 4 | We provide some examples about how to prepare the structure of data in this folder. 5 | 6 | This is essential because the data structure is related to the [data reader function](../src/data_layer) and the [loss function](../src/MyLossLayer). 7 | 8 | 1. Download the [LIVE2](http://live.ece.utexas.edu/research/quality/subjective.htm) dataset and rename it as [live](./live) folder. Rename the image name in each distortion folder from "imgx.bmp" and "imgxx.bmp" to "img0xx.bmp", which allows us to read the data by order. 9 | ``` 10 | python rename_image_names.py 11 | ``` 12 | 2. Download the [TID2013](http://www.ponomarenko.info/tid2013.htm) dataset and rename it as [tid2013](./tid2013) folder. 13 | 3. Download the [Waterloo](https://ece.uwaterloo.ca/~zduanmu/cvpr16_gmad/) or Validation set of [Places2](http://places2.csail.mit.edu/) datasets, and put it in [rank_live](./rank_live) and [rank_tid2013](./rank_tid2013) folders. 14 | 4. Follow the instructions of [Waterloo](https://ece.uwaterloo.ca/~zduanmu/cvpr16_gmad/) to generate 4 distortions (JPEG, JP2K, Gblur and GN) at five levels in [rank_live](./rank_live). The code to generate 17 distortions for tid2013 dataset will be publicly available in the future. 15 | 16 | ### Ranking datasets preparation 17 | 18 | To train the RankIQA model on generated rank dataset, the data structure should be like [tid2013_train.txt](./tid2013_train.txt). 19 | 20 | Run the code to generate the live_train.txt and live_test.txt files 21 | 22 | ``` 23 | cd data 24 | python generate_rank_txt_live.py 25 | ``` 26 | 27 | Run the code to generate the tid2013_train.txt and tid2013_test.txt files 28 | 29 | ``` 30 | python generate_rank_txt_tid2013.py 31 | ``` 32 | 33 | ### IQA datasets preparation 34 | 35 | To train the RankIQA+FT model finetuned on tid2013 dataset, the data structure should be like [ft_tid2013_train.txt](./ft_tid2013_train.txt). 36 | 37 | Run the code to generate the ft_live_train.txt and ft_live_test.txt files 38 | 39 | ``` 40 | python generate_ft_txt_live.py 41 | ``` 42 | 43 | Run the code to generate the ft_tid2013_train.txt and ft_tid2013_test.txt files 44 | 45 | ``` 46 | python generate_ft_txt_tid2013.py 47 | cd .. 48 | ``` 49 | -------------------------------------------------------------------------------- /data/data_generator/README.md: -------------------------------------------------------------------------------- 1 | # Run the main function 2 | 3 | ``` 4 | run distortion_saver.m 5 | ``` 6 | -------------------------------------------------------------------------------- /data/data_generator/distortion_generator.m: -------------------------------------------------------------------------------- 1 | function distortion_generator( img, dist_type, level, filename ) 2 | %% set distortion parameter 3 | gblur_level = [7,15,39,91,199]; 4 | wn_level = [-10,-7.5,-5.5,-3.5,0]; 5 | jpeg_level = [43,12,7,4,0]; 6 | jp2k_level = [0.46,0.16,0.07,0.04,0.02]; % bit per pixel 7 | 8 | %% distortion generation 9 | switch dist_type 10 | case 1 11 | strname = './GB/GB'; 12 | testName = fullfile([strname, int2str(level)],[filename.name(1:end-4),'.bmp']); 13 | hsize = gblur_level(level); 14 | h = fspecial('gaussian', hsize, hsize/6); 15 | distorted_img = imfilter(img,h,'symmetric'); 16 | if ~exist([strname, int2str(level)], 'dir') 17 | mkdir([strname, int2str(level)]); 18 | end 19 | imwrite(distorted_img,testName); 20 | case 2 21 | strname = './GN/GN'; 22 | testName = fullfile([strname, int2str(level)],[filename.name(1:end-4),'.bmp']); 23 | distorted_img = imnoise(img,'gaussian',0,2^(wn_level(level))); 24 | if ~exist([strname, int2str(level)], 'dir') 25 | mkdir([strname, int2str(level)]); 26 | end 27 | imwrite(distorted_img,testName); 28 | case 3 29 | strname = './JPEG/JPEG'; 30 | testName = fullfile([strname, int2str(level)],[filename.name(1:end-4),'.jpg']); 31 | if ~exist([strname, int2str(level)], 'dir') 32 | mkdir([strname, int2str(level)]); 33 | end 34 | imwrite(img,testName,'jpg','quality',jpeg_level(level)); 35 | case 4 36 | strname = './JP2K/JP2K'; 37 | testName = fullfile([strname, int2str(level)],[filename.name(1:end-4),'.jp2']); 38 | if ~exist([strname, int2str(level)], 'dir') 39 | mkdir([strname, int2str(level)]); 40 | end 41 | imwrite(img,testName,'jp2','CompressionRatio', 24 / jp2k_level(level)); 42 | end 43 | end 44 | 45 | -------------------------------------------------------------------------------- /data/data_generator/distortion_saver.m: -------------------------------------------------------------------------------- 1 | % Generate different distortions 2 | file = dir('./pristine_images/*.bmp'); % The folder path of dataset 3 | 4 | for i = 1:length(file) 5 | refI = open_bitfield_bmp(fullfile('.', 'pristine_images', file(i).name)); 6 | for type = 1:4 7 | for level = 1:5 8 | distortion_generator(refI, type, level,file(i)); % #ok 9 | end 10 | end 11 | fprintf('Finished image %d*21 / 4744*21...\n', i); 12 | end 13 | -------------------------------------------------------------------------------- /data/data_generator/open_bitfield_bmp.m: -------------------------------------------------------------------------------- 1 | function [out_im,status ] = open_bitfield_bmp( filename ) 2 | % OPEN_BITFIELD_BMP open a bitfield compressed bitmap image. 3 | % 4 | % IM = OPEN_BITFIELD_BMP( FILENAME ) opens a 16-bit bitmapped compressed file 5 | % named FILENAME. The output is formatted as three planes of Red, Green 6 | % and Blue data. 7 | % 8 | % See also imread, imfinfo 9 | 10 | % Get information about the image 11 | info = imfinfo(filename); 12 | 13 | % if we have a bitfield compressed R-G-B bitmap image 14 | if ( strcmp(info.Format , 'bmp') && ... 15 | strcmp(info.CompressionType , 'bitfields') && ... 16 | (info.BitDepth == 16 || info.BitDepth == 32) ) 17 | 18 | % indicate the input bmp file is not of 8-bit 19 | status = 0; 20 | 21 | % Open the file for reading 22 | fid = fopen(filename, 'r'); 23 | 24 | % Extract relevvant image info 25 | data_offset = info.ImageDataOffset; 26 | width = info.Width; 27 | height = info.Height; 28 | 29 | % Create space for output image 30 | out_im = zeros(height, width, 3); 31 | 32 | % Seek to where the image data begins (i.e. skip the file header 33 | fseek(fid, data_offset, 'bof'); 34 | 35 | % Read in the image data and format it into a matrix 36 | if (info.BitDepth == 16) 37 | % compressed_image = (fread(fid, [width + 1, height] , 'uint16'))'; 38 | compressed_image = (fread(fid, [width, height] , 'uint16'))'; 39 | else 40 | compressed_image = (fread(fid, [width, height] , 'uint32'))'; 41 | end 42 | 43 | % Eliminate last column of junk data (scanline row terminators) in 16 44 | % bit mode 45 | if (info.BitDepth == 16) 46 | compressed_image = compressed_image(:, 1:(width)); 47 | end; 48 | 49 | % Invert Row Order since it is flipped 50 | new_image = flipud(compressed_image); 51 | 52 | % Extract color bitmasks to decompress 53 | red_mask = info.RedMask; 54 | blue_mask = info.BlueMask; 55 | green_mask = info.GreenMask; 56 | 57 | 58 | % Extract color components and form output image 59 | out_im(:,:,1) = (bitand(new_image, red_mask) / red_mask * 255); 60 | out_im(:,:,2) = (bitand(new_image, green_mask) / green_mask * 255); 61 | out_im(:,:,3) = (bitand(new_image, blue_mask) / blue_mask * 255); 62 | 63 | % typecast 64 | out_im = uint8(out_im); 65 | 66 | % display image 67 | %imshow(out_im); 68 | 69 | else 70 | 71 | % indicate the input bmp file is 8-bit 72 | status = 1; 73 | 74 | % general imread for all other cases 75 | out_im = imread(filename); 76 | %imshow(out_im); 77 | 78 | end 79 | 80 | -------------------------------------------------------------------------------- /data/generate_ft_txt_live.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import scipy.io as sio 3 | import os 4 | import os.path as osp 5 | import cv2 6 | 7 | 8 | label = 'LIVE2_labels.mat' 9 | shape = ['gblur','wn','jpeg','jp2k','fastfading'] 10 | data_path = '/home/xialei/Project/CleanProject/Camera-ready-code/data/live/' 11 | list_file = 'ref' + '.txt' 12 | 13 | 14 | filename = [line.rstrip('\n') for line in open( 15 | osp.join('./', list_file))] 16 | 17 | ref = filename 18 | 19 | gt_label = sio.loadmat(label) 20 | 21 | shuff = np.random.permutation(range(29)) 22 | train_file = open('ft_live_train.txt', "w") 23 | test_file = open('ft_live_test.txt', "w") 24 | 25 | Num_tr = 23 26 | Num_te = 29 27 | test = True 28 | flag = 1 29 | 30 | for tp in shape: 31 | 32 | file_root = data_path + tp + '/' 33 | list_file = 'info' + '.txt' 34 | filename = [line.rstrip('\n') for line in open( 35 | osp.join(file_root, list_file))] 36 | S_name = [] 37 | N_name = [] 38 | scores = [] 39 | for i in filename: 40 | S_name.append(i.split()[0]) 41 | N_name.append(i.split()[1]) 42 | scores.append(float(i.split()[2])) 43 | temp_label = gt_label[tp] 44 | temp_label = temp_label.swapaxes(1,0) 45 | 46 | a = os.listdir(data_path +tp) 47 | a.sort() 48 | 49 | TotalNum = temp_label.shape[0] 50 | 51 | for i in range(Num_tr): 52 | for j in range(TotalNum): 53 | if S_name[j] == ref[shuff[i]]: 54 | folder = data_path + tp + '/' + a[int(N_name[j][3:-4])-1] 55 | labels = temp_label[int(N_name[j][3:-4])-1] 56 | train_file.write('%s %6.2f\n' % (folder,labels)) 57 | 58 | 59 | for i in range(Num_tr,Num_te): 60 | for j in range(TotalNum): 61 | if S_name[j] == ref[shuff[i]]: 62 | folder = data_path+ tp + '/' + a[int(N_name[j][3:-4])-1] 63 | if test ==True: 64 | tmp = cv2.imread(folder) 65 | cv2.imwrite('./test/' + str(flag)+'.bmp',tmp) 66 | flag += 1 67 | 68 | labels = temp_label[int(N_name[j][3:-4])-1] 69 | test_file.write('%s %6.2f\n' % (folder,labels)) 70 | 71 | 72 | train_file.close() 73 | test_file.close() 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /data/generate_ft_txt_tid2013.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | import scipy.io as sio 4 | import os 5 | import os.path as osp 6 | 7 | data_dir = 'data/tid2013/' 8 | 9 | file_root = data_dir + 'distorted_images' + '/' 10 | list_file = data_dir + 'mos_with_names' + '.txt' 11 | 12 | 13 | filename = [line.rstrip('\n') for line in open( 14 | osp.join(list_file))] 15 | S_name = [] 16 | scores = [] 17 | for i in filename: 18 | S_name.append(i.split()[1]) 19 | scores.append(float(i.split()[0])) 20 | 21 | ref = S_name 22 | 23 | TotalNum = len(ref) 24 | shuff = np.random.permutation(range(1,25)) 25 | 26 | Num_tr = 19 # ~80% of reference images as training samples 27 | Num_te = 5 # ~20% of reference images as testing samples 28 | 29 | train_file = open('ft_tid2013'+'_train.txt', "w") 30 | test_file = open('ft_tid2013'+'_test.txt', "w") 31 | 32 | shuff_txt=np.random.permutation(range(TotalNum)) 33 | 34 | for i in shuff_txt: 35 | #if ref[i][4:6]==tp: 36 | for j in range(Num_tr): 37 | if int(ref[i][1:3]) == shuff[j]: 38 | folder = data_dir + 'distorted_images/' + ref[i] 39 | labels = scores[i] 40 | train_file.write('%s %6.2f\n' % (folder,labels)) 41 | 42 | 43 | 44 | 45 | for i in shuff_txt: 46 | #if ref[i][4:6]==tp: 47 | for j in range(Num_tr,Num_tr+Num_te): 48 | if int(ref[i][1:3]) == shuff[j]: 49 | folder = data_dir + 'distorted_images/' + ref[i] 50 | labels = scores[i] 51 | test_file.write('%s %6.2f\n' % (folder,labels)) 52 | 53 | train_file.close() 54 | test_file.close() 55 | -------------------------------------------------------------------------------- /data/generate_rank_txt_live.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import scipy.io as sio 3 | import os 4 | 5 | 6 | # folder includes all distortion types of ranking data for tid2013 7 | folder = ['JPEG','GN','GB','JP2K'] 8 | 9 | dir_rank = './data/rank_live/' # Change to your data folder 10 | 11 | train_file = open('live'+'_train.txt', "w") 12 | test_file = open('live'+'_test.txt', "w") 13 | 14 | pristine = 'pristine_images' # The folder of reference images to generate different distortions 15 | 16 | real = os.listdir(dir_rank + pristine) 17 | real.sort() 18 | Num = len(real) 19 | Tr_num = int(Num*0.8) 20 | 21 | FileT_p = [] # To save the image names 22 | scores_p = [] # To save the distortion levels 23 | 24 | for i in real: 25 | FileT_p.append(dir_rank + pristine + '/' + i ) 26 | scores_p.append(5) 27 | 28 | shuff_p = range(Num) 29 | #shuff_p = np.random.permutation(range(Num)) # To decide shuffle the data or not 30 | 31 | for t in folder: 32 | 33 | 34 | DisType = os.listdir(dir_rank + t) 35 | DisType.sort(reverse = True) 36 | 37 | ind =0 38 | dis_level = 5 # dis_level +1 = Level of distortion can be chose by changing this variable 39 | shuff = range(Num) 40 | #shuff = np.random.permutation(range(Num)) 41 | for i in DisType[0:dis_level]: 42 | fileN = os.listdir(dir_rank + t+'/'+i) 43 | fileN.sort() 44 | 45 | FileT = [] 46 | scores = [] 47 | for j in range(len(fileN)): 48 | FileT.append(dir_rank + t + '/' + i +'/'+ fileN[j]) 49 | scores.append(ind) 50 | for i in range(Tr_num): 51 | train_file.write('%s %6.2f\n' % ( FileT[shuff[i]],scores[shuff[i]])) 52 | for i in range(Tr_num,Num): 53 | test_file.write('%s %6.2f\n' % ( FileT[shuff[i]],scores[shuff[i]])) 54 | ind += 1 55 | 56 | for i in range(Tr_num): 57 | train_file.write('%s %6.2f\n' % ( FileT_p[shuff_p[i]],scores_p[shuff_p[i]])) 58 | for i in range(Tr_num,Num): 59 | test_file.write('%s %6.2f\n' % ( FileT_p[shuff_p[i]],scores_p[shuff_p[i]])) 60 | 61 | train_file.close() 62 | test_file.close() 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /data/generate_rank_txt_tid2013.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import scipy.io as sio 3 | import os 4 | 5 | 6 | # folder includes all distortion types of ranking data for tid2013 7 | folder = ['JPEG','GN','GB','JP2K','GNC','MSL','MSH','CCL','CCH','IN','ID','BW','NEPN','QN','CA','CS','MGN','CQD'] 8 | 9 | dir_rank = 'data/rank_tid2013/' # Change to your data folder 10 | 11 | train_file = open('tid2013'+'_train.txt', "w") 12 | test_file = open('tid2013'+'_test.txt', "w") 13 | 14 | pristine = 'pristine_images' # The folder of reference images to generate different distortions 15 | 16 | real = os.listdir(dir_rank + pristine) 17 | real.sort() 18 | Num = len(real) 19 | Tr_num = int(Num*0.8) 20 | 21 | FileT_p = [] # To save the image names 22 | scores_p = [] # To save the distortion levels 23 | 24 | for i in real: 25 | FileT_p.append(dir_rank + pristine + '/' + i ) 26 | scores_p.append(0) 27 | 28 | shuff_p = range(Num) 29 | #shuff_p = np.random.permutation(range(Num)) # To decide shuffle the data or not 30 | 31 | for t in folder: 32 | 33 | for i in range(Tr_num): 34 | train_file.write('%s %6.2f\n' % ( FileT_p[shuff_p[i]],scores_p[shuff_p[i]])) 35 | for i in range(Tr_num,Num): 36 | test_file.write('%s %6.2f\n' % ( FileT_p[shuff_p[i]],scores_p[shuff_p[i]])) 37 | DisType = os.listdir(t) 38 | DisType.sort() 39 | 40 | ind =0 41 | dis_level = 4 # dis_level +1 = Level of distortion can be chose by changing this variable 42 | shuff = range(Num) 43 | #shuff = np.random.permutation(range(Num)) 44 | for i in DisType[0:dis_level]: 45 | fileN = os.listdir(dir_rank + t+'/'+i) 46 | fileN.sort() 47 | ind += 1 48 | FileT = [] 49 | scores = [] 50 | for j in range(len(fileN)): 51 | FileT.append(dir_rank + t + '/' + i +'/'+ fileN[j]) 52 | scores.append(ind) 53 | for i in range(Tr_num): 54 | train_file.write('%s %6.2f\n' % ( FileT[shuff[i]],scores[shuff[i]])) 55 | for i in range(Tr_num,Num): 56 | test_file.write('%s %6.2f\n' % ( FileT[shuff[i]],scores[shuff[i]])) 57 | 58 | train_file.close() 59 | test_file.close() 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /data/live/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## The folder of LIVE dataset 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/rank_live/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## The folder of ranking dataset to train for LIVE dataset 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/BM3D-SAPCA/BM3DSAPCA2009.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/BM3D-SAPCA/BM3DSAPCA2009.p -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/BM3D-SAPCA/README-BM3D-SAPCA.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------- 2 | 3 | BM3D-SAPCA : BM3D with Shape-Adaptive Principal Component Analysis 4 | v1.00, 2009 5 | 6 | -------------------------------------------------------------------- 7 | 8 | Copyright (c) 2009-2011 Tampere University of Technology. 9 | All rights reserved. 10 | This work should be used for nonprofit purposes only. 11 | 12 | Author: Alessandro Foi 13 | 14 | BM3D web page: http://www.cs.tut.fi/~foi/GCF-BM3D 15 | 16 | 17 | 18 | BM3D-SAPCA is an algorithm for attenuation of additive white 19 | Gaussian noise (AWGN) from grayscale images. 20 | 21 | 22 | This software package reproduces the results from the article: 23 | 24 | K. Dabov, A. Foi, V. Katkovnik, and K. Egiazarian, 25 | "BM3D Image Denoising with Shape-Adaptive Principal 26 | Component Analysis", Proc. Workshop on Signal Processing 27 | with Adaptive Sparse Structured Representations (SPARS'09), 28 | Saint-Malo, France, April 2009. 29 | 30 | ( PDF available at http://www.cs.tut.fi/~foi/GCF-BM3D ) 31 | 32 | 33 | -------------------------------------------------------------------- 34 | 35 | This demo package includes routines from both the 36 | LASIP 2D demobox (http://www.cs.tut.fi/~lasip/2D/) and the 37 | Pointwise SA-DCT demobox (http://www.cs.tut.fi/~foi/SA-DCT/). 38 | 39 | -------------------------------------------------------------------- 40 | 41 | 42 | 43 | -------------------------------------------------------------------- 44 | Disclaimer 45 | -------------------------------------------------------------------- 46 | 47 | Any unauthorized use of these routines for industrial or profit- 48 | oriented activities is expressively prohibited. By downloading 49 | and/or using any of these files, you implicitly agree to all the 50 | terms of the TUT limited license, as specified in the document 51 | Legal_Notice.txt (included in this package) and online at 52 | http://www.cs.tut.fi/~foi/GCF-BM3D/legal_notice.html 53 | 54 | -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/BM3D-SAPCA/demo_BM3DSAPCA.m: -------------------------------------------------------------------------------- 1 | % BM3D-SAPCA : BM3D with Shape-Adaptive Principal Component Analysis (v1.00, 2009) 2 | % (demo script) 3 | % 4 | % BM3D-SAPCA is an algorithm for attenuation of additive white Gaussian noise (AWGN) 5 | % from grayscale images. This algorithm reproduces the results from the article: 6 | % K. Dabov, A. Foi, V. Katkovnik, and K. Egiazarian, "BM3D Image Denoising with 7 | % Shape-Adaptive Principal Component Analysis", Proc. Workshop on Signal Processing 8 | % with Adaptive Sparse Structured Representations (SPARS'09), Saint-Malo, France, 9 | % April 2009. (PDF available at http://www.cs.tut.fi/~foi/GCF-BM3D ) 10 | % 11 | % 12 | % SYNTAX: 13 | % 14 | % y_est = BM3DSAPCA2009(z, sigma) 15 | % 16 | % where z is an image corrupted by AWGN with noise standard deviation sigma 17 | % and y_est is an estimate of the noise-free image. 18 | % Signals are assumed on the intensity range [0,1]. 19 | % 20 | % 21 | % USAGE EXAMPLE: 22 | % 23 | % y = im2double(imread('Cameraman256.png')); 24 | % sigma=25/255; 25 | % z=y+sigma*randn(size(y)); 26 | % y_est = BM3DSAPCA2009(z,sigma); 27 | % 28 | % 29 | % 30 | % Copyright (c) 2009-2011 Tampere University of Technology. All rights reserved. 31 | % This work should only be used for nonprofit purposes. 32 | % 33 | % author: Alessandro Foi, email: firstname.lastname@tut.fi 34 | % 35 | %% 36 | 37 | clear all 38 | 39 | y = im2double(imread('Cameraman256.png')); 40 | % y = im2double(imread('Lena512.png')); 41 | randn('seed',0); 42 | 43 | sigma=25/255; 44 | z=y+sigma*randn(size(y)); 45 | 46 | y_est = BM3DSAPCA2009(z,sigma); 47 | 48 | PSNR = 10*log10(1/mean((y(:)-y_est(:)).^2)); 49 | disp(['PSNR = ',num2str(PSNR)]) 50 | if exist('ssim_index') 51 | [mssim ssim_map] = ssim_index(y*255, y_est*255); 52 | disp(['SSIM = ',num2str(mssim)]) 53 | end 54 | 55 | -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/BM3D-SAPCA/function_AnisLPAICI8.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/BM3D-SAPCA/function_AnisLPAICI8.p -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/BM3D-SAPCA/function_CreateLPAKernels.m: -------------------------------------------------------------------------------- 1 | % Creates LPA kernels cell array (function_CreateLPAKernels) 2 | % 3 | % Alessandro Foi - Tampere University of Technology - 2003-2005 4 | % --------------------------------------------------------------- 5 | % 6 | % Builds kernels cell arrays kernels{direction,size} 7 | % and kernels_higher_order{direction,size,1:2} 8 | % kernels_higher_order{direction,size,1} is the 3D matrix 9 | % of all kernels for that particular direction/size 10 | % kernels_higher_order{direction,size,2} is the 2D matrix 11 | % containing the orders indices for the kernels 12 | % contained in kernels_higher_order{direction,size,1} 13 | % 14 | % --------------------------------------------------------------------- 15 | % 16 | % kernels_higher_order{direction,size,1}(:,:,1) is the funcion estimate kernel 17 | % kernels_higher_order{direction,size,1}(:,:,2) is a first derivative estimate kernel 18 | % 19 | % kernels_higher_order{direction,size,1}(:,:,n) is a higher order derivative estimate kernel 20 | % whose orders with respect to x and y are specified in 21 | % kernels_higher_order{direction,size,2}(n,:)= 22 | % =[xorder yorder xorder+yorder] 23 | % 24 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 25 | 26 | function [kernels, kernels_higher_order]=function_createLPAkernels(m,h1,h2,TYPE,window_type,directional_resolution,sig_winds,beta) 27 | 28 | %-------------------------------------------------------------------------- 29 | % LPA ORDER AND KERNELS SIZES 30 | %-------------------------------------------------------------------------- 31 | % m=[2,0]; % THE VECTOR ORDER OF LPA; 32 | 33 | % h1=[1 2 3 4 5]; % sizes of the kernel 34 | % h2=[1 2 3 4 5]; % row vectors h1 and h2 need to have the same lenght 35 | 36 | 37 | %-------------------------------------------------------------------------- 38 | % WINDOWS PARAMETERS 39 | %-------------------------------------------------------------------------- 40 | % sig_winds=[h1*1 ; h1*1]; % Gaussian parameter 41 | % beta=1; % Parameter of window 6 42 | 43 | % window_type=1 ; % window_type=1 for uniform, window_type=2 for Gaussian 44 | % window_type=6 for exponentions with beta 45 | % window_type=8 for Interpolation 46 | 47 | % TYPE=00; % TYPE IS A SYMMETRY OF THE WINDOW 48 | % 00 SYMMETRIC 49 | % 10 NONSYMMETRIC ON X1 and SYMMETRIC ON X2 50 | % 11 NONSYMMETRIC ON X1,X2 (Quadrants) 51 | % 52 | % for rotated directional kernels the method that is used for rotation can be specified by adding 53 | % a binary digit in front of these types, as follows: 54 | % 55 | % 10 56 | % 11 ARE "STANDARD" USING NN (Nearest Neighb.) (you can think of these numbers with a 0 in front) 57 | % 00 58 | % 59 | % 110 60 | % 111 ARE EXACT SAMPLING OF THE EXACT ROTATED KERNEL 61 | % 100 62 | % 63 | % 210 64 | % 211 ARE WITH BILINEAR INTERP 65 | % 200 66 | % 67 | % 310 68 | % 311 ARE WITH BICUBIC INTERP (not reccomended) 69 | % 300 70 | 71 | %-------------------------------------------------------------------------- 72 | % DIRECTIONAL PARAMETERS 73 | %-------------------------------------------------------------------------- 74 | % directional_resolution=4; % number of directions 75 | 76 | 77 | 78 | 79 | 80 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 81 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 82 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 83 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 84 | %%%%% From this point onwards this file and the create_LPA_kernels.m should be identical %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 85 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | lenh=max(length(h1),length(h2)); 96 | clear kernels 97 | clear kernels_higher_order 98 | kernels=cell(directional_resolution,lenh); 99 | kernels_higher_order=cell(directional_resolution,lenh,2); 100 | THETASTEP=2*pi/directional_resolution; 101 | THETA=[0:THETASTEP:2*pi-THETASTEP]; 102 | 103 | 104 | s1=0; 105 | for theta=THETA, 106 | s1=s1+1; 107 | for s=1:lenh, 108 | 109 | 110 | [gh,gh1,gh1degrees]=function_LPAKernelMatrixTheta(ceil(h2(s)),ceil(h1(s)),window_type,[sig_winds(1,s) sig_winds(2,s)],TYPE,theta, m); 111 | kernels{s1,s}=gh; % degree=0 kernel 112 | kernels_higher_order{s1,s,1}=gh1; % degree>=0 kernels 113 | kernels_higher_order{s1,s,2}=gh1degrees; % polynomial indexes matrix 114 | 115 | end % different lengths loop 116 | end % different directions loop 117 | 118 | -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/BM3D-SAPCA/function_LPAKernelMatrixTheta.m: -------------------------------------------------------------------------------- 1 | % Return the discrete kernels for LPA estimation and their degrees matrix 2 | % 3 | % function [G, G1, index_polynomials]=function_LPAKernelMatrixTheta(h2,h1,window_type,sig_wind,TYPE,theta, m) 4 | % 5 | % 6 | % Outputs: 7 | % 8 | % G kernel for function estimation 9 | % G1 kernels for function and derivative estimation 10 | % G1(:,:,j), j=1 for function estimation, j=2 for d/dx, j=3 for d/dy, 11 | % contains 0 and all higher order kernels (sorted by degree: 12 | % 1 x y y^2 x^3 x^2y xy^2 y^3 etc...) 13 | % index_polynomials matrix of degrees first column x powers, second 14 | % column y powers, third column total degree 15 | % 16 | % 17 | % Inputs: 18 | % 19 | % h2, h1 size of the kernel (size of the "asymmetrical portion") 20 | % m=[m(1) m(2)] the vector order of the LPA any order combination should work 21 | % "theta" is an angle of the directrd window 22 | % "TYPE" is a type of the window support 23 | % "sig_wind" - vector - sigma parameters of the Gaussian wind 24 | % "beta"- parameter of the power in some weights for the window function 25 | % (these last 3 parameters are fed into function_Window2D function) 26 | % 27 | % 28 | % Alessandro Foi, 6 march 2004 29 | 30 | function [G, G1, index_polynomials]=function_LPAKernelMatrixTheta(h2,h1,window_type,sig_wind,TYPE,theta, m) 31 | global beta 32 | 33 | %G1=0; 34 | m(1)=min(h1,m(1)); 35 | m(2)=min(h2,m(2)); 36 | 37 | % builds ordered matrix of the monomes powers 38 | number_of_polynomials=(min(m)+1)*(max(m)-min(m)+1)+(min(m)+1)*min(m)/2; % =size(index_polynomials,1) 39 | index_polynomials=zeros(number_of_polynomials,2); 40 | index3=1; 41 | for index1=1:min(m)+1 42 | for index2=1:max(m)+2-index1 43 | index_polynomials(index3,:)=[index1-1,index2-1]; 44 | index3=index3+1; 45 | end 46 | end 47 | if m(1)>m(2) 48 | index_polynomials=fliplr(index_polynomials); 49 | end 50 | index_polynomials(:,3)=index_polynomials(:,1)+index_polynomials(:,2); %calculates degrees of polynomials 51 | index_polynomials=sortrows(sortrows(index_polynomials,2),3); %sorts polynomials by degree (x first) 52 | 53 | %===================================================================================================================================== 54 | 55 | halfH=max(h1,h2); 56 | H=-halfH+1:halfH-1; 57 | 58 | 59 | % creates window function and then rotates it 60 | % win_fun=zeros(halfH-1,halfH-1); 61 | for x1=H 62 | for x2=H 63 | if TYPE==00|TYPE==200|TYPE==300 % SYMMETRIC WINDOW 64 | win_fun1(x2+halfH,x1+halfH)=function_Window2D(x1/h1/(1-1000*eps),x2/h2/(1-1000*eps),window_type,sig_wind,beta,h2/h1); % weight 65 | end 66 | if TYPE==11|TYPE==211|TYPE==311 % NONSYMMETRIC ON X1,X2 WINDOW 67 | win_fun1(x2+halfH,x1+halfH)=(x1>=-0.05)*(x2>=-0.05)*function_Window2D(x1/h1/(1-1000*eps),x2/h2/(1-1000*eps),window_type,sig_wind,beta,h2/h1); % weight 68 | end 69 | if TYPE==10|TYPE==210|TYPE==310 % NONSYMMETRIC ON X1 WINDOW 70 | win_fun1(x2+halfH,x1+halfH)=(x1>=-0.05)*function_Window2D(x1/h1/(1-1000*eps),x2/h2/(1-1000*eps),window_type,sig_wind,beta,h2/h1); % weight 71 | end 72 | 73 | if TYPE==100|TYPE==110|TYPE==111 % exact sampling 74 | xt1=x1*cos(-theta)+x2*sin(-theta); 75 | xt2=x2*cos(-theta)-x1*sin(-theta); 76 | if TYPE==100 % SYMMETRIC WINDOW 77 | win_fun1(x2+halfH,x1+halfH)=function_Window2D(xt1/h1/(1-1000*eps),xt2/h2/(1-1000*eps),window_type,sig_wind,beta,h2/h1); % weight 78 | end 79 | if TYPE==111 % NONSYMMETRIC ON X1,X2 WINDOW 80 | 81 | win_fun1(x2+halfH,x1+halfH)=(xt1>=-0.05)*(xt2>=-0.05)*function_Window2D(xt1/h1/(1-1000*eps),xt2/h2/(1-1000*eps),window_type,sig_wind,beta,h2/h1); % weight 82 | end 83 | if TYPE==110 % NONSYMMETRIC ON X1 WINDOW 84 | 85 | win_fun1(x2+halfH,x1+halfH)=(xt1>=-0.05)*function_Window2D(xt1/h1/(1-1000*eps),xt2/h2/(1-1000*eps),window_type,sig_wind,beta,h2/h1); % weight 86 | end 87 | end 88 | 89 | end 90 | end 91 | win_fun=win_fun1; 92 | if (theta~=0)&(TYPE<100) 93 | win_fun=imrotate(win_fun1,theta*180/pi,'nearest'); % use 'nearest' or 'bilinear' for different interpolation schemes ('bicubic'...?) 94 | end 95 | if (theta~=0)&(TYPE>=200)&(TYPE<300) 96 | win_fun=imrotate(win_fun1,theta*180/pi,'bilinear'); % use 'nearest' or 'bilinear' for different interpolation schemes ('bicubic'...?) 97 | end 98 | if (theta~=0)&(TYPE>=300) 99 | win_fun=imrotate(win_fun1,theta*180/pi,'bicubic'); % use 'nearest' or 'bilinear' for different interpolation schemes ('bicubic'...?) 100 | end 101 | 102 | 103 | 104 | % make the weight support a square 105 | win_fun2=zeros(max(size(win_fun))); 106 | win_fun2((max(size(win_fun))-size(win_fun,1))/2+1:max(size(win_fun))-((max(size(win_fun))-size(win_fun,1))/2),(max(size(win_fun))-size(win_fun,2))/2+1:max(size(win_fun))-((max(size(win_fun))-size(win_fun,2))/2))=win_fun; 107 | win_fun=win_fun2; 108 | 109 | 110 | %===================================================================================================================================== 111 | 112 | 113 | %%%% rotated coordinates 114 | H=-(size(win_fun,1)-1)/2:(size(win_fun,1)-1)/2; 115 | halfH=(size(win_fun,1)+1)/2; 116 | h_radious=halfH; 117 | Hcos=H*cos(theta); Hsin=H*sin(theta); 118 | 119 | 120 | %%%% Calculation of FI matrix 121 | FI=zeros(number_of_polynomials); 122 | i1=0; 123 | for s1=H 124 | i1=i1+1; 125 | i2=0; 126 | for s2=H 127 | i2=i2+1; 128 | x1=Hcos(s1+h_radious)-Hsin(s2+h_radious); 129 | x2=Hsin(s1+h_radious)+Hcos(s2+h_radious); 130 | phi=sqrt(win_fun(s2+halfH,s1+halfH))*(prod(((ones(number_of_polynomials,1)*[x1 x2]).^index_polynomials(:,1:2)),2)./prod(gamma(index_polynomials(:,1:2)+1),2).*(-ones(number_of_polynomials,1)).^index_polynomials(:,3)); 131 | FI=FI+phi*phi'; 132 | end % end of s2 133 | end % end of s1 134 | 135 | %FI_inv=((FI+1*eps*eye(size(FI)))^(-1)); % invert FI matrix 136 | FI_inv=pinv(FI); % invert FI matrix (using pseudoinverse) 137 | G1=zeros([size(H,2) size(H,2) number_of_polynomials]); 138 | 139 | %%%% Calculation of mask 140 | i1=0; 141 | for s1=H 142 | i1=i1+1; 143 | i2=0; 144 | for s2=H 145 | i2=i2+1; 146 | x1=Hcos(s1+h_radious)-Hsin(s2+h_radious); 147 | x2=Hsin(s1+h_radious)+Hcos(s2+h_radious); 148 | phi=FI_inv*win_fun(s2+halfH,s1+halfH)*(prod(((ones(number_of_polynomials,1)*[x1 x2]).^index_polynomials(:,1:2)),2)./prod(gamma(index_polynomials(:,1:2)+1),2).*(-ones(number_of_polynomials,1)).^index_polynomials(:,3)); 149 | G(i2,i1,1)=phi(1); % Function Est 150 | G1(i2,i1,:)=phi(:)'; % Function est & Der est on X Y etc... 151 | end % end of s1 152 | end % end of s2 153 | %keyboard -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/BM3D-SAPCA/function_WOSFilters.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/BM3D-SAPCA/function_WOSFilters.p -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/BM3D-SAPCA/function_Window2D.m: -------------------------------------------------------------------------------- 1 | % Returns a scalar/matrix weights (window function) for the LPA estimates 2 | % function w=function_Window2D(X,Y,window,sig_wind, beta); 3 | % X,Y scalar/matrix variables 4 | % window - type of the window weight 5 | % sig_wind - std scaling for the Gaussian ro-weight 6 | % beta -parameter of the degree in the weights 7 | %---------------------------------------------------------------------------------- 8 | % V. Katkovnik & A. Foi - Tampere University of Technology - 2002-2005 9 | 10 | 11 | function w=function_Window2D(X,Y,window,sig_wind, beta,ratio); 12 | 13 | if nargin == 5 14 | ratio=1; 15 | end 16 | 17 | IND=(abs(X)<=1)&(abs(Y)<=1); 18 | IND2=((X.^2+Y.^2)<=1); 19 | IND3=((X.^2+(Y*ratio).^2)<=1); 20 | 21 | 22 | if window==1 % rectangular symmetric window 23 | w=IND; end 24 | 25 | if window==2 %Gaussian 26 | 27 | X=X/sig_wind(1); 28 | Y=Y/sig_wind(2); 29 | w = IND.*exp(-(X.^2 + Y.^2)/2); %*(abs(Y)<=0.1*abs(X));%.*IND2; %((X.^2+Y.^2)<=1); 30 | end 31 | 32 | if window==3 % Quadratic window 33 | w=(1-(X.^2+Y.^2)).*((X.^2+Y.^2)<=1); end 34 | 35 | if window==4 % triangular symmetric window 36 | w=(1-abs(X)).*(1-abs(Y)).*((X.^2+Y.^2)<=1); end 37 | 38 | 39 | if window==5 % Epanechnikov symmetric window 40 | w=(1-X.^2).*(1-Y.^2).*((X.^2+Y.^2)<=1); 41 | end 42 | 43 | if window==6 % Generalized Gaussian 44 | 45 | X=X/sig_wind; 46 | Y=Y/sig_wind; 47 | w = exp(-((X.^2 + Y.^2).^beta)/2).*((X.^2+Y.^2)<=1); end 48 | 49 | 50 | if window==7 51 | 52 | X=X/sig_wind; 53 | Y=Y/sig_wind; 54 | w = exp(-abs(X) - abs(Y)).*IND; end 55 | 56 | if window==8 % Interpolation 57 | 58 | w=(1./(abs(X).^4+abs(Y).^4+0.0001)).*IND2; 59 | end 60 | 61 | if window==9 % Interpolation 62 | 63 | NORM=(abs(X)).^2+(abs(Y)).^2+0.0001; 64 | w=(1./NORM.*(1-sqrt(NORM)).^2).*(NORM<=1); 65 | end 66 | 67 | if window==10 68 | w=((X.^2+Y.^2)<=1); 69 | end 70 | 71 | 72 | if window==11 73 | 74 | temp=asin(Y./sqrt(X.^2+Y.^2+eps)); 75 | temp=temp*0.6; % Width of Beam 76 | temp=(temp>0)*min(temp,1)+(temp<=0)*max(temp,-1); 77 | 78 | w=max(0,IND.*cos(pi*temp)); 79 | 80 | 81 | end 82 | 83 | 84 | 85 | if window==111 86 | 87 | temp=asin(Y./sqrt(X.^2+Y.^2+eps)); 88 | temp=temp*0.8; % Width of Beam 89 | temp=(temp>0)*min(temp,1)+(temp<=0)*max(temp,-1); 90 | 91 | w=max(0,IND3.*(cos(pi*temp)>0)); 92 | % w=((X.^2+Y.^2)<=1); 93 | end 94 | 95 | if window==112 96 | 97 | temp=atan(Y/(X+eps)); 98 | %temp=temp*0.8; % Width of Beam 99 | %temp=(temp>0)*min(temp,1)+(temp<=0)*max(temp,-1); 100 | w=max(0,IND3.*((abs(temp))<=pi/4)); 101 | % w=((X.^2+Y.^2)<=1); 102 | 103 | end 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/BM3DSHARP.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/BM3DSHARP.m -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/BM3D_CFA.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/BM3D_CFA.m -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/CVBM3D.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/CVBM3D.m -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/ClipComp16b.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/ClipComp16b.p -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/IDDBM3D/BM3DDEB_init.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/IDDBM3D/BM3DDEB_init.m -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/IDDBM3D/BlockMatch.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/IDDBM3D/BlockMatch.mexw32 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/IDDBM3D/BlockMatch.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/IDDBM3D/BlockMatch.mexw64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/IDDBM3D/Demo_IDDBM3D.m: -------------------------------------------------------------------------------- 1 | function [isnr, y_hat] = Demo_IDDBM3D(experiment_number, test_image_name) 2 | % ------------------------------------------------------------------------------------------ 3 | % 4 | % Demo software for BM3D-frame based image deblurring 5 | % Public release ver. 0.8 (beta) (June 03, 2011) 6 | % 7 | % ------------------------------------------------------------------------------------------ 8 | % 9 | % This function implements the IDDBM3D image deblurring algorithm proposed in: 10 | % 11 | % [1] A.Danielyan, V. Katkovnik, and K. Egiazarian, "BM3D frames and 12 | % variational image deblurring," submitted to IEEE TIP, May 2011 13 | % 14 | % ------------------------------------------------------------------------------------------ 15 | % 16 | % authors: Aram Danielyan 17 | % Vladimir Katkovnik 18 | % 19 | % web page: http://www.cs.tut.fi/~foi/GCF-BM3D/ 20 | % 21 | % contact: firstname.lastname@tut.fi 22 | % 23 | % ------------------------------------------------------------------------------------------ 24 | % Copyright (c) 2011 Tampere University of Technology. 25 | % All rights reserved. 26 | % This work should be used for nonprofit purposes only. 27 | % ------------------------------------------------------------------------------------------ 28 | % 29 | % Disclaimer 30 | % ---------- 31 | % 32 | % Any unauthorized use of these routines for industrial or profit-oriented activities is 33 | % expressively prohibited. By downloading and/or using any of these files, you implicitly 34 | % agree to all the terms of the TUT limited license (included in the file Legal_Notice.txt). 35 | % ------------------------------------------------------------------------------------------ 36 | 37 | 38 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 39 | % FUNCTION INTERFACE: 40 | % 41 | % [psnr, y_hat] = Demo_IDDBM3D(experiment_number, test_image_name) 42 | % 43 | % INPUT: 44 | % 1) experiment_number: 1 -> PSF 1, sigma^2 = 2 45 | % 2 -> PSF 1, sigma^2 = 8 46 | % 3 -> PSF 2, sigma^2 = 0.308 47 | % 4 -> PSF 3, sigma^2 = 49 48 | % 5 -> PSF 4, sigma^2 = 4 49 | % 6 -> PSF 5, sigma^2 = 64 50 | % 7-13 -> experiments 7-13 are not described in [1]. 51 | % see this file for the blur and noise parameters. 52 | % 2) test_image_name: a valid filename of a grayscale test image 53 | % 54 | % OUTPUT: 55 | % 1) isnr the output improvement in SNR, dB 56 | % 2) y_hat: the restored image 57 | % 58 | % ! The function can work without any of the input arguments, 59 | % in which case, the internal default ones are used ! 60 | % 61 | % To run this demo functions within the BM3D package should be accessible to Matlab 62 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 63 | addpath('../') 64 | 65 | if ~exist('experiment_number','var'), experiment_number=3; end 66 | if ~exist('test_image_name','var'), test_image_name='Cameraman256.png'; end 67 | 68 | filename=test_image_name; 69 | 70 | if 1 % 71 | initType = 'bm3ddeb'; %use output of the BM3DDEB to initialize the algorithm 72 | else 73 | initType = 'zeros'; %use zero image to initialize the algorithm 74 | end 75 | 76 | matchType = 'bm3ddeb'; %build groups using output of the BM3DDEB algorithm 77 | numIt = 200; 78 | 79 | fprintf('Experiment number: %d\n', experiment_number); 80 | fprintf('Image: %s\n', filename); 81 | 82 | %% ------- Generating bservation --------------------------------------------- 83 | disp('--- Generating observation ----'); 84 | y=im2double(imread(filename)); 85 | 86 | [yN,xN]=size(y); 87 | 88 | switch experiment_number 89 | case 1 90 | sigma=sqrt(2)/255; 91 | for x1=-7:7; for x2=-7:7; h(x1+8,x2+8)=1/(x1^2+x2^2+1); end, end; h=h./sum(h(:)); 92 | case 2 93 | sigma=sqrt(8)/255; 94 | s1=0; for a1=-7:7; s1=s1+1; s2=0; for a2=-7:7; s2=s2+1; h(s1,s2)=1/(a1^2+a2^2+1); end, end; h=h./sum(h(:)); 95 | case 3 96 | BSNR=40; 97 | sigma=-1; % if "sigma=-1", then the value of sigma depends on the BSNR 98 | h=ones(9); h=h./sum(h(:)); 99 | case 4 100 | sigma=7/255; 101 | h=[1 4 6 4 1]'*[1 4 6 4 1]; h=h./sum(h(:)); % PSF 102 | case 5 103 | sigma=2/255; 104 | h=fspecial('gaussian', 25, 1.6); 105 | case 6 106 | sigma=8/255; 107 | h=fspecial('gaussian', 25, .4); 108 | %extra experiments 109 | case 7 110 | BSNR=30; 111 | sigma=-1; 112 | h=ones(9); h=h./sum(h(:)); 113 | case 8 114 | BSNR=20; 115 | sigma=-1; 116 | h=ones(9); h=h./sum(h(:)); 117 | case 9 118 | BSNR=40; 119 | sigma=-1; 120 | h=fspecial('gaussian', 25, 1.6); 121 | case 10 122 | BSNR=20; 123 | sigma=-1; 124 | h=fspecial('gaussian', 25, 1.6); 125 | case 11 126 | BSNR=15; 127 | sigma=-1; 128 | h=fspecial('gaussian', 25, 1.6); 129 | case 12 130 | BSNR=40; 131 | sigma=-1; % if "sigma=-1", then the value of sigma depends on the BSNR 132 | h=ones(19); h=h./sum(h(:)); 133 | case 13 134 | BSNR=25; 135 | sigma=-1; % if "sigma=-1", then the value of sigma depends on the BSNR 136 | h=ones(19); h=h./sum(h(:)); 137 | end 138 | 139 | y_blur = imfilter(y, h, 'circular'); % performs blurring (by circular convolution) 140 | 141 | if sigma == -1; %% check whether to use BSNR in order to define value of sigma 142 | sigma=sqrt(norm(y_blur(:)-mean(y_blur(:)),2)^2 /(yN*xN*10^(BSNR/10))); 143 | % Xv% compute sigma from the desired BSNR 144 | end 145 | 146 | %%%% Create a blurred and noisy observation 147 | randn('seed',0); 148 | z = y_blur + sigma*randn(yN, xN); 149 | 150 | bsnr=10*log10(norm(y_blur(:)-mean(y_blur(:)),2)^2 /sigma^2/yN/xN); 151 | psnr_z =PSNR(y,z,1,0); 152 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 153 | 154 | fprintf('Observation BSNR: %4.2f, PSNR: %4.2f\n', bsnr, psnr_z); 155 | 156 | %% ----- Computing initial estimate --------------------- 157 | disp('--- Computing initial estimate ----'); 158 | 159 | [dummy, y_hat_RI,y_hat_RWI,zRI] = BM3DDEB_init(experiment_number, y, z, h, sigma); 160 | 161 | switch lower(initType) 162 | case 'zeros' 163 | y_hat_init=zeros(size(z)); 164 | case 'zri' 165 | y_hat_init=zRI; 166 | case 'ri' 167 | y_hat_init=y_hat_RI; 168 | case 'bm3ddeb' 169 | y_hat_init=y_hat_RWI; 170 | 171 | end 172 | 173 | switch lower(matchType) 174 | case 'z' 175 | match_im = z; 176 | case 'y' 177 | match_im = y; 178 | case 'zri' 179 | match_im = zRI; 180 | case 'ri' 181 | match_im = y_hat_RI; 182 | case 'bm3ddeb' 183 | match_im = y_hat_RWI; 184 | end 185 | 186 | psnr_init = PSNR(y, y_hat_init,1,0); 187 | 188 | fprintf('Initialization method: %s\n', initType); 189 | fprintf('Initial estimate ISNR: %4.2f, PSNR: %4.2f\n', psnr_init-psnr_z, psnr_init); 190 | 191 | %% ------- Core algorithm --------------------- 192 | %------ Description of the parameters of the IDDBM3D function ---------- 193 | %y - true image (use [] if true image is unavaliable) 194 | %z - observed 195 | %h - blurring PSF 196 | %y_hat_init - initial estimate y_0 197 | %match_im - image used to constuct groups and calculate weights g_r 198 | %sigma - standard deviation of the noise 199 | %threshType = 'h'; %use 's' for soft thresholding 200 | %numIt - number of iterations 201 | %gamma - regularization parameter see [1] 202 | %tau - regularization parameter see [1] (thresholding level) 203 | %xi - regularization parameter see [1], it is always set to 1 in this implementation 204 | %showFigure - set to True to display figure with current estimate 205 | %-------------------------------------------------------------------- 206 | 207 | threshType = 'h'; 208 | showFigure = true; 209 | 210 | switch threshType 211 | case {'s'} 212 | gamma_tau_xi_inits= [ 213 | 0.0004509 0.70 1;%1 214 | 0.0006803 0.78 1;%2 215 | 0.0003485 0.65 1;%3 216 | 0.0005259 0.72 1;%4 217 | 0.0005327 0.82 1;%5 218 | 7.632e-05 0.25 1;%6 219 | 0.0005818 0.81 1;%7 220 | 0.001149 1.18 1;%8 221 | 0.0004155 0.74 1;%9 222 | 0.0005591 0.74 1;%10 223 | 0.0007989 0.82 1;%11 224 | 0.0006702 0.75 1;%12 225 | 0.001931 1.83 1;%13 226 | ]; 227 | case {'h'} 228 | gamma_tau_xi_inits= [ 229 | 0.00051 3.13 1;%1 230 | 0.0006004 2.75 1;%2 231 | 0.0004573 2.91 1;%3 232 | 0.0005959 2.82 1;%4 233 | 0.0006018 3.63 1;%5 234 | 0.0001726 2.24 1;%6 235 | 0.00062 2.98 1;%7 236 | 0.001047 3.80 1;%8 237 | 0.0005125 3.00 1;%9 238 | 0.0005685 2.80 1;%10 239 | 0.0005716 2.75 1;%11 240 | 0.0005938 2.55 1;%12 241 | 0.001602 4.16 1;%13 242 | ]; 243 | end 244 | 245 | gamma = gamma_tau_xi_inits(experiment_number,1); 246 | tau = gamma_tau_xi_inits(experiment_number,2)/255*2.7; 247 | xi = gamma_tau_xi_inits(experiment_number,3); 248 | 249 | disp('-------- Start ----------'); 250 | fprintf('Number of iterations to perform: %d\n', numIt); 251 | fprintf('Thresholding type: %s\n', threshType); 252 | 253 | y_hat = IDDBM3D(y, h, z, y_hat_init, match_im, sigma, threshType, numIt, gamma, tau, xi, showFigure); 254 | psnr = PSNR(y,y_hat,1,0); 255 | isnr = psnr-psnr_z; 256 | 257 | disp('-------- Results --------'); 258 | fprintf('Final estimate ISNR: %4.2f, PSNR: %4.2f\n', isnr, psnr); 259 | return; 260 | 261 | end 262 | 263 | function PSNRdb = PSNR(x, y, maxval, borders) 264 | if ~exist('borders', 'var'), borders = 0; end 265 | if ~exist('maxval', 'var'), maxval = 255; end 266 | 267 | xx=borders+1:size(x,1)-borders; 268 | yy=borders+1:size(x,2)-borders; 269 | 270 | PSNRdb = zeros(1,size(x,3)); 271 | for fr=1:size(x,3) 272 | err = x(xx,yy,fr) - y(xx,yy,fr); 273 | PSNRdb(fr) = 10 * log10((maxval^2)/mean2(err.^2)); 274 | end 275 | end -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/IDDBM3D/GroupProcessor.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/IDDBM3D/GroupProcessor.mexw32 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/IDDBM3D/GroupProcessor.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/IDDBM3D/GroupProcessor.mexw64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/IDDBM3D/IDDBM3D.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/IDDBM3D/IDDBM3D.p -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/LEGAL_NOTICE.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/LEGAL_NOTICE.txt -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/README.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/README.txt -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/VBM3D.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/VBM3D.m -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_CFA_thr.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_CFA_thr.mexa64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_CFA_thr.mexglx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_CFA_thr.mexglx -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_CFA_thr.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_CFA_thr.mexmaci64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_CFA_thr.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_CFA_thr.mexw32 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_CFA_thr.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_CFA_thr.mexw64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_CFA_wiener.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_CFA_wiener.mexa64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_CFA_wiener.mexglx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_CFA_wiener.mexglx -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_CFA_wiener.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_CFA_wiener.mexmaci64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_CFA_wiener.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_CFA_wiener.mexw32 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_CFA_wiener.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_CFA_wiener.mexw64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr.mexa64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr.mexglx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr.mexglx -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr.mexmaci: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr.mexmaci -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr.mexmaci64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr.mexw32 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr.mexw64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_color.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_color.mexa64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_color.mexglx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_color.mexglx -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_color.mexmaci: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_color.mexmaci -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_color.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_color.mexmaci64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_color.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_color.mexw32 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_color.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_color.mexw64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_colored_noise.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_colored_noise.mexa64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_colored_noise.mexglx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_colored_noise.mexglx -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_colored_noise.mexmaci: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_colored_noise.mexmaci -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_colored_noise.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_colored_noise.mexmaci64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_colored_noise.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_colored_noise.mexw32 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_colored_noise.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_colored_noise.mexw64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_sharpen_var.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_sharpen_var.mexa64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_sharpen_var.mexglx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_sharpen_var.mexglx -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_sharpen_var.mexmaci: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_sharpen_var.mexmaci -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_sharpen_var.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_sharpen_var.mexmaci64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_sharpen_var.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_sharpen_var.mexw32 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_sharpen_var.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_sharpen_var.mexw64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_video.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_video.mexa64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_video.mexglx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_video.mexglx -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_video.mexmaci: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_video.mexmaci -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_video.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_video.mexmaci64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_video.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_video.mexw32 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_video.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_video.mexw64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_video_c.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_video_c.mexw32 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_thr_video_c.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_thr_video_c.mexw64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener.mexa64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener.mexglx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener.mexglx -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener.mexmaci: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener.mexmaci -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener.mexmaci64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener.mexw32 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener.mexw64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener_color.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener_color.mexa64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener_color.mexglx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener_color.mexglx -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener_color.mexmaci: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener_color.mexmaci -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener_color.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener_color.mexmaci64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener_color.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener_color.mexw32 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener_color.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener_color.mexw64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener_colored_noise.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener_colored_noise.mexa64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener_colored_noise.mexglx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener_colored_noise.mexglx -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener_colored_noise.mexmaci: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener_colored_noise.mexmaci -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener_colored_noise.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener_colored_noise.mexmaci64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener_colored_noise.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener_colored_noise.mexw32 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener_colored_noise.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener_colored_noise.mexw64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener_video.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener_video.mexa64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener_video.mexglx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener_video.mexglx -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener_video.mexmaci: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener_video.mexmaci -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener_video.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener_video.mexmaci64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener_video.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener_video.mexw32 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener_video.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener_video.mexw64 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener_video_c.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener_video_c.mexw32 -------------------------------------------------------------------------------- /data/rank_tid2013/BM3D/bm3d_wiener_video_c.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/BM3D/bm3d_wiener_video_c.mexw64 -------------------------------------------------------------------------------- /data/rank_tid2013/BlockWise.m: -------------------------------------------------------------------------------- 1 | function b=BlockWise(img,level,flag) 2 | 3 | R_mean = mean(mean(img(:,:,1))); 4 | G_mean = mean(mean(img(:,:,2))); 5 | B_mean = mean(mean(img(:,:,3))); 6 | W = size(img,1); 7 | H = size(img,2); 8 | 9 | switch flag 10 | case 5 11 | block = repmat([R_mean G_mean B_mean]',[1,32,32]); 12 | block = permute(block,[3,2,1]); 13 | case 4 14 | block = repmat([R_mean G_mean B_mean]',[1,32,32]); 15 | block = permute(block,[3,2,1]); 16 | case 3 17 | block = repmat([R_mean+30 G_mean B_mean]',[1,32,32]); 18 | block = permute(block,[3,2,1]); 19 | case 2 20 | block = repmat([R_mean+50 G_mean B_mean]',[1,32,32]); 21 | block = permute(block,[3,2,1]); 22 | case 1 23 | block = repmat([0 G_mean B_mean]',[1,32,32]); 24 | block = permute(block,[3,2,1]); 25 | end 26 | 27 | block = uint8(block); 28 | 29 | for i=1:level 30 | r_W = randi([1 W-32],1); 31 | r_H = randi([2 H-32],1); 32 | img(r_W:r_W+31,r_H:r_H+31,:) = block; 33 | end 34 | 35 | b= img; 36 | 37 | end -------------------------------------------------------------------------------- /data/rank_tid2013/CA.m: -------------------------------------------------------------------------------- 1 | function b= CA(img_rgb,level) 2 | 3 | hsize=3; 4 | 5 | R=(img_rgb(:,:,1)); 6 | G=(img_rgb(:,:,3)); 7 | B=(img_rgb(:,:,2)); 8 | R2=R; 9 | B2=B; 10 | R2(:,level:end)=R(:,1:end-level+1); 11 | B2(:,level/2:end)=B(:,1:end-level/2+1); 12 | temp = img_rgb; 13 | temp(:,:,1)=R2; 14 | temp(:,:,2)=B2; 15 | img=temp; 16 | h = fspecial('gaussian', hsize, hsize/6); 17 | b=imfilter(img,h,'symmetric'); 18 | 19 | 20 | end -------------------------------------------------------------------------------- /data/rank_tid2013/ColorSaturation.m: -------------------------------------------------------------------------------- 1 | function b = ColorSaturation(img_rgb,level) 2 | 3 | ycbcr = rgb2ycbcr(img_rgb); 4 | ycbcr = im2double(ycbcr); 5 | ycbcr(:,:,2) = 0.5 + (ycbcr(:,:,2)-0.5)*level; 6 | ycbcr(:,:,3) = 0.5 + (ycbcr(:,:,3)-0.5)*level; 7 | b=ycbcr2rgb(ycbcr); 8 | b=uint8(b*255); 9 | 10 | end -------------------------------------------------------------------------------- /data/rank_tid2013/ContrastChange.m: -------------------------------------------------------------------------------- 1 | function b = ContrastChange(img,level) 2 | 3 | img = im2double(img)*255; 4 | img= img*level; 5 | b = uint8(img); 6 | end -------------------------------------------------------------------------------- /data/rank_tid2013/HighFN.m: -------------------------------------------------------------------------------- 1 | function img2 = HighFN(img,level) 2 | 3 | imgFFT = fft2(double(img)); 4 | thresh = 10; 5 | b(:,:,1) = ghp(imgFFT(:,:,1),thresh); 6 | b(:,:,2) = ghp(imgFFT(:,:,2),thresh); 7 | b(:,:,3) = ghp(imgFFT(:,:,3),thresh); 8 | 9 | img2 = ifft2(b); 10 | img2 = real(img2); 11 | img2= uint8(img2); 12 | img2 = imnoise(img2,'gaussian',0,level); 13 | 14 | end -------------------------------------------------------------------------------- /data/rank_tid2013/ImageDenoising.m: -------------------------------------------------------------------------------- 1 | function b= ImageDenoising(img, level) 2 | distorted_img = imnoise(img,'gaussian',0,level); 3 | 4 | yRGB = im2double(distorted_img); 5 | % Generate the same seed used in the experimental results of [1] 6 | randn('seed', 0); 7 | % Standard deviation of the noise --- corresponding to intensity 8 | % range [0,255], despite that the input was scaled in [0,1] 9 | sigma = 25; 10 | % Add the AWGN with zero mean and standard deviation 'sigma' 11 | zRGB = yRGB + (sigma/255)*randn(size(yRGB)); 12 | % Denoise 'zRGB'. The denoised image is 'yRGB_est', and 'NA = 1' 13 | % because the true image was not provided 14 | [~, yRGB_est] = CBM3D(1, zRGB, sigma); 15 | % Compute the putput PSNR 16 | % PSNR = 10*log10(1/mean((yRGB(:)-yRGB_est(:)).^2)) 17 | % show the noisy image 'zRGB' and the denoised 'yRGB_est' 18 | % figure; imshow(min(max(zRGB,0),1)); 19 | % figure; imshow(min(max(yRGB_est,0),1)); 20 | b = uint8(yRGB_est*255); 21 | 22 | end -------------------------------------------------------------------------------- /data/rank_tid2013/MeanShift.m: -------------------------------------------------------------------------------- 1 | function b = MeanShift(img,level) 2 | 3 | img = img + level; 4 | 5 | b = uint8(img); 6 | 7 | 8 | end -------------------------------------------------------------------------------- /data/rank_tid2013/MultiGN.m: -------------------------------------------------------------------------------- 1 | function b= MultiGN(img_rgb,level) 2 | 3 | img_rgb = im2double(img_rgb)*255; 4 | noiseOnlyImage = 1+level* randn(size(img_rgb,1),size(img_rgb,2)); 5 | img_rgb(:,:,1) = img_rgb(:,:,1) .* noiseOnlyImage; 6 | 7 | noiseOnlyImage = 1+level* randn(size(img_rgb,1),size(img_rgb,2)); 8 | img_rgb(:,:,2) = img_rgb(:,:,2) .* noiseOnlyImage; 9 | 10 | noiseOnlyImage = 1+level * randn(size(img_rgb,1),size(img_rgb,2)); 11 | img_rgb(:,:,3) = img_rgb(:,:,3) .* noiseOnlyImage; 12 | 13 | b=uint8(img_rgb); 14 | 15 | end -------------------------------------------------------------------------------- /data/rank_tid2013/QuantizationNoise.m: -------------------------------------------------------------------------------- 1 | function b = QuantizationNoise(img, level) 2 | 3 | threshRGB = multithresh(img,level); 4 | 5 | threshForPlanes = zeros(3,level); 6 | 7 | for i = 1:3 8 | threshForPlanes(i,:) = multithresh(img(:,:,i),level); 9 | end 10 | 11 | value = [0 threshRGB(2:end) 255]; 12 | b = imquantize(img, threshRGB, value); 13 | 14 | end -------------------------------------------------------------------------------- /data/rank_tid2013/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## The code for generating ranking dataset for tid2013 dataset (17 distortions) 3 | 4 | Put your original images in pristine_images folder and run the main function. 5 | 6 | ``` 7 | run tid2013_main.m 8 | 9 | ``` 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /data/rank_tid2013/correlatedGaussianNoise.m: -------------------------------------------------------------------------------- 1 | function [result, sampRpp] = correlatedGaussianNoise(Rpp, nSamp) 2 | %% generates correlated 0-mean Gaussian vector process 3 | % 4 | % inputs: Rpp - correlation matrix. must be positive definite 5 | % and size determines output vector 6 | % nSamp - number of independent samples of correlated process 7 | % 8 | % output: result - matrix of dimension Rpp rows X nSamp cols. 9 | % sampRpp - sample correlation matrix 10 | % 11 | % result has form: 12 | % < ------ nSamp -------> 13 | % ------------------------ data is correlated along 14 | % | | | all rows for each column 15 | % | | output | 16 | % p | data matrix | data is independent along 17 | % | | | all columns for a given row 18 | % | | | 19 | % < -------- nSamp ------> 20 | % 21 | % example: use following correlation matrix (output implicitly 3 rows) 22 | % [1 0.2 0.2] 23 | % [0.2 1 0.2] 24 | % [0.2 0.2 1 ] 25 | % 26 | % and 1e5 samples to check function 27 | % 28 | %% 29 | % n = 3; Rpp = repmat(0.2, [n,n]); Rpp(1:(n+1):n^2) = 1; 30 | % disp(Rpp) 31 | % nSamp = 1e5; 32 | % [x, sampR] = correlatedGaussianNoise(Rpp, nSamp); 33 | % disp(sampR) 34 | % 35 | %% ----------------------------------------------------- 36 | % michaelB 37 | % 38 | 39 | %% algorithm 40 | 41 | % check dimenions - add other checking as necessary... 42 | if(ndims(Rpp) ~= 2), 43 | result = []; 44 | error('Rpp must be a real-valued symmetric matrix'); 45 | return; 46 | end 47 | 48 | % symmeterize the correlation matrix 49 | Rpp = 0.5 .*(double(Rpp) + double(Rpp')); 50 | 51 | % eigen decomposition 52 | [V,D] = eig(Rpp); 53 | 54 | % check for positive definiteness 55 | if(any(diag(D) <= 0)), 56 | result = []; 57 | error('Rpp must be a positive definite'); 58 | return; 59 | end 60 | 61 | % form correlating filter 62 | W = V*sqrt(D); 63 | 64 | % form white noise dataset 65 | n = randn(size(Rpp,1), nSamp); 66 | 67 | % correlated (colored) noise 68 | result = W * n; 69 | 70 | % calculate the sample correlation matrix if necessary 71 | if(nargout == 2), 72 | sampRpp = 0; 73 | for k1=1:nSamp, 74 | sampRpp = sampRpp + result(:,k1) * (result(:,k1)'); 75 | end 76 | 77 | % unbiased estimate 78 | sampRpp = sampRpp ./ (nSamp - 1); 79 | end 80 | -------------------------------------------------------------------------------- /data/rank_tid2013/ghp.m: -------------------------------------------------------------------------------- 1 | function res = ghp(im,thresh) 2 | % inputs 3 | % im is the fourier transform of the image 4 | % thresh is the cutoff circle radius 5 | %outputs 6 | % res is the filtered image 7 | [r,c]=size(im); 8 | d0=thresh; 9 | d=zeros(r,c); 10 | h=zeros(r,c); 11 | for i=1:r 12 | for j=1:c 13 | d(i,j)= sqrt( (i-(r/2))^2 + (j-(c/2))^2); 14 | end 15 | end 16 | for i=1:r 17 | for j=1:c 18 | h(i,j)=1- exp ( -( (d(i,j)^2)/(2*(d0^2)) ) ); 19 | end 20 | end 21 | for i=1:r 22 | for j=1:c 23 | res(i,j)=(h(i,j))*im(i,j); 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /data/rank_tid2013/gnc.m: -------------------------------------------------------------------------------- 1 | function b = gnc(img_rgb,level) 2 | 3 | ycbcr = rgb2ycbcr(img_rgb); 4 | ycbcr = im2double(ycbcr); 5 | sizeA = size(ycbcr); 6 | b = ycbcr + sqrt(level)*randn(sizeA); 7 | b=ycbcr2rgb(b)*255; 8 | b=uint8(b); 9 | 10 | end -------------------------------------------------------------------------------- /data/rank_tid2013/nepn.m: -------------------------------------------------------------------------------- 1 | function b = nepn(img, level) 2 | 3 | W = size(img,1); 4 | H = size(img,2); 5 | 6 | img_out = img; 7 | 8 | for i=1:level 9 | r_W = randi([1 W-30],1); 10 | r_H = randi([1 H-30],1); 11 | img_out(r_W:r_W+14,r_H:r_H+14,:) = img(r_W+5:r_W+19,r_H+5:r_H+19,:); 12 | 13 | end 14 | b= img_out; 15 | 16 | end -------------------------------------------------------------------------------- /data/rank_tid2013/open_bitfield_bmp.m: -------------------------------------------------------------------------------- 1 | function [out_im,status ] = open_bitfield_bmp( filename ) 2 | % OPEN_BITFIELD_BMP open a bitfield compressed bitmap image. 3 | % 4 | % IM = OPEN_BITFIELD_BMP( FILENAME ) opens a 16-bit bitmapped compressed file 5 | % named FILENAME. The output is formatted as three planes of Red, Green 6 | % and Blue data. 7 | % 8 | % See also imread, imfinfo 9 | 10 | % Get information about the image 11 | info = imfinfo(filename); 12 | 13 | % if we have a bitfield compressed R-G-B bitmap image 14 | if ( strcmp(info.Format , 'bmp') && ... 15 | strcmp(info.CompressionType , 'bitfields') && ... 16 | (info.BitDepth == 16 || info.BitDepth == 32) ) 17 | 18 | % indicate the input bmp file is not of 8-bit 19 | status = 0; 20 | 21 | % Open the file for reading 22 | fid = fopen(filename, 'r'); 23 | 24 | % Extract relevvant image info 25 | data_offset = info.ImageDataOffset; 26 | width = info.Width; 27 | height = info.Height; 28 | 29 | % Create space for output image 30 | out_im = zeros(height, width, 3); 31 | 32 | % Seek to where the image data begins (i.e. skip the file header 33 | fseek(fid, data_offset, 'bof'); 34 | 35 | % Read in the image data and format it into a matrix 36 | if (info.BitDepth == 16) 37 | % compressed_image = (fread(fid, [width + 1, height] , 'uint16'))'; 38 | compressed_image = (fread(fid, [width, height] , 'uint16'))'; 39 | else 40 | compressed_image = (fread(fid, [width, height] , 'uint32'))'; 41 | end 42 | 43 | % Eliminate last column of junk data (scanline row terminators) in 16 44 | % bit mode 45 | if (info.BitDepth == 16) 46 | compressed_image = compressed_image(:, 1:(width)); 47 | end; 48 | 49 | % Invert Row Order since it is flipped 50 | new_image = flipud(compressed_image); 51 | 52 | % Extract color bitmasks to decompress 53 | red_mask = info.RedMask; 54 | blue_mask = info.BlueMask; 55 | green_mask = info.GreenMask; 56 | 57 | 58 | % Extract color components and form output image 59 | out_im(:,:,1) = (bitand(new_image, red_mask) / red_mask * 255); 60 | out_im(:,:,2) = (bitand(new_image, green_mask) / green_mask * 255); 61 | out_im(:,:,3) = (bitand(new_image, blue_mask) / blue_mask * 255); 62 | 63 | % typecast 64 | out_im = uint8(out_im); 65 | 66 | % display image 67 | %imshow(out_im); 68 | 69 | else 70 | 71 | % indicate the input bmp file is 8-bit 72 | status = 1; 73 | 74 | % general imread for all other cases 75 | out_im = imread(filename); 76 | %imshow(out_im); 77 | 78 | end 79 | 80 | -------------------------------------------------------------------------------- /data/rank_tid2013/pristine_images/00001.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/data/rank_tid2013/pristine_images/00001.bmp -------------------------------------------------------------------------------- /data/rank_tid2013/tid2013_generator.m: -------------------------------------------------------------------------------- 1 | function tid2013_generator( img, dist_type, level, filename ) 2 | %% set distortion parameter 3 | wn_level = [0.001, 0.005,0.01, 0.05]; % #1 Gaussian noise 4 | gnc_level = [0.0140,0.0198,0.0343,0.0524]; % #2 Gaussian noise in color components 5 | hfn_level = [0.001,0.005,0.01,0.05]; % #5 High frequency noise 6 | in_level = [0.005,0.01,0.05,0.1]; % #6 Impulse noise 7 | qn_level = int32([255./27,255./39,255./55,255./76]); % #7 Quantization noise 8 | gblur_level = [7,15,39,91]; % #8 Gaussian Blur 9 | id_level = [0.001, 0.005,0.01, 0.05]; % #9 Image Denoising 10 | jpeg_level = [43,12,7,4]; % #10 JPEG compression 11 | jp2k_level = [0.46,0.16,0.07,0.04]; % #11 JP2K compression 12 | nepn_level = [30,70,150,300]; % #14 Non eccentricity pattern noise 13 | bw_level = [2,4,8,16,32]; % #15 Local block-wise distortions of different intensity 14 | ms_level = [15,30,45,60] ; % #16 Mean shift MSH =[15,30,45,60] MSL = [-15,-30,-45,-60] 15 | cc_level = [0.85,0.7,0.55,0.4]; % #17 Contrast change [0.85,0.7,0.55,0.4] [1.2,1.4,1.6,1.8] 16 | cs_level = [0.4,0,-0.4,-0.8]; % #18 color saturation 17 | mgn_level = [0.05, 0.09,0.13, 0.2]; % #19 Multiplicative Gaussian noise 18 | cqd_level = [64,32, 16,8,4]; % #22 Color quantization dither 19 | ca_level = [2,6,10,14]; % #23 Color aberrations 20 | %% distortion generation 21 | switch dist_type 22 | 23 | case 1 24 | strname = './GN/GN'; 25 | 26 | testName = fullfile([strname, int2str(level)],[filename.name(1:end-4),'.bmp']); 27 | distorted_img = imnoise(img,'gaussian',0,(wn_level(level))); 28 | if ~exist([strname, int2str(level)], 'dir') 29 | mkdir([strname, int2str(level)]); 30 | end 31 | imwrite(distorted_img,testName); 32 | 33 | case 2 34 | strname = './GNC/GNC'; 35 | 36 | testName = fullfile([strname, int2str(level)],[filename.name(1:end-4),'.bmp']); 37 | 38 | distorted_img = gnc(img,gnc_level(level)); 39 | if ~exist([strname, int2str(level)], 'dir') 40 | mkdir([strname, int2str(level)]); 41 | end 42 | imwrite(distorted_img,testName); 43 | 44 | case 5 45 | strname = './HFN/HFN'; 46 | 47 | testName = fullfile([strname, int2str(level)],[filename.name(1:end-4),'.bmp']); 48 | 49 | distorted_img = HighFN(img,(hfn_level(level))); 50 | if ~exist([strname, int2str(level)], 'dir') 51 | mkdir([strname, int2str(level)]); 52 | end 53 | imwrite(distorted_img,testName); 54 | 55 | case 6 56 | strname = './IN/IN'; 57 | 58 | testName = fullfile([strname, int2str(level)],[filename.name(1:end-4),'.bmp']); 59 | 60 | distorted_img =imnoise(img,'salt & pepper',(in_level(level))); 61 | if ~exist([strname, int2str(level)], 'dir') 62 | mkdir([strname, int2str(level)]); 63 | end 64 | imwrite(distorted_img,testName); 65 | 66 | case 7 67 | strname = './QN/QN'; 68 | 69 | testName = fullfile([strname, int2str(level)],[filename.name(1:end-4),'.bmp']); 70 | 71 | distorted_img = QuantizationNoise(img,qn_level(level)); 72 | if ~exist([strname, int2str(level)], 'dir') 73 | mkdir([strname, int2str(level)]); 74 | end 75 | imwrite(distorted_img,testName); 76 | 77 | case 8 78 | strname = './GB/GB'; 79 | testName = fullfile([strname, int2str(level)],[filename.name(1:end-4),'.bmp']); 80 | hsize = gblur_level(level); 81 | h = fspecial('gaussian', hsize, hsize/6); 82 | distorted_img = imfilter(img,h,'symmetric'); 83 | if ~exist([strname, int2str(level)], 'dir') 84 | mkdir([strname, int2str(level)]); 85 | end 86 | imwrite(distorted_img,testName); 87 | 88 | case 9 89 | strname = './ID/ID'; 90 | 91 | testName = fullfile([strname, int2str(level)],[filename.name(1:end-4),'.bmp']); 92 | 93 | distorted_img = ImageDenoising(img,id_level(level)); 94 | if ~exist([strname, int2str(level)], 'dir') 95 | mkdir([strname, int2str(level)]); 96 | end 97 | imwrite(distorted_img,testName); 98 | 99 | case 10 100 | strname = './JPEG/JPEG'; 101 | testName = fullfile([strname, int2str(level)],[filename.name(1:end-4),'.jpg']); 102 | if ~exist([strname, int2str(level)], 'dir') 103 | mkdir([strname, int2str(level)]); 104 | end 105 | imwrite(img,testName,'jpg','quality',jpeg_level(level)); 106 | case 11 107 | strname = './JP2K/JP2K'; 108 | testName = fullfile([strname, int2str(level)],[filename.name(1:end-4),'.jp2']); 109 | if ~exist([strname, int2str(level)], 'dir') 110 | mkdir([strname, int2str(level)]); 111 | end 112 | imwrite(img,testName,'jp2','CompressionRatio', 24 / jp2k_level(level)); 113 | 114 | case 14 115 | strname = './NEPN/NEPN'; 116 | 117 | testName = fullfile([strname, int2str(level)],[filename.name(1:end-4),'.bmp']); 118 | 119 | distorted_img = nepn(img,nepn_level(level)); 120 | if ~exist([strname, int2str(level)], 'dir') 121 | mkdir([strname, int2str(level)]); 122 | end 123 | imwrite(distorted_img,testName); 124 | 125 | case 15 126 | strname = './BW/BW'; 127 | 128 | testName = fullfile([strname, int2str(level)],[filename.name(1:end-4),'.bmp']); 129 | 130 | distorted_img = BlockWise(img,bw_level(level),level); 131 | if ~exist([strname, int2str(level)], 'dir') 132 | mkdir([strname, int2str(level)]); 133 | end 134 | imwrite(distorted_img,testName); 135 | 136 | case 16 137 | strname = './MSH/MSH'; 138 | 139 | testName = fullfile([strname, int2str(level)],[filename.name(1:end-4),'.bmp']); 140 | 141 | distorted_img = MeanShift(img,ms_level(level)); 142 | if ~exist([strname, int2str(level)], 'dir') 143 | mkdir([strname, int2str(level)]); 144 | end 145 | imwrite(distorted_img,testName); 146 | case 17 147 | strname = './CCL/CCL'; 148 | 149 | testName = fullfile([strname, int2str(level)],[filename.name(1:end-4),'.bmp']); 150 | 151 | distorted_img = ContrastChange(img,cc_level(level)); 152 | if ~exist([strname, int2str(level)], 'dir') 153 | mkdir([strname, int2str(level)]); 154 | end 155 | imwrite(distorted_img,testName); 156 | case 18 157 | strname = './CS/CS'; 158 | 159 | testName = fullfile([strname, int2str(level)],[filename.name(1:end-4),'.bmp']); 160 | 161 | distorted_img = ColorSaturation(img,cs_level(level)); 162 | if ~exist([strname, int2str(level)], 'dir') 163 | mkdir([strname, int2str(level)]); 164 | end 165 | imwrite(distorted_img,testName); 166 | case 19 167 | strname = './MGN/MGN'; 168 | 169 | testName = fullfile([strname, int2str(level)],[filename.name(1:end-4),'.bmp']); 170 | 171 | distorted_img = MultiGN(img,mgn_level(level)); 172 | if ~exist([strname, int2str(level)], 'dir') 173 | mkdir([strname, int2str(level)]); 174 | end 175 | imwrite(distorted_img,testName); 176 | case 22 177 | strname = './CQD/CQD'; 178 | 179 | testName = fullfile([strname, int2str(level)],[filename.name(1:end-4),'.bmp']); 180 | 181 | [temp,map]=rgb2ind(img,cqd_level(level)); 182 | distorted_img = uint8(ind2rgb(temp,map)*255); 183 | 184 | if ~exist([strname, int2str(level)], 'dir') 185 | mkdir([strname, int2str(level)]); 186 | end 187 | imwrite(distorted_img,testName); 188 | 189 | case 23 190 | strname = './CA/CA'; 191 | 192 | testName = fullfile([strname, int2str(level)],[filename.name(1:end-4),'.bmp']); 193 | 194 | distorted_img = CA(img,ca_level(level)); 195 | 196 | if ~exist([strname, int2str(level)], 'dir') 197 | mkdir([strname, int2str(level)]); 198 | end 199 | imwrite(distorted_img,testName); 200 | 201 | 202 | end 203 | end 204 | 205 | -------------------------------------------------------------------------------- /data/rank_tid2013/tid2013_main.m: -------------------------------------------------------------------------------- 1 | % Generate multiple distortions 2 | addpath('BM3D') 3 | file = dir('./pristine_images/*.bmp'); 4 | distortions = [1,2,5,6,7,8,9,10,11,14,15,16,17,18,19,22,23]; 5 | levels = 1:4; 6 | for i = 1:length(file) 7 | 8 | refI = open_bitfield_bmp(fullfile('.', 'pristine_images', file(i).name)); 9 | for type = distortions % you could decide which types of distortion you want to generate 10 | for level = levels % You could decide how many levels of distortion 11 | tid2013_generator(refI, type, level,file(i)); 12 | end 13 | end 14 | fprintf('Finished image %d*16 / %d*16...\n', i,length(file)); 15 | 16 | end 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /data/ref.txt: -------------------------------------------------------------------------------- 1 | manfishing.bmp 2 | building2.bmp 3 | flowersonih35.bmp 4 | lighthouse.bmp 5 | parrots.bmp 6 | sailing1.bmp 7 | dancers.bmp 8 | plane.bmp 9 | sailing2.bmp 10 | churchandcapitol.bmp 11 | sailing3.bmp 12 | woman.bmp 13 | statue.bmp 14 | carnivaldolls.bmp 15 | stream.bmp 16 | cemetry.bmp 17 | lighthouse2.bmp 18 | studentsculpture.bmp 19 | monarch.bmp 20 | womanhat.bmp 21 | bikes.bmp 22 | paintedhouse.bmp 23 | ocean.bmp 24 | coinsinfountain.bmp 25 | sailing4.bmp 26 | house.bmp 27 | caps.bmp 28 | rapids.bmp 29 | buildings.bmp 30 | -------------------------------------------------------------------------------- /data/rename_image_names.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | import os 4 | import os.path as osp 5 | import cv2 6 | import pdb 7 | 8 | shape = ['gblur','wn','jpeg','jp2k','fastfading'] 9 | data = './live/' 10 | 11 | for tp in shape: 12 | 13 | file_root = data + tp + '/' 14 | list_file = 'info' + '.txt' 15 | filename = [line.rstrip('\n') for line in open( 16 | osp.join(file_root, list_file))] 17 | N_name = [] 18 | for i in filename: 19 | N_name.append(i.split()[1]) 20 | 21 | pdb.set_trace() 22 | 23 | for j in range(len(N_name)): 24 | folder = data +tp + '/' + N_name[j] 25 | 26 | tmp = cv2.imread(folder) 27 | cv2.imwrite(data+ tp + '/' + 'img' + str(int(N_name[j][3:-4])).zfill(3)+'.bmp',tmp) 28 | 29 | 30 | if int(N_name[j][3:-4])<100: 31 | os.remove(folder) 32 | os.remove(data+tp+'/'+'Thumbs.db') 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /data/tid2013/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## The folder of tid2013 dataset 3 | 4 | 5 | -------------------------------------------------------------------------------- /figs/models.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/figs/models.png -------------------------------------------------------------------------------- /models/README.md: -------------------------------------------------------------------------------- 1 | ## The folder to save the trained models 2 | The pre-trained [VGG-16](https://gist.github.com/ksimonyan/211839e770f7b538e2d8#file-readme-md) ImageNet model should be put here to do finetuning. 3 | -------------------------------------------------------------------------------- /pdf/Xialei_IQA_ICCV.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/pdf/Xialei_IQA_ICCV.pdf -------------------------------------------------------------------------------- /pdf/poster_ICCV_2017.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xialeiliu/RankIQA/22ca65cd0156b5b428cecd55ed939366fb64d2e5/pdf/poster_ICCV_2017.pdf -------------------------------------------------------------------------------- /pre-trained/README.md: -------------------------------------------------------------------------------- 1 | ## The folder to put the pre-trained models for evaluation 2 | 3 | 1. [Rank_live.caffemodel](https://pan.baidu.com/s/1jIabZKU) is trained from Ranking dataset generated from 4 distortions (JPEG, JP2K, GB, GN), which can be a good initialization of your IQA algorithm. 4 | 2. [FT_live.caffemodel](https://pan.baidu.com/s/1jIabZKU) is fine-tuned from one split of LIVE dataset. 5 | 3. [Rank_tid2013.caffemodel](https://pan.baidu.com/s/1jIabZKU) is trained from Ranking dataset generated from 17 distortions, which can be a good initialization of your IQA algorithm. 6 | 4. [FT_tid2013.caffemodel](https://pan.baidu.com/s/1jIabZKU) is fine-tuned from one split of TID2013 dataset. 7 | 8 | Apart from the above links, the models are also available on [Google Drive](https://drive.google.com/drive/folders/1S55n7tHBfJop3Z-nDjHXvEc34HmHowZt?usp=sharing). 9 | -------------------------------------------------------------------------------- /results/README.md: -------------------------------------------------------------------------------- 1 | ## The folder to put the evaluation results -------------------------------------------------------------------------------- /src/FT/live/deploy_vgg.prototxt: -------------------------------------------------------------------------------- 1 | name: "mnist_siamese_train_test" 2 | input: "data" 3 | input_shape { 4 | dim: 1 5 | dim: 3 6 | dim: 224 7 | dim: 224 8 | } 9 | 10 | layer { 11 | bottom: "data" 12 | top: "conv1_1" 13 | name: "conv1_1" 14 | type: "Convolution" 15 | param { 16 | lr_mult: 1 17 | decay_mult: 1 18 | } 19 | param { 20 | lr_mult: 2 21 | decay_mult: 0 22 | } 23 | convolution_param { 24 | num_output: 64 25 | pad: 1 26 | kernel_size: 3 27 | weight_filler { 28 | type: "xavier" 29 | } 30 | bias_filler { 31 | type: "constant" 32 | } 33 | } 34 | } 35 | layer { 36 | bottom: "conv1_1" 37 | top: "conv1_1" 38 | name: "relu1_1" 39 | type: "ReLU" 40 | } 41 | layer { 42 | bottom: "conv1_1" 43 | top: "conv1_2" 44 | name: "conv1_2" 45 | type: "Convolution" 46 | param { 47 | lr_mult: 1 48 | decay_mult: 1 49 | } 50 | param { 51 | lr_mult: 2 52 | decay_mult: 0 53 | } 54 | convolution_param { 55 | num_output: 64 56 | pad: 1 57 | kernel_size: 3 58 | weight_filler { 59 | type: "xavier" 60 | } 61 | bias_filler { 62 | type: "constant" 63 | } 64 | } 65 | } 66 | layer { 67 | bottom: "conv1_2" 68 | top: "conv1_2" 69 | name: "relu1_2" 70 | type: "ReLU" 71 | } 72 | layer { 73 | bottom: "conv1_2" 74 | top: "pool1" 75 | name: "pool1" 76 | type: "Pooling" 77 | pooling_param { 78 | pool: MAX 79 | kernel_size: 2 80 | stride: 2 81 | } 82 | } 83 | layer { 84 | bottom: "pool1" 85 | top: "conv2_1" 86 | name: "conv2_1" 87 | type: "Convolution" 88 | param { 89 | lr_mult: 1 90 | decay_mult: 1 91 | } 92 | param { 93 | lr_mult: 2 94 | decay_mult: 0 95 | } 96 | convolution_param { 97 | num_output: 128 98 | pad: 1 99 | kernel_size: 3 100 | weight_filler { 101 | type: "xavier" 102 | } 103 | bias_filler { 104 | type: "constant" 105 | } 106 | } 107 | } 108 | layer { 109 | bottom: "conv2_1" 110 | top: "conv2_1" 111 | name: "relu2_1" 112 | type: "ReLU" 113 | } 114 | layer { 115 | bottom: "conv2_1" 116 | top: "conv2_2" 117 | name: "conv2_2" 118 | type: "Convolution" 119 | param { 120 | lr_mult: 1 121 | decay_mult: 1 122 | } 123 | param { 124 | lr_mult: 2 125 | decay_mult: 0 126 | } 127 | convolution_param { 128 | num_output: 128 129 | pad: 1 130 | kernel_size: 3 131 | weight_filler { 132 | type: "xavier" 133 | } 134 | bias_filler { 135 | type: "constant" 136 | } 137 | } 138 | } 139 | layer { 140 | bottom: "conv2_2" 141 | top: "conv2_2" 142 | name: "relu2_2" 143 | type: "ReLU" 144 | } 145 | layer { 146 | bottom: "conv2_2" 147 | top: "pool2" 148 | name: "pool2" 149 | type: "Pooling" 150 | pooling_param { 151 | pool: MAX 152 | kernel_size: 2 153 | stride: 2 154 | } 155 | } 156 | layer { 157 | bottom: "pool2" 158 | top: "conv3_1" 159 | name: "conv3_1" 160 | type: "Convolution" 161 | param { 162 | lr_mult: 1 163 | decay_mult: 1 164 | } 165 | param { 166 | lr_mult: 2 167 | decay_mult: 0 168 | } 169 | convolution_param { 170 | num_output: 256 171 | pad: 1 172 | kernel_size: 3 173 | weight_filler { 174 | type: "xavier" 175 | } 176 | bias_filler { 177 | type: "constant" 178 | } 179 | } 180 | } 181 | layer { 182 | bottom: "conv3_1" 183 | top: "conv3_1" 184 | name: "relu3_1" 185 | type: "ReLU" 186 | } 187 | layer { 188 | bottom: "conv3_1" 189 | top: "conv3_2" 190 | name: "conv3_2" 191 | type: "Convolution" 192 | param { 193 | lr_mult: 1 194 | decay_mult: 1 195 | } 196 | param { 197 | lr_mult: 2 198 | decay_mult: 0 199 | } 200 | convolution_param { 201 | num_output: 256 202 | pad: 1 203 | kernel_size: 3 204 | weight_filler { 205 | type: "xavier" 206 | } 207 | bias_filler { 208 | type: "constant" 209 | } 210 | } 211 | } 212 | layer { 213 | bottom: "conv3_2" 214 | top: "conv3_2" 215 | name: "relu3_2" 216 | type: "ReLU" 217 | } 218 | layer { 219 | bottom: "conv3_2" 220 | top: "conv3_3" 221 | name: "conv3_3" 222 | type: "Convolution" 223 | param { 224 | lr_mult: 1 225 | decay_mult: 1 226 | } 227 | param { 228 | lr_mult: 2 229 | decay_mult: 0 230 | } 231 | convolution_param { 232 | num_output: 256 233 | pad: 1 234 | kernel_size: 3 235 | weight_filler { 236 | type: "xavier" 237 | } 238 | bias_filler { 239 | type: "constant" 240 | } 241 | } 242 | } 243 | layer { 244 | bottom: "conv3_3" 245 | top: "conv3_3" 246 | name: "relu3_3" 247 | type: "ReLU" 248 | } 249 | layer { 250 | bottom: "conv3_3" 251 | top: "pool3" 252 | name: "pool3" 253 | type: "Pooling" 254 | pooling_param { 255 | pool: MAX 256 | kernel_size: 2 257 | stride: 2 258 | } 259 | } 260 | layer { 261 | bottom: "pool3" 262 | top: "conv4_1" 263 | name: "conv4_1" 264 | type: "Convolution" 265 | param { 266 | lr_mult: 1 267 | decay_mult: 1 268 | } 269 | param { 270 | lr_mult: 2 271 | decay_mult: 0 272 | } 273 | convolution_param { 274 | num_output: 512 275 | pad: 1 276 | kernel_size: 3 277 | weight_filler { 278 | type: "xavier" 279 | } 280 | bias_filler { 281 | type: "constant" 282 | } 283 | } 284 | } 285 | layer { 286 | bottom: "conv4_1" 287 | top: "conv4_1" 288 | name: "relu4_1" 289 | type: "ReLU" 290 | } 291 | layer { 292 | bottom: "conv4_1" 293 | top: "conv4_2" 294 | name: "conv4_2" 295 | type: "Convolution" 296 | param { 297 | lr_mult: 1 298 | decay_mult: 1 299 | } 300 | param { 301 | lr_mult: 2 302 | decay_mult: 0 303 | } 304 | convolution_param { 305 | num_output: 512 306 | pad: 1 307 | kernel_size: 3 308 | weight_filler { 309 | type: "xavier" 310 | } 311 | bias_filler { 312 | type: "constant" 313 | } 314 | } 315 | } 316 | layer { 317 | bottom: "conv4_2" 318 | top: "conv4_2" 319 | name: "relu4_2" 320 | type: "ReLU" 321 | } 322 | layer { 323 | bottom: "conv4_2" 324 | top: "conv4_3" 325 | name: "conv4_3" 326 | type: "Convolution" 327 | param { 328 | lr_mult: 1 329 | decay_mult: 1 330 | } 331 | param { 332 | lr_mult: 2 333 | decay_mult: 0 334 | } 335 | convolution_param { 336 | num_output: 512 337 | pad: 1 338 | kernel_size: 3 339 | weight_filler { 340 | type: "xavier" 341 | } 342 | bias_filler { 343 | type: "constant" 344 | } 345 | } 346 | } 347 | layer { 348 | bottom: "conv4_3" 349 | top: "conv4_3" 350 | name: "relu4_3" 351 | type: "ReLU" 352 | } 353 | layer { 354 | bottom: "conv4_3" 355 | top: "pool4" 356 | name: "pool4" 357 | type: "Pooling" 358 | pooling_param { 359 | pool: MAX 360 | kernel_size: 2 361 | stride: 2 362 | } 363 | } 364 | layer { 365 | bottom: "pool4" 366 | top: "conv5_1" 367 | name: "conv5_1" 368 | type: "Convolution" 369 | param { 370 | lr_mult: 1 371 | decay_mult: 1 372 | } 373 | param { 374 | lr_mult: 2 375 | decay_mult: 0 376 | } 377 | convolution_param { 378 | num_output: 512 379 | pad: 1 380 | kernel_size: 3 381 | weight_filler { 382 | type: "xavier" 383 | } 384 | bias_filler { 385 | type: "constant" 386 | } 387 | } 388 | } 389 | layer { 390 | bottom: "conv5_1" 391 | top: "conv5_1" 392 | name: "relu5_1" 393 | type: "ReLU" 394 | } 395 | layer { 396 | bottom: "conv5_1" 397 | top: "conv5_2" 398 | name: "conv5_2" 399 | type: "Convolution" 400 | param { 401 | lr_mult: 1 402 | decay_mult: 1 403 | } 404 | param { 405 | lr_mult: 2 406 | decay_mult: 0 407 | } 408 | convolution_param { 409 | num_output: 512 410 | pad: 1 411 | kernel_size: 3 412 | weight_filler { 413 | type: "xavier" 414 | } 415 | bias_filler { 416 | type: "constant" 417 | } 418 | } 419 | } 420 | layer { 421 | bottom: "conv5_2" 422 | top: "conv5_2" 423 | name: "relu5_2" 424 | type: "ReLU" 425 | } 426 | layer { 427 | bottom: "conv5_2" 428 | top: "conv5_3" 429 | name: "conv5_3" 430 | type: "Convolution" 431 | param { 432 | lr_mult: 1 433 | decay_mult: 1 434 | } 435 | param { 436 | lr_mult: 2 437 | decay_mult: 0 438 | } 439 | convolution_param { 440 | num_output: 512 441 | pad: 1 442 | kernel_size: 3 443 | weight_filler { 444 | type: "xavier" 445 | } 446 | bias_filler { 447 | type: "constant" 448 | } 449 | } 450 | } 451 | layer { 452 | bottom: "conv5_3" 453 | top: "conv5_3" 454 | name: "relu5_3" 455 | type: "ReLU" 456 | } 457 | layer { 458 | bottom: "conv5_3" 459 | top: "pool5" 460 | name: "pool5" 461 | type: "Pooling" 462 | pooling_param { 463 | pool: MAX 464 | kernel_size: 2 465 | stride: 2 466 | } 467 | } 468 | layer { 469 | bottom: "pool5" 470 | top: "fc6" 471 | name: "fc6" 472 | type: "InnerProduct" 473 | param { 474 | lr_mult: 10 475 | decay_mult: 1 476 | } 477 | param { 478 | lr_mult: 20 479 | decay_mult: 0 480 | } 481 | inner_product_param { 482 | num_output: 4096 483 | weight_filler { 484 | type: "xavier" 485 | } 486 | bias_filler { 487 | type: "constant" 488 | } 489 | } 490 | } 491 | layer { 492 | bottom: "fc6" 493 | top: "fc6" 494 | name: "relu6" 495 | type: "ReLU" 496 | } 497 | layer { 498 | bottom: "fc6" 499 | top: "fc6" 500 | name: "drop6" 501 | type: "Dropout" 502 | dropout_param { 503 | dropout_ratio: 0.5 504 | } 505 | } 506 | layer { 507 | bottom: "fc6" 508 | top: "fc7" 509 | name: "fc7" 510 | type: "InnerProduct" 511 | param { 512 | lr_mult: 10 513 | decay_mult: 1 514 | } 515 | param { 516 | lr_mult: 20 517 | decay_mult: 0 518 | } 519 | inner_product_param { 520 | num_output: 4096 521 | weight_filler { 522 | type: "xavier" 523 | } 524 | bias_filler { 525 | type: "constant" 526 | } 527 | } 528 | } 529 | layer { 530 | bottom: "fc7" 531 | top: "fc7" 532 | name: "relu7" 533 | type: "ReLU" 534 | } 535 | layer { 536 | bottom: "fc7" 537 | top: "fc7" 538 | name: "drop7" 539 | type: "Dropout" 540 | dropout_param { 541 | dropout_ratio: 0.5 542 | } 543 | } 544 | layer { 545 | bottom: "fc7" 546 | top: "fc8" 547 | name: "fc8" 548 | type: "InnerProduct" 549 | param { 550 | lr_mult: 10 551 | decay_mult: 1 552 | } 553 | param { 554 | lr_mult: 20 555 | decay_mult: 0 556 | } 557 | inner_product_param { 558 | num_output: 1 559 | weight_filler { 560 | type: "xavier" 561 | } 562 | bias_filler { 563 | type: "constant" 564 | } 565 | } 566 | } 567 | -------------------------------------------------------------------------------- /src/FT/live/solver_live.prototxt: -------------------------------------------------------------------------------- 1 | # The train/test net protocol buffer definition 2 | net: "src/FT/live/train_live.prototxt" 3 | 4 | test_iter: 20 5 | 6 | test_interval: 1000 7 | base_lr: 0.000001 8 | lr_policy: "step" 9 | gamma: 0.5 10 | stepsize: 5000 11 | display: 100 12 | max_iter: 20000 13 | momentum: 0.9 14 | solver_type: SGD 15 | weight_decay: 0.0005 16 | average_loss: 500 17 | snapshot: 10000 18 | snapshot_prefix: "models/ft_live/my_siamese" 19 | solver_mode: GPU 20 | -------------------------------------------------------------------------------- /src/FT/live/train_live.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | TOOLS=/home/xialei/caffe/distribute/bin #TODO Changing to your Caffe bin 4 | 5 | $TOOLS/caffe.bin train --gpu 0 --solver=src/FT/live/solver_live.prototxt --weights ./models/rank_live_20/my_siamese_iter_20000.caffemodel 2>&1 | tee models/ft_live/log_live 6 | -------------------------------------------------------------------------------- /src/FT/tid2013/deploy_vgg.prototxt: -------------------------------------------------------------------------------- 1 | name: "mnist_siamese_train_test" 2 | input: "data" 3 | input_shape { 4 | dim: 1 5 | dim: 3 6 | dim: 224 7 | dim: 224 8 | } 9 | 10 | layer { 11 | bottom: "data" 12 | top: "conv1_1" 13 | name: "conv1_1" 14 | type: "Convolution" 15 | param { 16 | lr_mult: 1 17 | decay_mult: 1 18 | } 19 | param { 20 | lr_mult: 2 21 | decay_mult: 0 22 | } 23 | convolution_param { 24 | num_output: 64 25 | pad: 1 26 | kernel_size: 3 27 | weight_filler { 28 | type: "xavier" 29 | } 30 | bias_filler { 31 | type: "constant" 32 | } 33 | } 34 | } 35 | layer { 36 | bottom: "conv1_1" 37 | top: "conv1_1" 38 | name: "relu1_1" 39 | type: "ReLU" 40 | } 41 | layer { 42 | bottom: "conv1_1" 43 | top: "conv1_2" 44 | name: "conv1_2" 45 | type: "Convolution" 46 | param { 47 | lr_mult: 1 48 | decay_mult: 1 49 | } 50 | param { 51 | lr_mult: 2 52 | decay_mult: 0 53 | } 54 | convolution_param { 55 | num_output: 64 56 | pad: 1 57 | kernel_size: 3 58 | weight_filler { 59 | type: "xavier" 60 | } 61 | bias_filler { 62 | type: "constant" 63 | } 64 | } 65 | } 66 | layer { 67 | bottom: "conv1_2" 68 | top: "conv1_2" 69 | name: "relu1_2" 70 | type: "ReLU" 71 | } 72 | layer { 73 | bottom: "conv1_2" 74 | top: "pool1" 75 | name: "pool1" 76 | type: "Pooling" 77 | pooling_param { 78 | pool: MAX 79 | kernel_size: 2 80 | stride: 2 81 | } 82 | } 83 | layer { 84 | bottom: "pool1" 85 | top: "conv2_1" 86 | name: "conv2_1" 87 | type: "Convolution" 88 | param { 89 | lr_mult: 1 90 | decay_mult: 1 91 | } 92 | param { 93 | lr_mult: 2 94 | decay_mult: 0 95 | } 96 | convolution_param { 97 | num_output: 128 98 | pad: 1 99 | kernel_size: 3 100 | weight_filler { 101 | type: "xavier" 102 | } 103 | bias_filler { 104 | type: "constant" 105 | } 106 | } 107 | } 108 | layer { 109 | bottom: "conv2_1" 110 | top: "conv2_1" 111 | name: "relu2_1" 112 | type: "ReLU" 113 | } 114 | layer { 115 | bottom: "conv2_1" 116 | top: "conv2_2" 117 | name: "conv2_2" 118 | type: "Convolution" 119 | param { 120 | lr_mult: 1 121 | decay_mult: 1 122 | } 123 | param { 124 | lr_mult: 2 125 | decay_mult: 0 126 | } 127 | convolution_param { 128 | num_output: 128 129 | pad: 1 130 | kernel_size: 3 131 | weight_filler { 132 | type: "xavier" 133 | } 134 | bias_filler { 135 | type: "constant" 136 | } 137 | } 138 | } 139 | layer { 140 | bottom: "conv2_2" 141 | top: "conv2_2" 142 | name: "relu2_2" 143 | type: "ReLU" 144 | } 145 | layer { 146 | bottom: "conv2_2" 147 | top: "pool2" 148 | name: "pool2" 149 | type: "Pooling" 150 | pooling_param { 151 | pool: MAX 152 | kernel_size: 2 153 | stride: 2 154 | } 155 | } 156 | layer { 157 | bottom: "pool2" 158 | top: "conv3_1" 159 | name: "conv3_1" 160 | type: "Convolution" 161 | param { 162 | lr_mult: 1 163 | decay_mult: 1 164 | } 165 | param { 166 | lr_mult: 2 167 | decay_mult: 0 168 | } 169 | convolution_param { 170 | num_output: 256 171 | pad: 1 172 | kernel_size: 3 173 | weight_filler { 174 | type: "xavier" 175 | } 176 | bias_filler { 177 | type: "constant" 178 | } 179 | } 180 | } 181 | layer { 182 | bottom: "conv3_1" 183 | top: "conv3_1" 184 | name: "relu3_1" 185 | type: "ReLU" 186 | } 187 | layer { 188 | bottom: "conv3_1" 189 | top: "conv3_2" 190 | name: "conv3_2" 191 | type: "Convolution" 192 | param { 193 | lr_mult: 1 194 | decay_mult: 1 195 | } 196 | param { 197 | lr_mult: 2 198 | decay_mult: 0 199 | } 200 | convolution_param { 201 | num_output: 256 202 | pad: 1 203 | kernel_size: 3 204 | weight_filler { 205 | type: "xavier" 206 | } 207 | bias_filler { 208 | type: "constant" 209 | } 210 | } 211 | } 212 | layer { 213 | bottom: "conv3_2" 214 | top: "conv3_2" 215 | name: "relu3_2" 216 | type: "ReLU" 217 | } 218 | layer { 219 | bottom: "conv3_2" 220 | top: "conv3_3" 221 | name: "conv3_3" 222 | type: "Convolution" 223 | param { 224 | lr_mult: 1 225 | decay_mult: 1 226 | } 227 | param { 228 | lr_mult: 2 229 | decay_mult: 0 230 | } 231 | convolution_param { 232 | num_output: 256 233 | pad: 1 234 | kernel_size: 3 235 | weight_filler { 236 | type: "xavier" 237 | } 238 | bias_filler { 239 | type: "constant" 240 | } 241 | } 242 | } 243 | layer { 244 | bottom: "conv3_3" 245 | top: "conv3_3" 246 | name: "relu3_3" 247 | type: "ReLU" 248 | } 249 | layer { 250 | bottom: "conv3_3" 251 | top: "pool3" 252 | name: "pool3" 253 | type: "Pooling" 254 | pooling_param { 255 | pool: MAX 256 | kernel_size: 2 257 | stride: 2 258 | } 259 | } 260 | layer { 261 | bottom: "pool3" 262 | top: "conv4_1" 263 | name: "conv4_1" 264 | type: "Convolution" 265 | param { 266 | lr_mult: 1 267 | decay_mult: 1 268 | } 269 | param { 270 | lr_mult: 2 271 | decay_mult: 0 272 | } 273 | convolution_param { 274 | num_output: 512 275 | pad: 1 276 | kernel_size: 3 277 | weight_filler { 278 | type: "xavier" 279 | } 280 | bias_filler { 281 | type: "constant" 282 | } 283 | } 284 | } 285 | layer { 286 | bottom: "conv4_1" 287 | top: "conv4_1" 288 | name: "relu4_1" 289 | type: "ReLU" 290 | } 291 | layer { 292 | bottom: "conv4_1" 293 | top: "conv4_2" 294 | name: "conv4_2" 295 | type: "Convolution" 296 | param { 297 | lr_mult: 1 298 | decay_mult: 1 299 | } 300 | param { 301 | lr_mult: 2 302 | decay_mult: 0 303 | } 304 | convolution_param { 305 | num_output: 512 306 | pad: 1 307 | kernel_size: 3 308 | weight_filler { 309 | type: "xavier" 310 | } 311 | bias_filler { 312 | type: "constant" 313 | } 314 | } 315 | } 316 | layer { 317 | bottom: "conv4_2" 318 | top: "conv4_2" 319 | name: "relu4_2" 320 | type: "ReLU" 321 | } 322 | layer { 323 | bottom: "conv4_2" 324 | top: "conv4_3" 325 | name: "conv4_3" 326 | type: "Convolution" 327 | param { 328 | lr_mult: 1 329 | decay_mult: 1 330 | } 331 | param { 332 | lr_mult: 2 333 | decay_mult: 0 334 | } 335 | convolution_param { 336 | num_output: 512 337 | pad: 1 338 | kernel_size: 3 339 | weight_filler { 340 | type: "xavier" 341 | } 342 | bias_filler { 343 | type: "constant" 344 | } 345 | } 346 | } 347 | layer { 348 | bottom: "conv4_3" 349 | top: "conv4_3" 350 | name: "relu4_3" 351 | type: "ReLU" 352 | } 353 | layer { 354 | bottom: "conv4_3" 355 | top: "pool4" 356 | name: "pool4" 357 | type: "Pooling" 358 | pooling_param { 359 | pool: MAX 360 | kernel_size: 2 361 | stride: 2 362 | } 363 | } 364 | layer { 365 | bottom: "pool4" 366 | top: "conv5_1" 367 | name: "conv5_1" 368 | type: "Convolution" 369 | param { 370 | lr_mult: 1 371 | decay_mult: 1 372 | } 373 | param { 374 | lr_mult: 2 375 | decay_mult: 0 376 | } 377 | convolution_param { 378 | num_output: 512 379 | pad: 1 380 | kernel_size: 3 381 | weight_filler { 382 | type: "xavier" 383 | } 384 | bias_filler { 385 | type: "constant" 386 | } 387 | } 388 | } 389 | layer { 390 | bottom: "conv5_1" 391 | top: "conv5_1" 392 | name: "relu5_1" 393 | type: "ReLU" 394 | } 395 | layer { 396 | bottom: "conv5_1" 397 | top: "conv5_2" 398 | name: "conv5_2" 399 | type: "Convolution" 400 | param { 401 | lr_mult: 1 402 | decay_mult: 1 403 | } 404 | param { 405 | lr_mult: 2 406 | decay_mult: 0 407 | } 408 | convolution_param { 409 | num_output: 512 410 | pad: 1 411 | kernel_size: 3 412 | weight_filler { 413 | type: "xavier" 414 | } 415 | bias_filler { 416 | type: "constant" 417 | } 418 | } 419 | } 420 | layer { 421 | bottom: "conv5_2" 422 | top: "conv5_2" 423 | name: "relu5_2" 424 | type: "ReLU" 425 | } 426 | layer { 427 | bottom: "conv5_2" 428 | top: "conv5_3" 429 | name: "conv5_3" 430 | type: "Convolution" 431 | param { 432 | lr_mult: 1 433 | decay_mult: 1 434 | } 435 | param { 436 | lr_mult: 2 437 | decay_mult: 0 438 | } 439 | convolution_param { 440 | num_output: 512 441 | pad: 1 442 | kernel_size: 3 443 | weight_filler { 444 | type: "xavier" 445 | } 446 | bias_filler { 447 | type: "constant" 448 | } 449 | } 450 | } 451 | layer { 452 | bottom: "conv5_3" 453 | top: "conv5_3" 454 | name: "relu5_3" 455 | type: "ReLU" 456 | } 457 | layer { 458 | bottom: "conv5_3" 459 | top: "pool5" 460 | name: "pool5" 461 | type: "Pooling" 462 | pooling_param { 463 | pool: MAX 464 | kernel_size: 2 465 | stride: 2 466 | } 467 | } 468 | layer { 469 | bottom: "pool5" 470 | top: "fc6_m" 471 | name: "fc6_m" 472 | type: "InnerProduct" 473 | param { 474 | lr_mult: 10 475 | decay_mult: 1 476 | } 477 | param { 478 | lr_mult: 20 479 | decay_mult: 0 480 | } 481 | inner_product_param { 482 | num_output: 4096 483 | weight_filler { 484 | type: "xavier" 485 | } 486 | bias_filler { 487 | type: "constant" 488 | } 489 | } 490 | } 491 | layer { 492 | bottom: "fc6_m" 493 | top: "fc6_m" 494 | name: "relu6" 495 | type: "ReLU" 496 | } 497 | layer { 498 | bottom: "fc6_m" 499 | top: "fc6_m" 500 | name: "drop6" 501 | type: "Dropout" 502 | dropout_param { 503 | dropout_ratio: 0.5 504 | } 505 | } 506 | layer { 507 | bottom: "fc6_m" 508 | top: "fc7_m" 509 | name: "fc7_m" 510 | type: "InnerProduct" 511 | param { 512 | lr_mult: 10 513 | decay_mult: 1 514 | } 515 | param { 516 | lr_mult: 20 517 | decay_mult: 0 518 | } 519 | inner_product_param { 520 | num_output: 4096 521 | weight_filler { 522 | type: "xavier" 523 | } 524 | bias_filler { 525 | type: "constant" 526 | } 527 | } 528 | } 529 | layer { 530 | bottom: "fc7_m" 531 | top: "fc7_m" 532 | name: "relu7" 533 | type: "ReLU" 534 | } 535 | layer { 536 | bottom: "fc7_m" 537 | top: "fc7_m" 538 | name: "drop7" 539 | type: "Dropout" 540 | dropout_param { 541 | dropout_ratio: 0.5 542 | } 543 | } 544 | layer { 545 | bottom: "fc7_m" 546 | top: "fc8" 547 | name: "fc8" 548 | type: "InnerProduct" 549 | param { 550 | lr_mult: 10 551 | decay_mult: 1 552 | } 553 | param { 554 | lr_mult: 20 555 | decay_mult: 0 556 | } 557 | inner_product_param { 558 | num_output: 1 559 | weight_filler { 560 | type: "xavier" 561 | } 562 | bias_filler { 563 | type: "constant" 564 | } 565 | } 566 | } 567 | -------------------------------------------------------------------------------- /src/FT/tid2013/solver_vgg.prototxt: -------------------------------------------------------------------------------- 1 | # The train/test net protocol buffer definition 2 | net: "src/FT/tid2013/train_vgg.prototxt" 3 | 4 | test_iter: 20 5 | 6 | test_interval: 1000 7 | base_lr: 0.00001 8 | lr_policy: "step" 9 | gamma: 0.5 10 | stepsize: 5000 11 | display: 100 12 | max_iter: 10000 13 | momentum: 0.9 14 | solver_type: SGD 15 | weight_decay: 0.0005 16 | average_loss: 500 17 | snapshot: 10000 18 | snapshot_prefix: "models/ft_rank_tid2013/my_siamese" 19 | solver_mode: GPU 20 | -------------------------------------------------------------------------------- /src/FT/tid2013/train_vgg.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | TOOLS=/home/xialei/caffe/distribute/bin #TODO Changing to your Caffe bin 4 | 5 | $TOOLS/caffe.bin train --gpu 4 --solver=src/FT/tid2013/solver_vgg.prototxt --weights ./models/rank_tid2013/my_siamese_iter_50000.caffemodel 2>&1 | tee models/ft_rank_tid2013/log_tid2013 6 | -------------------------------------------------------------------------------- /src/MyLossLayer/__init__.py: -------------------------------------------------------------------------------- 1 | # Placeholder so this diectory acts like a python module. 2 | -------------------------------------------------------------------------------- /src/MyLossLayer/netloss_live.py: -------------------------------------------------------------------------------- 1 | import caffe 2 | import numpy as np 3 | import pdb 4 | 5 | class MyLossLayer(caffe.Layer): 6 | """Layer of Efficient Siamese loss function.""" 7 | 8 | def setup(self, bottom, top): 9 | self.margin = 10 10 | print '*********************** SETTING UP' 11 | pass 12 | 13 | def forward(self, bottom, top): 14 | """The forward """ 15 | self.Num = 0 16 | batch = 2 17 | level = 6 18 | dis = 4 19 | SepSize = batch*level 20 | self.dis = [] 21 | # for the first 22 | for k in range(dis): 23 | for i in range(SepSize*k,SepSize*(k+1)-batch): 24 | for j in range(SepSize*k + int((i-SepSize*k)/batch+1)*batch,SepSize*(k+1)): 25 | self.dis.append(bottom[0].data[i]-bottom[0].data[j]) 26 | self.Num +=1 27 | 28 | self.dis = np.asarray(self.dis) 29 | self.loss = np.maximum(0,self.margin-self.dis) # Efficient Siamese forward pass of hinge loss 30 | 31 | top[0].data[...] = np.sum(self.loss)/bottom[0].num 32 | 33 | 34 | def backward(self, top, propagate_down, bottom): 35 | """The parameters here have the same meaning as data_layer""" 36 | batch=2 37 | index = 0 38 | level = 6 39 | dis = 4 40 | SepSize = batch*level 41 | self.ref= np.zeros(bottom[0].num,dtype=np.float32) 42 | for k in range(dis): 43 | for i in range(SepSize*k,SepSize*(k+1)-batch): 44 | for j in range(SepSize*k + int((i-SepSize*k)/batch+1)*batch,SepSize*(k+1)): 45 | if self.loss[index]>0: 46 | self.ref[i] += -1 47 | self.ref[j] += +1 48 | index +=1 49 | 50 | # Efficient Siamese backward pass 51 | bottom[0].diff[...]= np.reshape(self.ref,(bottom[0].num,1))/bottom[0].num 52 | 53 | 54 | def reshape(self, bottom, top): 55 | """Reshaping happens during the call to forward.""" 56 | 57 | top[0].reshape(1) 58 | 59 | -------------------------------------------------------------------------------- /src/MyLossLayer/netloss_tid2013.py: -------------------------------------------------------------------------------- 1 | import caffe 2 | import numpy as np 3 | import pdb 4 | 5 | class MyLossLayer(caffe.Layer): 6 | """Layer of Efficient Siamese loss function.""" 7 | 8 | def setup(self, bottom, top): 9 | self.margin = 10 10 | print '*********************** SETTING UP' 11 | pass 12 | 13 | def forward(self, bottom, top): 14 | """The parameters here have the same meaning as data_layer""" 15 | self.Num = 0 16 | batch = 1 17 | level = 5 18 | dis = 9 19 | SepSize = batch*level 20 | self.dis = [] 21 | # for the first 22 | for k in range(dis): 23 | for i in range(SepSize*k,SepSize*(k+1)-batch): 24 | for j in range(SepSize*k + int((i-SepSize*k)/batch+1)*batch,SepSize*(k+1)): 25 | self.dis.append(bottom[0].data[i]-bottom[0].data[j]) 26 | self.Num +=1 27 | 28 | self.dis = np.asarray(self.dis) 29 | self.loss = np.maximum(0,self.margin-self.dis) # Efficient Siamese forward pass of hinge loss 30 | 31 | top[0].data[...] = np.sum(self.loss)/bottom[0].num 32 | 33 | 34 | def backward(self, top, propagate_down, bottom): 35 | """The parameters here have the same meaning as data_layer""" 36 | batch=1 37 | index = 0 38 | level = 5 39 | dis = 9 40 | SepSize = batch*level 41 | self.ref= np.zeros(bottom[0].num,dtype=np.float32) 42 | for k in range(dis): 43 | for i in range(SepSize*k,SepSize*(k+1)-batch): 44 | for j in range(SepSize*k + int((i-SepSize*k)/batch+1)*batch,SepSize*(k+1)): 45 | if self.loss[index]>0: 46 | self.ref[i] += -1 47 | self.ref[j] += +1 48 | index +=1 49 | 50 | # Efficient Siamese backward pass 51 | bottom[0].diff[...]= np.reshape(self.ref,(bottom[0].num,1))/bottom[0].num 52 | 53 | 54 | def reshape(self, bottom, top): 55 | """Reshaping happens during the call to forward.""" 56 | top[0].reshape(1) 57 | 58 | -------------------------------------------------------------------------------- /src/README.md: -------------------------------------------------------------------------------- 1 | # Training examples on TID2013 and LIVE datasets 2 | ``` 3 | git clone https://github.com/xialeiliu/RankIQA.git 4 | cd RankIQA 5 | ``` 6 | ## Requirements 7 | 1. Requirements for ```caffe ``` and ```pycaffe ``` (see: [Caffe installation instructions](http://caffe.berkeleyvision.org/installation.html)). 8 | Caffe must be built with support for Python layers! 9 | 10 | ``` 11 | # In your Makefile.config, make sure to have this line uncommented 12 | WITH_PYTHON_LAYER := 1 13 | ``` 14 | 2. Requirements for GPU (Titan X (~11G of memory) is needed to train VGG). 15 | 16 | ## Preparing Ranking and IQA datasets 17 | 18 | The details can be found in [data](../data) 19 | 20 | ## Pre-trained ImageNet VGG-16 model 21 | Download the pre-trained [VGG-16](https://gist.github.com/ksimonyan/211839e770f7b538e2d8#file-readme-md) ImageNet model and put it in the folder [models](../models). 22 | 23 | ## RankIQA 24 | 25 | To train the RankIQA models on tid2013 dataset: 26 | 27 | ``` 28 | ./src/RankIQA/tid2013/train_vgg.sh 29 | ``` 30 | 31 | To train the RankIQA models on LIVE dataset: 32 | 33 | ``` 34 | ./src/RankIQA/live/train_vgg.sh 35 | ``` 36 | 37 | ## FT 38 | 39 | To train the RankIQA+FT models on tid2013 dataset: 40 | 41 | ``` 42 | ./src/FT/tid2013/train_vgg.sh 43 | ``` 44 | To train the RankIQA+FT models on LIVE dataset: 45 | 46 | ``` 47 | ./src/FT/live/train_live.sh 48 | ``` 49 | ## Evaluation for RankIQA on tid2013: 50 | 51 | ``` 52 | python src/eval/Rank_eval_each_tid2013.py # evaluation for each distortions in tid2013 53 | python src/eval/Rank_eval_all_tid2013.py # evaluation for all distortions in tid2013 54 | ``` 55 | 56 | ## Evaluation for RankIQA+FT on tid2013: 57 | 58 | ``` 59 | python src/eval/FT_eval_each_tid2013.py # evaluation for each distortions in tid2013 60 | python src/eval/FT_eval_all_tid2013.py # evaluation for all distortions in tid2013 61 | ``` 62 | 63 | ## Evaluation for RankIQA on LIVE: 64 | 65 | ``` 66 | python src/eval/Rank_eval_all_live.py # evaluation for all distortions in LIVE 67 | ``` 68 | 69 | ## Evaluation for RankIQA+FT on LIVE: 70 | 71 | ``` 72 | python src/eval/FT_eval_all_live.py # evaluation for all distortions in LIVE 73 | ``` 74 | 75 | ## Folder introdcutions 76 | 77 | 1. [data_layer](./data_layer) includes the Python functions to read the input data for different datasets. 78 | 2. [MyLossLayer](./MyLossLayer) contains the Python functions of our efficient back-propagation method for different datasets. 79 | 3. [tools](./tools) provides the Python functions to calculate the evaluation matrix during training. 80 | 4. [eval](./eval) provides the Python functions to evaluate the trained models. 81 | 82 | -------------------------------------------------------------------------------- /src/RankIQA/live/deploy_vgg.prototxt: -------------------------------------------------------------------------------- 1 | name: "mnist_siamese_train_test" 2 | input: "data" 3 | input_shape { 4 | dim: 1 5 | dim: 3 6 | dim: 224 7 | dim: 224 8 | } 9 | 10 | layer { 11 | bottom: "data" 12 | top: "conv1_1" 13 | name: "conv1_1" 14 | type: "Convolution" 15 | param { 16 | lr_mult: 1 17 | decay_mult: 1 18 | } 19 | param { 20 | lr_mult: 2 21 | decay_mult: 0 22 | } 23 | convolution_param { 24 | num_output: 64 25 | pad: 1 26 | kernel_size: 3 27 | weight_filler { 28 | type: "xavier" 29 | } 30 | bias_filler { 31 | type: "constant" 32 | } 33 | } 34 | } 35 | layer { 36 | bottom: "conv1_1" 37 | top: "conv1_1" 38 | name: "relu1_1" 39 | type: "ReLU" 40 | } 41 | layer { 42 | bottom: "conv1_1" 43 | top: "conv1_2" 44 | name: "conv1_2" 45 | type: "Convolution" 46 | param { 47 | lr_mult: 1 48 | decay_mult: 1 49 | } 50 | param { 51 | lr_mult: 2 52 | decay_mult: 0 53 | } 54 | convolution_param { 55 | num_output: 64 56 | pad: 1 57 | kernel_size: 3 58 | weight_filler { 59 | type: "xavier" 60 | } 61 | bias_filler { 62 | type: "constant" 63 | } 64 | } 65 | } 66 | layer { 67 | bottom: "conv1_2" 68 | top: "conv1_2" 69 | name: "relu1_2" 70 | type: "ReLU" 71 | } 72 | layer { 73 | bottom: "conv1_2" 74 | top: "pool1" 75 | name: "pool1" 76 | type: "Pooling" 77 | pooling_param { 78 | pool: MAX 79 | kernel_size: 2 80 | stride: 2 81 | } 82 | } 83 | layer { 84 | bottom: "pool1" 85 | top: "conv2_1" 86 | name: "conv2_1" 87 | type: "Convolution" 88 | param { 89 | lr_mult: 1 90 | decay_mult: 1 91 | } 92 | param { 93 | lr_mult: 2 94 | decay_mult: 0 95 | } 96 | convolution_param { 97 | num_output: 128 98 | pad: 1 99 | kernel_size: 3 100 | weight_filler { 101 | type: "xavier" 102 | } 103 | bias_filler { 104 | type: "constant" 105 | } 106 | } 107 | } 108 | layer { 109 | bottom: "conv2_1" 110 | top: "conv2_1" 111 | name: "relu2_1" 112 | type: "ReLU" 113 | } 114 | layer { 115 | bottom: "conv2_1" 116 | top: "conv2_2" 117 | name: "conv2_2" 118 | type: "Convolution" 119 | param { 120 | lr_mult: 1 121 | decay_mult: 1 122 | } 123 | param { 124 | lr_mult: 2 125 | decay_mult: 0 126 | } 127 | convolution_param { 128 | num_output: 128 129 | pad: 1 130 | kernel_size: 3 131 | weight_filler { 132 | type: "xavier" 133 | } 134 | bias_filler { 135 | type: "constant" 136 | } 137 | } 138 | } 139 | layer { 140 | bottom: "conv2_2" 141 | top: "conv2_2" 142 | name: "relu2_2" 143 | type: "ReLU" 144 | } 145 | layer { 146 | bottom: "conv2_2" 147 | top: "pool2" 148 | name: "pool2" 149 | type: "Pooling" 150 | pooling_param { 151 | pool: MAX 152 | kernel_size: 2 153 | stride: 2 154 | } 155 | } 156 | layer { 157 | bottom: "pool2" 158 | top: "conv3_1" 159 | name: "conv3_1" 160 | type: "Convolution" 161 | param { 162 | lr_mult: 1 163 | decay_mult: 1 164 | } 165 | param { 166 | lr_mult: 2 167 | decay_mult: 0 168 | } 169 | convolution_param { 170 | num_output: 256 171 | pad: 1 172 | kernel_size: 3 173 | weight_filler { 174 | type: "xavier" 175 | } 176 | bias_filler { 177 | type: "constant" 178 | } 179 | } 180 | } 181 | layer { 182 | bottom: "conv3_1" 183 | top: "conv3_1" 184 | name: "relu3_1" 185 | type: "ReLU" 186 | } 187 | layer { 188 | bottom: "conv3_1" 189 | top: "conv3_2" 190 | name: "conv3_2" 191 | type: "Convolution" 192 | param { 193 | lr_mult: 1 194 | decay_mult: 1 195 | } 196 | param { 197 | lr_mult: 2 198 | decay_mult: 0 199 | } 200 | convolution_param { 201 | num_output: 256 202 | pad: 1 203 | kernel_size: 3 204 | weight_filler { 205 | type: "xavier" 206 | } 207 | bias_filler { 208 | type: "constant" 209 | } 210 | } 211 | } 212 | layer { 213 | bottom: "conv3_2" 214 | top: "conv3_2" 215 | name: "relu3_2" 216 | type: "ReLU" 217 | } 218 | layer { 219 | bottom: "conv3_2" 220 | top: "conv3_3" 221 | name: "conv3_3" 222 | type: "Convolution" 223 | param { 224 | lr_mult: 1 225 | decay_mult: 1 226 | } 227 | param { 228 | lr_mult: 2 229 | decay_mult: 0 230 | } 231 | convolution_param { 232 | num_output: 256 233 | pad: 1 234 | kernel_size: 3 235 | weight_filler { 236 | type: "xavier" 237 | } 238 | bias_filler { 239 | type: "constant" 240 | } 241 | } 242 | } 243 | layer { 244 | bottom: "conv3_3" 245 | top: "conv3_3" 246 | name: "relu3_3" 247 | type: "ReLU" 248 | } 249 | layer { 250 | bottom: "conv3_3" 251 | top: "pool3" 252 | name: "pool3" 253 | type: "Pooling" 254 | pooling_param { 255 | pool: MAX 256 | kernel_size: 2 257 | stride: 2 258 | } 259 | } 260 | layer { 261 | bottom: "pool3" 262 | top: "conv4_1" 263 | name: "conv4_1" 264 | type: "Convolution" 265 | param { 266 | lr_mult: 1 267 | decay_mult: 1 268 | } 269 | param { 270 | lr_mult: 2 271 | decay_mult: 0 272 | } 273 | convolution_param { 274 | num_output: 512 275 | pad: 1 276 | kernel_size: 3 277 | weight_filler { 278 | type: "xavier" 279 | } 280 | bias_filler { 281 | type: "constant" 282 | } 283 | } 284 | } 285 | layer { 286 | bottom: "conv4_1" 287 | top: "conv4_1" 288 | name: "relu4_1" 289 | type: "ReLU" 290 | } 291 | layer { 292 | bottom: "conv4_1" 293 | top: "conv4_2" 294 | name: "conv4_2" 295 | type: "Convolution" 296 | param { 297 | lr_mult: 1 298 | decay_mult: 1 299 | } 300 | param { 301 | lr_mult: 2 302 | decay_mult: 0 303 | } 304 | convolution_param { 305 | num_output: 512 306 | pad: 1 307 | kernel_size: 3 308 | weight_filler { 309 | type: "xavier" 310 | } 311 | bias_filler { 312 | type: "constant" 313 | } 314 | } 315 | } 316 | layer { 317 | bottom: "conv4_2" 318 | top: "conv4_2" 319 | name: "relu4_2" 320 | type: "ReLU" 321 | } 322 | layer { 323 | bottom: "conv4_2" 324 | top: "conv4_3" 325 | name: "conv4_3" 326 | type: "Convolution" 327 | param { 328 | lr_mult: 1 329 | decay_mult: 1 330 | } 331 | param { 332 | lr_mult: 2 333 | decay_mult: 0 334 | } 335 | convolution_param { 336 | num_output: 512 337 | pad: 1 338 | kernel_size: 3 339 | weight_filler { 340 | type: "xavier" 341 | } 342 | bias_filler { 343 | type: "constant" 344 | } 345 | } 346 | } 347 | layer { 348 | bottom: "conv4_3" 349 | top: "conv4_3" 350 | name: "relu4_3" 351 | type: "ReLU" 352 | } 353 | layer { 354 | bottom: "conv4_3" 355 | top: "pool4" 356 | name: "pool4" 357 | type: "Pooling" 358 | pooling_param { 359 | pool: MAX 360 | kernel_size: 2 361 | stride: 2 362 | } 363 | } 364 | layer { 365 | bottom: "pool4" 366 | top: "conv5_1" 367 | name: "conv5_1" 368 | type: "Convolution" 369 | param { 370 | lr_mult: 1 371 | decay_mult: 1 372 | } 373 | param { 374 | lr_mult: 2 375 | decay_mult: 0 376 | } 377 | convolution_param { 378 | num_output: 512 379 | pad: 1 380 | kernel_size: 3 381 | weight_filler { 382 | type: "xavier" 383 | } 384 | bias_filler { 385 | type: "constant" 386 | } 387 | } 388 | } 389 | layer { 390 | bottom: "conv5_1" 391 | top: "conv5_1" 392 | name: "relu5_1" 393 | type: "ReLU" 394 | } 395 | layer { 396 | bottom: "conv5_1" 397 | top: "conv5_2" 398 | name: "conv5_2" 399 | type: "Convolution" 400 | param { 401 | lr_mult: 1 402 | decay_mult: 1 403 | } 404 | param { 405 | lr_mult: 2 406 | decay_mult: 0 407 | } 408 | convolution_param { 409 | num_output: 512 410 | pad: 1 411 | kernel_size: 3 412 | weight_filler { 413 | type: "xavier" 414 | } 415 | bias_filler { 416 | type: "constant" 417 | } 418 | } 419 | } 420 | layer { 421 | bottom: "conv5_2" 422 | top: "conv5_2" 423 | name: "relu5_2" 424 | type: "ReLU" 425 | } 426 | layer { 427 | bottom: "conv5_2" 428 | top: "conv5_3" 429 | name: "conv5_3" 430 | type: "Convolution" 431 | param { 432 | lr_mult: 1 433 | decay_mult: 1 434 | } 435 | param { 436 | lr_mult: 2 437 | decay_mult: 0 438 | } 439 | convolution_param { 440 | num_output: 512 441 | pad: 1 442 | kernel_size: 3 443 | weight_filler { 444 | type: "xavier" 445 | } 446 | bias_filler { 447 | type: "constant" 448 | } 449 | } 450 | } 451 | layer { 452 | bottom: "conv5_3" 453 | top: "conv5_3" 454 | name: "relu5_3" 455 | type: "ReLU" 456 | } 457 | layer { 458 | bottom: "conv5_3" 459 | top: "pool5" 460 | name: "pool5" 461 | type: "Pooling" 462 | pooling_param { 463 | pool: MAX 464 | kernel_size: 2 465 | stride: 2 466 | } 467 | } 468 | layer { 469 | bottom: "pool5" 470 | top: "fc6" 471 | name: "fc6" 472 | type: "InnerProduct" 473 | param { 474 | lr_mult: 10 475 | decay_mult: 1 476 | } 477 | param { 478 | lr_mult: 20 479 | decay_mult: 0 480 | } 481 | inner_product_param { 482 | num_output: 4096 483 | weight_filler { 484 | type: "xavier" 485 | } 486 | bias_filler { 487 | type: "constant" 488 | } 489 | } 490 | } 491 | layer { 492 | bottom: "fc6" 493 | top: "fc6" 494 | name: "relu6" 495 | type: "ReLU" 496 | } 497 | layer { 498 | bottom: "fc6" 499 | top: "fc6" 500 | name: "drop6" 501 | type: "Dropout" 502 | dropout_param { 503 | dropout_ratio: 0.5 504 | } 505 | } 506 | layer { 507 | bottom: "fc6" 508 | top: "fc7" 509 | name: "fc7" 510 | type: "InnerProduct" 511 | param { 512 | lr_mult: 10 513 | decay_mult: 1 514 | } 515 | param { 516 | lr_mult: 20 517 | decay_mult: 0 518 | } 519 | inner_product_param { 520 | num_output: 4096 521 | weight_filler { 522 | type: "xavier" 523 | } 524 | bias_filler { 525 | type: "constant" 526 | } 527 | } 528 | } 529 | layer { 530 | bottom: "fc7" 531 | top: "fc7" 532 | name: "relu7" 533 | type: "ReLU" 534 | } 535 | layer { 536 | bottom: "fc7" 537 | top: "fc7" 538 | name: "drop7" 539 | type: "Dropout" 540 | dropout_param { 541 | dropout_ratio: 0.5 542 | } 543 | } 544 | layer { 545 | bottom: "fc7" 546 | top: "fc8_m" 547 | name: "fc8_m" 548 | type: "InnerProduct" 549 | param { 550 | lr_mult: 10 551 | decay_mult: 1 552 | } 553 | param { 554 | lr_mult: 20 555 | decay_mult: 0 556 | } 557 | inner_product_param { 558 | num_output: 1 559 | weight_filler { 560 | type: "xavier" 561 | } 562 | bias_filler { 563 | type: "constant" 564 | } 565 | } 566 | } 567 | -------------------------------------------------------------------------------- /src/RankIQA/live/solver_vgg.prototxt: -------------------------------------------------------------------------------- 1 | # The train/test net protocol buffer definition 2 | net: "src/RankIQA/live/train_vgg.prototxt" 3 | 4 | test_iter: 1 5 | 6 | test_interval: 1000 7 | base_lr: 0.00001 8 | lr_policy: "step" 9 | gamma: 0.1 10 | stepsize: 10000 11 | display: 100 12 | max_iter: 50000 13 | momentum: 0.9 14 | solver_type: SGD 15 | weight_decay: 0.0005 16 | average_loss: 500 17 | snapshot: 10000 18 | snapshot_prefix: "models/rank_live/my_siamese" 19 | solver_mode: GPU 20 | -------------------------------------------------------------------------------- /src/RankIQA/live/train_vgg.prototxt: -------------------------------------------------------------------------------- 1 | name: "RankIQA_siamese_train_test" 2 | 3 | layer { 4 | name: "data" 5 | type: "Python" 6 | top: "data" 7 | top: "label" 8 | include { 9 | phase: TRAIN 10 | } 11 | python_param { 12 | module: "src.data_layer.rank_layer_live" 13 | layer: "DataLayer" 14 | param_str: " {\'pascal_root\': \'data\' ,\'split\': \'live_train\', \'im_shape\': [224, 224],\'batch_size\': 48}" 15 | } 16 | } 17 | layer { 18 | name: "data" 19 | type: "Python" 20 | top: "data" 21 | top: "label" 22 | include { 23 | phase: TEST 24 | } 25 | python_param { 26 | module: "src.data_layer.rank_layer_live" 27 | layer: "DataLayer" 28 | #batch_size: 160 29 | param_str: " {\'pascal_root\': \'data\' ,\'split\': \'live_test\', \'im_shape\': [224, 224],\'batch_size\': 48}" 30 | } 31 | } 32 | layer { 33 | bottom: "data" 34 | top: "conv1_1" 35 | name: "conv1_1" 36 | type: "Convolution" 37 | param { 38 | lr_mult: 1 39 | decay_mult: 1 40 | } 41 | param { 42 | lr_mult: 2 43 | decay_mult: 0 44 | } 45 | convolution_param { 46 | num_output: 64 47 | pad: 1 48 | kernel_size: 3 49 | weight_filler { 50 | type: "xavier" 51 | } 52 | bias_filler { 53 | type: "constant" 54 | } 55 | } 56 | } 57 | layer { 58 | bottom: "conv1_1" 59 | top: "conv1_1" 60 | name: "relu1_1" 61 | type: "ReLU" 62 | } 63 | layer { 64 | bottom: "conv1_1" 65 | top: "conv1_2" 66 | name: "conv1_2" 67 | type: "Convolution" 68 | param { 69 | lr_mult: 1 70 | decay_mult: 1 71 | } 72 | param { 73 | lr_mult: 2 74 | decay_mult: 0 75 | } 76 | convolution_param { 77 | num_output: 64 78 | pad: 1 79 | kernel_size: 3 80 | weight_filler { 81 | type: "xavier" 82 | } 83 | bias_filler { 84 | type: "constant" 85 | } 86 | } 87 | } 88 | layer { 89 | bottom: "conv1_2" 90 | top: "conv1_2" 91 | name: "relu1_2" 92 | type: "ReLU" 93 | } 94 | layer { 95 | bottom: "conv1_2" 96 | top: "pool1" 97 | name: "pool1" 98 | type: "Pooling" 99 | pooling_param { 100 | pool: MAX 101 | kernel_size: 2 102 | stride: 2 103 | } 104 | } 105 | layer { 106 | bottom: "pool1" 107 | top: "conv2_1" 108 | name: "conv2_1" 109 | type: "Convolution" 110 | param { 111 | lr_mult: 1 112 | decay_mult: 1 113 | } 114 | param { 115 | lr_mult: 2 116 | decay_mult: 0 117 | } 118 | convolution_param { 119 | num_output: 128 120 | pad: 1 121 | kernel_size: 3 122 | weight_filler { 123 | type: "xavier" 124 | } 125 | bias_filler { 126 | type: "constant" 127 | } 128 | } 129 | } 130 | layer { 131 | bottom: "conv2_1" 132 | top: "conv2_1" 133 | name: "relu2_1" 134 | type: "ReLU" 135 | } 136 | layer { 137 | bottom: "conv2_1" 138 | top: "conv2_2" 139 | name: "conv2_2" 140 | type: "Convolution" 141 | param { 142 | lr_mult: 1 143 | decay_mult: 1 144 | } 145 | param { 146 | lr_mult: 2 147 | decay_mult: 0 148 | } 149 | convolution_param { 150 | num_output: 128 151 | pad: 1 152 | kernel_size: 3 153 | weight_filler { 154 | type: "xavier" 155 | } 156 | bias_filler { 157 | type: "constant" 158 | } 159 | } 160 | } 161 | layer { 162 | bottom: "conv2_2" 163 | top: "conv2_2" 164 | name: "relu2_2" 165 | type: "ReLU" 166 | } 167 | layer { 168 | bottom: "conv2_2" 169 | top: "pool2" 170 | name: "pool2" 171 | type: "Pooling" 172 | pooling_param { 173 | pool: MAX 174 | kernel_size: 2 175 | stride: 2 176 | } 177 | } 178 | layer { 179 | bottom: "pool2" 180 | top: "conv3_1" 181 | name: "conv3_1" 182 | type: "Convolution" 183 | param { 184 | lr_mult: 1 185 | decay_mult: 1 186 | } 187 | param { 188 | lr_mult: 2 189 | decay_mult: 0 190 | } 191 | convolution_param { 192 | num_output: 256 193 | pad: 1 194 | kernel_size: 3 195 | weight_filler { 196 | type: "xavier" 197 | } 198 | bias_filler { 199 | type: "constant" 200 | } 201 | } 202 | } 203 | layer { 204 | bottom: "conv3_1" 205 | top: "conv3_1" 206 | name: "relu3_1" 207 | type: "ReLU" 208 | } 209 | layer { 210 | bottom: "conv3_1" 211 | top: "conv3_2" 212 | name: "conv3_2" 213 | type: "Convolution" 214 | param { 215 | lr_mult: 1 216 | decay_mult: 1 217 | } 218 | param { 219 | lr_mult: 2 220 | decay_mult: 0 221 | } 222 | convolution_param { 223 | num_output: 256 224 | pad: 1 225 | kernel_size: 3 226 | weight_filler { 227 | type: "xavier" 228 | } 229 | bias_filler { 230 | type: "constant" 231 | } 232 | } 233 | } 234 | layer { 235 | bottom: "conv3_2" 236 | top: "conv3_2" 237 | name: "relu3_2" 238 | type: "ReLU" 239 | } 240 | layer { 241 | bottom: "conv3_2" 242 | top: "conv3_3" 243 | name: "conv3_3" 244 | type: "Convolution" 245 | param { 246 | lr_mult: 1 247 | decay_mult: 1 248 | } 249 | param { 250 | lr_mult: 2 251 | decay_mult: 0 252 | } 253 | convolution_param { 254 | num_output: 256 255 | pad: 1 256 | kernel_size: 3 257 | weight_filler { 258 | type: "xavier" 259 | } 260 | bias_filler { 261 | type: "constant" 262 | } 263 | } 264 | } 265 | layer { 266 | bottom: "conv3_3" 267 | top: "conv3_3" 268 | name: "relu3_3" 269 | type: "ReLU" 270 | } 271 | layer { 272 | bottom: "conv3_3" 273 | top: "pool3" 274 | name: "pool3" 275 | type: "Pooling" 276 | pooling_param { 277 | pool: MAX 278 | kernel_size: 2 279 | stride: 2 280 | } 281 | } 282 | layer { 283 | bottom: "pool3" 284 | top: "conv4_1" 285 | name: "conv4_1" 286 | type: "Convolution" 287 | param { 288 | lr_mult: 1 289 | decay_mult: 1 290 | } 291 | param { 292 | lr_mult: 2 293 | decay_mult: 0 294 | } 295 | convolution_param { 296 | num_output: 512 297 | pad: 1 298 | kernel_size: 3 299 | weight_filler { 300 | type: "xavier" 301 | } 302 | bias_filler { 303 | type: "constant" 304 | } 305 | } 306 | } 307 | layer { 308 | bottom: "conv4_1" 309 | top: "conv4_1" 310 | name: "relu4_1" 311 | type: "ReLU" 312 | } 313 | layer { 314 | bottom: "conv4_1" 315 | top: "conv4_2" 316 | name: "conv4_2" 317 | type: "Convolution" 318 | param { 319 | lr_mult: 1 320 | decay_mult: 1 321 | } 322 | param { 323 | lr_mult: 2 324 | decay_mult: 0 325 | } 326 | convolution_param { 327 | num_output: 512 328 | pad: 1 329 | kernel_size: 3 330 | weight_filler { 331 | type: "xavier" 332 | } 333 | bias_filler { 334 | type: "constant" 335 | } 336 | } 337 | } 338 | layer { 339 | bottom: "conv4_2" 340 | top: "conv4_2" 341 | name: "relu4_2" 342 | type: "ReLU" 343 | } 344 | layer { 345 | bottom: "conv4_2" 346 | top: "conv4_3" 347 | name: "conv4_3" 348 | type: "Convolution" 349 | param { 350 | lr_mult: 1 351 | decay_mult: 1 352 | } 353 | param { 354 | lr_mult: 2 355 | decay_mult: 0 356 | } 357 | convolution_param { 358 | num_output: 512 359 | pad: 1 360 | kernel_size: 3 361 | weight_filler { 362 | type: "xavier" 363 | } 364 | bias_filler { 365 | type: "constant" 366 | } 367 | } 368 | } 369 | layer { 370 | bottom: "conv4_3" 371 | top: "conv4_3" 372 | name: "relu4_3" 373 | type: "ReLU" 374 | } 375 | layer { 376 | bottom: "conv4_3" 377 | top: "pool4" 378 | name: "pool4" 379 | type: "Pooling" 380 | pooling_param { 381 | pool: MAX 382 | kernel_size: 2 383 | stride: 2 384 | } 385 | } 386 | layer { 387 | bottom: "pool4" 388 | top: "conv5_1" 389 | name: "conv5_1" 390 | type: "Convolution" 391 | param { 392 | lr_mult: 1 393 | decay_mult: 1 394 | } 395 | param { 396 | lr_mult: 2 397 | decay_mult: 0 398 | } 399 | convolution_param { 400 | num_output: 512 401 | pad: 1 402 | kernel_size: 3 403 | weight_filler { 404 | type: "xavier" 405 | } 406 | bias_filler { 407 | type: "constant" 408 | } 409 | } 410 | } 411 | layer { 412 | bottom: "conv5_1" 413 | top: "conv5_1" 414 | name: "relu5_1" 415 | type: "ReLU" 416 | } 417 | layer { 418 | bottom: "conv5_1" 419 | top: "conv5_2" 420 | name: "conv5_2" 421 | type: "Convolution" 422 | param { 423 | lr_mult: 1 424 | decay_mult: 1 425 | } 426 | param { 427 | lr_mult: 2 428 | decay_mult: 0 429 | } 430 | convolution_param { 431 | num_output: 512 432 | pad: 1 433 | kernel_size: 3 434 | weight_filler { 435 | type: "xavier" 436 | } 437 | bias_filler { 438 | type: "constant" 439 | } 440 | } 441 | } 442 | layer { 443 | bottom: "conv5_2" 444 | top: "conv5_2" 445 | name: "relu5_2" 446 | type: "ReLU" 447 | } 448 | layer { 449 | bottom: "conv5_2" 450 | top: "conv5_3" 451 | name: "conv5_3" 452 | type: "Convolution" 453 | param { 454 | lr_mult: 1 455 | decay_mult: 1 456 | } 457 | param { 458 | lr_mult: 2 459 | decay_mult: 0 460 | } 461 | convolution_param { 462 | num_output: 512 463 | pad: 1 464 | kernel_size: 3 465 | weight_filler { 466 | type: "xavier" 467 | } 468 | bias_filler { 469 | type: "constant" 470 | } 471 | } 472 | } 473 | layer { 474 | bottom: "conv5_3" 475 | top: "conv5_3" 476 | name: "relu5_3" 477 | type: "ReLU" 478 | } 479 | layer { 480 | bottom: "conv5_3" 481 | top: "pool5" 482 | name: "pool5" 483 | type: "Pooling" 484 | pooling_param { 485 | pool: MAX 486 | kernel_size: 2 487 | stride: 2 488 | } 489 | } 490 | layer { 491 | bottom: "pool5" 492 | top: "fc6" 493 | name: "fc6" 494 | type: "InnerProduct" 495 | param { 496 | lr_mult: 1 497 | decay_mult: 1 498 | } 499 | param { 500 | lr_mult: 2 501 | decay_mult: 0 502 | } 503 | inner_product_param { 504 | num_output: 4096 505 | weight_filler { 506 | type: "xavier" 507 | } 508 | bias_filler { 509 | type: "constant" 510 | } 511 | } 512 | } 513 | layer { 514 | bottom: "fc6" 515 | top: "fc6" 516 | name: "relu6" 517 | type: "ReLU" 518 | } 519 | layer { 520 | bottom: "fc6" 521 | top: "fc6" 522 | name: "drop6" 523 | type: "Dropout" 524 | dropout_param { 525 | dropout_ratio: 0.5 526 | } 527 | } 528 | layer { 529 | bottom: "fc6" 530 | top: "fc7" 531 | name: "fc7" 532 | type: "InnerProduct" 533 | param { 534 | lr_mult: 1 535 | decay_mult: 1 536 | } 537 | param { 538 | lr_mult: 2 539 | decay_mult: 0 540 | } 541 | inner_product_param { 542 | num_output: 4096 543 | weight_filler { 544 | type: "xavier" 545 | } 546 | bias_filler { 547 | type: "constant" 548 | } 549 | } 550 | } 551 | layer { 552 | bottom: "fc7" 553 | top: "fc7" 554 | name: "relu7" 555 | type: "ReLU" 556 | } 557 | layer { 558 | bottom: "fc7" 559 | top: "fc7" 560 | name: "drop7" 561 | type: "Dropout" 562 | dropout_param { 563 | dropout_ratio: 0.5 564 | } 565 | } 566 | layer { 567 | bottom: "fc7" 568 | top: "fc8_m" 569 | name: "fc8_m" 570 | type: "InnerProduct" 571 | param { 572 | lr_mult: 10 573 | decay_mult: 1 574 | } 575 | param { 576 | lr_mult: 20 577 | decay_mult: 0 578 | } 579 | inner_product_param { 580 | num_output: 1 581 | weight_filler { 582 | type: "xavier" 583 | } 584 | bias_filler { 585 | type: "constant" 586 | } 587 | } 588 | } 589 | 590 | 591 | layer { 592 | type: "Python" 593 | name: "accuracy" 594 | top: 'loss' 595 | 596 | bottom: "fc8_m" 597 | bottom: "label" 598 | 599 | python_param { 600 | module: 'src.MyLossLayer.netloss_live' 601 | layer: 'MyLossLayer' 602 | } 603 | loss_weight:1 604 | } 605 | -------------------------------------------------------------------------------- /src/RankIQA/live/train_vgg.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | TOOLS=/home/xialei/caffe/distribute/bin # TODO Changing to your Caffe bin 4 | 5 | $TOOLS/caffe.bin -gpu 2 train -solver src/RankIQA/live/solver_vgg.prototxt --weights ./models/VGG_ILSVRC_16_layers.caffemodel 2>&1 | tee models/rank_live/log_live 6 | -------------------------------------------------------------------------------- /src/RankIQA/tid2013/deploy_vgg.prototxt: -------------------------------------------------------------------------------- 1 | name: "mnist_siamese_train_test" 2 | input: "data" 3 | input_shape { 4 | dim: 1 5 | dim: 3 6 | dim: 224 7 | dim: 224 8 | } 9 | 10 | layer { 11 | bottom: "data" 12 | top: "conv1_1" 13 | name: "conv1_1" 14 | type: "Convolution" 15 | param { 16 | lr_mult: 1 17 | decay_mult: 1 18 | } 19 | param { 20 | lr_mult: 2 21 | decay_mult: 0 22 | } 23 | convolution_param { 24 | num_output: 64 25 | pad: 1 26 | kernel_size: 3 27 | weight_filler { 28 | type: "xavier" 29 | } 30 | bias_filler { 31 | type: "constant" 32 | } 33 | } 34 | } 35 | layer { 36 | bottom: "conv1_1" 37 | top: "conv1_1" 38 | name: "relu1_1" 39 | type: "ReLU" 40 | } 41 | layer { 42 | bottom: "conv1_1" 43 | top: "conv1_2" 44 | name: "conv1_2" 45 | type: "Convolution" 46 | param { 47 | lr_mult: 1 48 | decay_mult: 1 49 | } 50 | param { 51 | lr_mult: 2 52 | decay_mult: 0 53 | } 54 | convolution_param { 55 | num_output: 64 56 | pad: 1 57 | kernel_size: 3 58 | weight_filler { 59 | type: "xavier" 60 | } 61 | bias_filler { 62 | type: "constant" 63 | } 64 | } 65 | } 66 | layer { 67 | bottom: "conv1_2" 68 | top: "conv1_2" 69 | name: "relu1_2" 70 | type: "ReLU" 71 | } 72 | layer { 73 | bottom: "conv1_2" 74 | top: "pool1" 75 | name: "pool1" 76 | type: "Pooling" 77 | pooling_param { 78 | pool: MAX 79 | kernel_size: 2 80 | stride: 2 81 | } 82 | } 83 | layer { 84 | bottom: "pool1" 85 | top: "conv2_1" 86 | name: "conv2_1" 87 | type: "Convolution" 88 | param { 89 | lr_mult: 1 90 | decay_mult: 1 91 | } 92 | param { 93 | lr_mult: 2 94 | decay_mult: 0 95 | } 96 | convolution_param { 97 | num_output: 128 98 | pad: 1 99 | kernel_size: 3 100 | weight_filler { 101 | type: "xavier" 102 | } 103 | bias_filler { 104 | type: "constant" 105 | } 106 | } 107 | } 108 | layer { 109 | bottom: "conv2_1" 110 | top: "conv2_1" 111 | name: "relu2_1" 112 | type: "ReLU" 113 | } 114 | layer { 115 | bottom: "conv2_1" 116 | top: "conv2_2" 117 | name: "conv2_2" 118 | type: "Convolution" 119 | param { 120 | lr_mult: 1 121 | decay_mult: 1 122 | } 123 | param { 124 | lr_mult: 2 125 | decay_mult: 0 126 | } 127 | convolution_param { 128 | num_output: 128 129 | pad: 1 130 | kernel_size: 3 131 | weight_filler { 132 | type: "xavier" 133 | } 134 | bias_filler { 135 | type: "constant" 136 | } 137 | } 138 | } 139 | layer { 140 | bottom: "conv2_2" 141 | top: "conv2_2" 142 | name: "relu2_2" 143 | type: "ReLU" 144 | } 145 | layer { 146 | bottom: "conv2_2" 147 | top: "pool2" 148 | name: "pool2" 149 | type: "Pooling" 150 | pooling_param { 151 | pool: MAX 152 | kernel_size: 2 153 | stride: 2 154 | } 155 | } 156 | layer { 157 | bottom: "pool2" 158 | top: "conv3_1" 159 | name: "conv3_1" 160 | type: "Convolution" 161 | param { 162 | lr_mult: 1 163 | decay_mult: 1 164 | } 165 | param { 166 | lr_mult: 2 167 | decay_mult: 0 168 | } 169 | convolution_param { 170 | num_output: 256 171 | pad: 1 172 | kernel_size: 3 173 | weight_filler { 174 | type: "xavier" 175 | } 176 | bias_filler { 177 | type: "constant" 178 | } 179 | } 180 | } 181 | layer { 182 | bottom: "conv3_1" 183 | top: "conv3_1" 184 | name: "relu3_1" 185 | type: "ReLU" 186 | } 187 | layer { 188 | bottom: "conv3_1" 189 | top: "conv3_2" 190 | name: "conv3_2" 191 | type: "Convolution" 192 | param { 193 | lr_mult: 1 194 | decay_mult: 1 195 | } 196 | param { 197 | lr_mult: 2 198 | decay_mult: 0 199 | } 200 | convolution_param { 201 | num_output: 256 202 | pad: 1 203 | kernel_size: 3 204 | weight_filler { 205 | type: "xavier" 206 | } 207 | bias_filler { 208 | type: "constant" 209 | } 210 | } 211 | } 212 | layer { 213 | bottom: "conv3_2" 214 | top: "conv3_2" 215 | name: "relu3_2" 216 | type: "ReLU" 217 | } 218 | layer { 219 | bottom: "conv3_2" 220 | top: "conv3_3" 221 | name: "conv3_3" 222 | type: "Convolution" 223 | param { 224 | lr_mult: 1 225 | decay_mult: 1 226 | } 227 | param { 228 | lr_mult: 2 229 | decay_mult: 0 230 | } 231 | convolution_param { 232 | num_output: 256 233 | pad: 1 234 | kernel_size: 3 235 | weight_filler { 236 | type: "xavier" 237 | } 238 | bias_filler { 239 | type: "constant" 240 | } 241 | } 242 | } 243 | layer { 244 | bottom: "conv3_3" 245 | top: "conv3_3" 246 | name: "relu3_3" 247 | type: "ReLU" 248 | } 249 | layer { 250 | bottom: "conv3_3" 251 | top: "pool3" 252 | name: "pool3" 253 | type: "Pooling" 254 | pooling_param { 255 | pool: MAX 256 | kernel_size: 2 257 | stride: 2 258 | } 259 | } 260 | layer { 261 | bottom: "pool3" 262 | top: "conv4_1" 263 | name: "conv4_1" 264 | type: "Convolution" 265 | param { 266 | lr_mult: 1 267 | decay_mult: 1 268 | } 269 | param { 270 | lr_mult: 2 271 | decay_mult: 0 272 | } 273 | convolution_param { 274 | num_output: 512 275 | pad: 1 276 | kernel_size: 3 277 | weight_filler { 278 | type: "xavier" 279 | } 280 | bias_filler { 281 | type: "constant" 282 | } 283 | } 284 | } 285 | layer { 286 | bottom: "conv4_1" 287 | top: "conv4_1" 288 | name: "relu4_1" 289 | type: "ReLU" 290 | } 291 | layer { 292 | bottom: "conv4_1" 293 | top: "conv4_2" 294 | name: "conv4_2" 295 | type: "Convolution" 296 | param { 297 | lr_mult: 1 298 | decay_mult: 1 299 | } 300 | param { 301 | lr_mult: 2 302 | decay_mult: 0 303 | } 304 | convolution_param { 305 | num_output: 512 306 | pad: 1 307 | kernel_size: 3 308 | weight_filler { 309 | type: "xavier" 310 | } 311 | bias_filler { 312 | type: "constant" 313 | } 314 | } 315 | } 316 | layer { 317 | bottom: "conv4_2" 318 | top: "conv4_2" 319 | name: "relu4_2" 320 | type: "ReLU" 321 | } 322 | layer { 323 | bottom: "conv4_2" 324 | top: "conv4_3" 325 | name: "conv4_3" 326 | type: "Convolution" 327 | param { 328 | lr_mult: 1 329 | decay_mult: 1 330 | } 331 | param { 332 | lr_mult: 2 333 | decay_mult: 0 334 | } 335 | convolution_param { 336 | num_output: 512 337 | pad: 1 338 | kernel_size: 3 339 | weight_filler { 340 | type: "xavier" 341 | } 342 | bias_filler { 343 | type: "constant" 344 | } 345 | } 346 | } 347 | layer { 348 | bottom: "conv4_3" 349 | top: "conv4_3" 350 | name: "relu4_3" 351 | type: "ReLU" 352 | } 353 | layer { 354 | bottom: "conv4_3" 355 | top: "pool4" 356 | name: "pool4" 357 | type: "Pooling" 358 | pooling_param { 359 | pool: MAX 360 | kernel_size: 2 361 | stride: 2 362 | } 363 | } 364 | layer { 365 | bottom: "pool4" 366 | top: "conv5_1" 367 | name: "conv5_1" 368 | type: "Convolution" 369 | param { 370 | lr_mult: 1 371 | decay_mult: 1 372 | } 373 | param { 374 | lr_mult: 2 375 | decay_mult: 0 376 | } 377 | convolution_param { 378 | num_output: 512 379 | pad: 1 380 | kernel_size: 3 381 | weight_filler { 382 | type: "xavier" 383 | } 384 | bias_filler { 385 | type: "constant" 386 | } 387 | } 388 | } 389 | layer { 390 | bottom: "conv5_1" 391 | top: "conv5_1" 392 | name: "relu5_1" 393 | type: "ReLU" 394 | } 395 | layer { 396 | bottom: "conv5_1" 397 | top: "conv5_2" 398 | name: "conv5_2" 399 | type: "Convolution" 400 | param { 401 | lr_mult: 1 402 | decay_mult: 1 403 | } 404 | param { 405 | lr_mult: 2 406 | decay_mult: 0 407 | } 408 | convolution_param { 409 | num_output: 512 410 | pad: 1 411 | kernel_size: 3 412 | weight_filler { 413 | type: "xavier" 414 | } 415 | bias_filler { 416 | type: "constant" 417 | } 418 | } 419 | } 420 | layer { 421 | bottom: "conv5_2" 422 | top: "conv5_2" 423 | name: "relu5_2" 424 | type: "ReLU" 425 | } 426 | layer { 427 | bottom: "conv5_2" 428 | top: "conv5_3" 429 | name: "conv5_3" 430 | type: "Convolution" 431 | param { 432 | lr_mult: 1 433 | decay_mult: 1 434 | } 435 | param { 436 | lr_mult: 2 437 | decay_mult: 0 438 | } 439 | convolution_param { 440 | num_output: 512 441 | pad: 1 442 | kernel_size: 3 443 | weight_filler { 444 | type: "xavier" 445 | } 446 | bias_filler { 447 | type: "constant" 448 | } 449 | } 450 | } 451 | layer { 452 | bottom: "conv5_3" 453 | top: "conv5_3" 454 | name: "relu5_3" 455 | type: "ReLU" 456 | } 457 | layer { 458 | bottom: "conv5_3" 459 | top: "pool5" 460 | name: "pool5" 461 | type: "Pooling" 462 | pooling_param { 463 | pool: MAX 464 | kernel_size: 2 465 | stride: 2 466 | } 467 | } 468 | layer { 469 | bottom: "pool5" 470 | top: "fc6" 471 | name: "fc6" 472 | type: "InnerProduct" 473 | param { 474 | lr_mult: 10 475 | decay_mult: 1 476 | } 477 | param { 478 | lr_mult: 20 479 | decay_mult: 0 480 | } 481 | inner_product_param { 482 | num_output: 4096 483 | weight_filler { 484 | type: "xavier" 485 | } 486 | bias_filler { 487 | type: "constant" 488 | } 489 | } 490 | } 491 | layer { 492 | bottom: "fc6" 493 | top: "fc6" 494 | name: "relu6" 495 | type: "ReLU" 496 | } 497 | layer { 498 | bottom: "fc6" 499 | top: "fc6" 500 | name: "drop6" 501 | type: "Dropout" 502 | dropout_param { 503 | dropout_ratio: 0.5 504 | } 505 | } 506 | layer { 507 | bottom: "fc6" 508 | top: "fc7" 509 | name: "fc7" 510 | type: "InnerProduct" 511 | param { 512 | lr_mult: 10 513 | decay_mult: 1 514 | } 515 | param { 516 | lr_mult: 20 517 | decay_mult: 0 518 | } 519 | inner_product_param { 520 | num_output: 4096 521 | weight_filler { 522 | type: "xavier" 523 | } 524 | bias_filler { 525 | type: "constant" 526 | } 527 | } 528 | } 529 | layer { 530 | bottom: "fc7" 531 | top: "fc7" 532 | name: "relu7" 533 | type: "ReLU" 534 | } 535 | layer { 536 | bottom: "fc7" 537 | top: "fc7" 538 | name: "drop7" 539 | type: "Dropout" 540 | dropout_param { 541 | dropout_ratio: 0.5 542 | } 543 | } 544 | layer { 545 | bottom: "fc7" 546 | top: "fc8_m" 547 | name: "fc8_m" 548 | type: "InnerProduct" 549 | param { 550 | lr_mult: 10 551 | decay_mult: 1 552 | } 553 | param { 554 | lr_mult: 20 555 | decay_mult: 0 556 | } 557 | inner_product_param { 558 | num_output: 1 559 | weight_filler { 560 | type: "xavier" 561 | } 562 | bias_filler { 563 | type: "constant" 564 | } 565 | } 566 | } 567 | -------------------------------------------------------------------------------- /src/RankIQA/tid2013/solver_vgg.prototxt: -------------------------------------------------------------------------------- 1 | # The train/test net protocol buffer definition 2 | net: "src/RankIQA/tid2013/train_vgg.prototxt" 3 | 4 | test_iter: 1 5 | 6 | test_interval: 1000 7 | base_lr: 0.0001 8 | lr_policy: "step" 9 | gamma: 0.1 10 | stepsize: 10000 11 | display: 100 12 | max_iter: 50000 13 | momentum: 0.9 14 | solver_type: SGD 15 | weight_decay: 0.0005 16 | average_loss: 500 17 | snapshot: 10000 18 | snapshot_prefix: "models/rank_tid2013/my_siamese" 19 | solver_mode: GPU 20 | -------------------------------------------------------------------------------- /src/RankIQA/tid2013/train_vgg.prototxt: -------------------------------------------------------------------------------- 1 | name: "RankIQA_siamese_train_test" 2 | 3 | layer { 4 | name: "data" 5 | type: "Python" 6 | top: "data" 7 | top: "label" 8 | include { 9 | phase: TRAIN 10 | } 11 | python_param { 12 | module: "src.data_layer.rank_layer_tid2013" 13 | layer: "DataLayer" 14 | param_str: " {\'pascal_root\': \'data\' ,\'split\': \'tid2013_train\', \'im_shape\': [224, 224],\'batch_size\': 45}" 15 | } 16 | } 17 | layer { 18 | name: "data" 19 | type: "Python" 20 | top: "data" 21 | top: "label" 22 | include { 23 | phase: TEST 24 | } 25 | python_param { 26 | module: "src.data_layer.rank_layer_tid2013" 27 | layer: "DataLayer" 28 | param_str: " {\'pascal_root\': \'data\' ,\'split\': \'tid2013_test\', \'im_shape\': [224, 224],\'batch_size\': 45}" 29 | } 30 | } 31 | layer { 32 | bottom: "data" 33 | top: "conv1_1" 34 | name: "conv1_1" 35 | type: "Convolution" 36 | param { 37 | lr_mult: 1 38 | decay_mult: 1 39 | } 40 | param { 41 | lr_mult: 2 42 | decay_mult: 0 43 | } 44 | convolution_param { 45 | num_output: 64 46 | pad: 1 47 | kernel_size: 3 48 | weight_filler { 49 | type: "xavier" 50 | } 51 | bias_filler { 52 | type: "constant" 53 | } 54 | } 55 | } 56 | layer { 57 | bottom: "conv1_1" 58 | top: "conv1_1" 59 | name: "relu1_1" 60 | type: "ReLU" 61 | } 62 | layer { 63 | bottom: "conv1_1" 64 | top: "conv1_2" 65 | name: "conv1_2" 66 | type: "Convolution" 67 | param { 68 | lr_mult: 1 69 | decay_mult: 1 70 | } 71 | param { 72 | lr_mult: 2 73 | decay_mult: 0 74 | } 75 | convolution_param { 76 | num_output: 64 77 | pad: 1 78 | kernel_size: 3 79 | weight_filler { 80 | type: "xavier" 81 | } 82 | bias_filler { 83 | type: "constant" 84 | } 85 | } 86 | } 87 | layer { 88 | bottom: "conv1_2" 89 | top: "conv1_2" 90 | name: "relu1_2" 91 | type: "ReLU" 92 | } 93 | layer { 94 | bottom: "conv1_2" 95 | top: "pool1" 96 | name: "pool1" 97 | type: "Pooling" 98 | pooling_param { 99 | pool: MAX 100 | kernel_size: 2 101 | stride: 2 102 | } 103 | } 104 | layer { 105 | bottom: "pool1" 106 | top: "conv2_1" 107 | name: "conv2_1" 108 | type: "Convolution" 109 | param { 110 | lr_mult: 1 111 | decay_mult: 1 112 | } 113 | param { 114 | lr_mult: 2 115 | decay_mult: 0 116 | } 117 | convolution_param { 118 | num_output: 128 119 | pad: 1 120 | kernel_size: 3 121 | weight_filler { 122 | type: "xavier" 123 | } 124 | bias_filler { 125 | type: "constant" 126 | } 127 | } 128 | } 129 | layer { 130 | bottom: "conv2_1" 131 | top: "conv2_1" 132 | name: "relu2_1" 133 | type: "ReLU" 134 | } 135 | layer { 136 | bottom: "conv2_1" 137 | top: "conv2_2" 138 | name: "conv2_2" 139 | type: "Convolution" 140 | param { 141 | lr_mult: 1 142 | decay_mult: 1 143 | } 144 | param { 145 | lr_mult: 2 146 | decay_mult: 0 147 | } 148 | convolution_param { 149 | num_output: 128 150 | pad: 1 151 | kernel_size: 3 152 | weight_filler { 153 | type: "xavier" 154 | } 155 | bias_filler { 156 | type: "constant" 157 | } 158 | } 159 | } 160 | layer { 161 | bottom: "conv2_2" 162 | top: "conv2_2" 163 | name: "relu2_2" 164 | type: "ReLU" 165 | } 166 | layer { 167 | bottom: "conv2_2" 168 | top: "pool2" 169 | name: "pool2" 170 | type: "Pooling" 171 | pooling_param { 172 | pool: MAX 173 | kernel_size: 2 174 | stride: 2 175 | } 176 | } 177 | layer { 178 | bottom: "pool2" 179 | top: "conv3_1" 180 | name: "conv3_1" 181 | type: "Convolution" 182 | param { 183 | lr_mult: 1 184 | decay_mult: 1 185 | } 186 | param { 187 | lr_mult: 2 188 | decay_mult: 0 189 | } 190 | convolution_param { 191 | num_output: 256 192 | pad: 1 193 | kernel_size: 3 194 | weight_filler { 195 | type: "xavier" 196 | } 197 | bias_filler { 198 | type: "constant" 199 | } 200 | } 201 | } 202 | layer { 203 | bottom: "conv3_1" 204 | top: "conv3_1" 205 | name: "relu3_1" 206 | type: "ReLU" 207 | } 208 | layer { 209 | bottom: "conv3_1" 210 | top: "conv3_2" 211 | name: "conv3_2" 212 | type: "Convolution" 213 | param { 214 | lr_mult: 1 215 | decay_mult: 1 216 | } 217 | param { 218 | lr_mult: 2 219 | decay_mult: 0 220 | } 221 | convolution_param { 222 | num_output: 256 223 | pad: 1 224 | kernel_size: 3 225 | weight_filler { 226 | type: "xavier" 227 | } 228 | bias_filler { 229 | type: "constant" 230 | } 231 | } 232 | } 233 | layer { 234 | bottom: "conv3_2" 235 | top: "conv3_2" 236 | name: "relu3_2" 237 | type: "ReLU" 238 | } 239 | layer { 240 | bottom: "conv3_2" 241 | top: "conv3_3" 242 | name: "conv3_3" 243 | type: "Convolution" 244 | param { 245 | lr_mult: 1 246 | decay_mult: 1 247 | } 248 | param { 249 | lr_mult: 2 250 | decay_mult: 0 251 | } 252 | convolution_param { 253 | num_output: 256 254 | pad: 1 255 | kernel_size: 3 256 | weight_filler { 257 | type: "xavier" 258 | } 259 | bias_filler { 260 | type: "constant" 261 | } 262 | } 263 | } 264 | layer { 265 | bottom: "conv3_3" 266 | top: "conv3_3" 267 | name: "relu3_3" 268 | type: "ReLU" 269 | } 270 | layer { 271 | bottom: "conv3_3" 272 | top: "pool3" 273 | name: "pool3" 274 | type: "Pooling" 275 | pooling_param { 276 | pool: MAX 277 | kernel_size: 2 278 | stride: 2 279 | } 280 | } 281 | layer { 282 | bottom: "pool3" 283 | top: "conv4_1" 284 | name: "conv4_1" 285 | type: "Convolution" 286 | param { 287 | lr_mult: 1 288 | decay_mult: 1 289 | } 290 | param { 291 | lr_mult: 2 292 | decay_mult: 0 293 | } 294 | convolution_param { 295 | num_output: 512 296 | pad: 1 297 | kernel_size: 3 298 | weight_filler { 299 | type: "xavier" 300 | } 301 | bias_filler { 302 | type: "constant" 303 | } 304 | } 305 | } 306 | layer { 307 | bottom: "conv4_1" 308 | top: "conv4_1" 309 | name: "relu4_1" 310 | type: "ReLU" 311 | } 312 | layer { 313 | bottom: "conv4_1" 314 | top: "conv4_2" 315 | name: "conv4_2" 316 | type: "Convolution" 317 | param { 318 | lr_mult: 1 319 | decay_mult: 1 320 | } 321 | param { 322 | lr_mult: 2 323 | decay_mult: 0 324 | } 325 | convolution_param { 326 | num_output: 512 327 | pad: 1 328 | kernel_size: 3 329 | weight_filler { 330 | type: "xavier" 331 | } 332 | bias_filler { 333 | type: "constant" 334 | } 335 | } 336 | } 337 | layer { 338 | bottom: "conv4_2" 339 | top: "conv4_2" 340 | name: "relu4_2" 341 | type: "ReLU" 342 | } 343 | layer { 344 | bottom: "conv4_2" 345 | top: "conv4_3" 346 | name: "conv4_3" 347 | type: "Convolution" 348 | param { 349 | lr_mult: 1 350 | decay_mult: 1 351 | } 352 | param { 353 | lr_mult: 2 354 | decay_mult: 0 355 | } 356 | convolution_param { 357 | num_output: 512 358 | pad: 1 359 | kernel_size: 3 360 | weight_filler { 361 | type: "xavier" 362 | } 363 | bias_filler { 364 | type: "constant" 365 | } 366 | } 367 | } 368 | layer { 369 | bottom: "conv4_3" 370 | top: "conv4_3" 371 | name: "relu4_3" 372 | type: "ReLU" 373 | } 374 | layer { 375 | bottom: "conv4_3" 376 | top: "pool4" 377 | name: "pool4" 378 | type: "Pooling" 379 | pooling_param { 380 | pool: MAX 381 | kernel_size: 2 382 | stride: 2 383 | } 384 | } 385 | layer { 386 | bottom: "pool4" 387 | top: "conv5_1" 388 | name: "conv5_1" 389 | type: "Convolution" 390 | param { 391 | lr_mult: 1 392 | decay_mult: 1 393 | } 394 | param { 395 | lr_mult: 2 396 | decay_mult: 0 397 | } 398 | convolution_param { 399 | num_output: 512 400 | pad: 1 401 | kernel_size: 3 402 | weight_filler { 403 | type: "xavier" 404 | } 405 | bias_filler { 406 | type: "constant" 407 | } 408 | } 409 | } 410 | layer { 411 | bottom: "conv5_1" 412 | top: "conv5_1" 413 | name: "relu5_1" 414 | type: "ReLU" 415 | } 416 | layer { 417 | bottom: "conv5_1" 418 | top: "conv5_2" 419 | name: "conv5_2" 420 | type: "Convolution" 421 | param { 422 | lr_mult: 1 423 | decay_mult: 1 424 | } 425 | param { 426 | lr_mult: 2 427 | decay_mult: 0 428 | } 429 | convolution_param { 430 | num_output: 512 431 | pad: 1 432 | kernel_size: 3 433 | weight_filler { 434 | type: "xavier" 435 | } 436 | bias_filler { 437 | type: "constant" 438 | } 439 | } 440 | } 441 | layer { 442 | bottom: "conv5_2" 443 | top: "conv5_2" 444 | name: "relu5_2" 445 | type: "ReLU" 446 | } 447 | layer { 448 | bottom: "conv5_2" 449 | top: "conv5_3" 450 | name: "conv5_3" 451 | type: "Convolution" 452 | param { 453 | lr_mult: 1 454 | decay_mult: 1 455 | } 456 | param { 457 | lr_mult: 2 458 | decay_mult: 0 459 | } 460 | convolution_param { 461 | num_output: 512 462 | pad: 1 463 | kernel_size: 3 464 | weight_filler { 465 | type: "xavier" 466 | } 467 | bias_filler { 468 | type: "constant" 469 | } 470 | } 471 | } 472 | layer { 473 | bottom: "conv5_3" 474 | top: "conv5_3" 475 | name: "relu5_3" 476 | type: "ReLU" 477 | } 478 | layer { 479 | bottom: "conv5_3" 480 | top: "pool5" 481 | name: "pool5" 482 | type: "Pooling" 483 | pooling_param { 484 | pool: MAX 485 | kernel_size: 2 486 | stride: 2 487 | } 488 | } 489 | layer { 490 | bottom: "pool5" 491 | top: "fc6" 492 | name: "fc6" 493 | type: "InnerProduct" 494 | param { 495 | lr_mult: 1 496 | decay_mult: 1 497 | } 498 | param { 499 | lr_mult: 2 500 | decay_mult: 0 501 | } 502 | inner_product_param { 503 | num_output: 4096 504 | weight_filler { 505 | type: "xavier" 506 | } 507 | bias_filler { 508 | type: "constant" 509 | } 510 | } 511 | } 512 | layer { 513 | bottom: "fc6" 514 | top: "fc6" 515 | name: "relu6" 516 | type: "ReLU" 517 | } 518 | layer { 519 | bottom: "fc6" 520 | top: "fc6" 521 | name: "drop6" 522 | type: "Dropout" 523 | dropout_param { 524 | dropout_ratio: 0.5 525 | } 526 | } 527 | layer { 528 | bottom: "fc6" 529 | top: "fc7" 530 | name: "fc7" 531 | type: "InnerProduct" 532 | param { 533 | lr_mult: 1 534 | decay_mult: 1 535 | } 536 | param { 537 | lr_mult: 2 538 | decay_mult: 0 539 | } 540 | inner_product_param { 541 | num_output: 4096 542 | weight_filler { 543 | type: "xavier" 544 | } 545 | bias_filler { 546 | type: "constant" 547 | } 548 | } 549 | } 550 | layer { 551 | bottom: "fc7" 552 | top: "fc7" 553 | name: "relu7" 554 | type: "ReLU" 555 | } 556 | layer { 557 | bottom: "fc7" 558 | top: "fc7" 559 | name: "drop7" 560 | type: "Dropout" 561 | dropout_param { 562 | dropout_ratio: 0.5 563 | } 564 | } 565 | layer { 566 | bottom: "fc7" 567 | top: "fc8_m" 568 | name: "fc8_m" 569 | type: "InnerProduct" 570 | param { 571 | lr_mult: 10 572 | decay_mult: 1 573 | } 574 | param { 575 | lr_mult: 20 576 | decay_mult: 0 577 | } 578 | inner_product_param { 579 | num_output: 1 580 | weight_filler { 581 | type: "xavier" 582 | } 583 | bias_filler { 584 | type: "constant" 585 | } 586 | } 587 | } 588 | 589 | 590 | layer { 591 | type: "Python" 592 | name: "accuracy" 593 | top: 'loss' 594 | 595 | bottom: "fc8_m" 596 | bottom: "label" 597 | 598 | python_param { 599 | module: 'src.MyLossLayer.netloss_tid2013' 600 | layer: 'MyLossLayer' 601 | } 602 | loss_weight:1 603 | } 604 | -------------------------------------------------------------------------------- /src/RankIQA/tid2013/train_vgg.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | TOOLS=/home/xialei/caffe/distribute/bin #TODO Chaning to your Caffe bin 4 | 5 | $TOOLS/caffe.bin -gpu 0 train -solver src/RankIQA/tid2013/solver_vgg.prototxt --weights ./models/VGG_ILSVRC_16_layers.caffemodel 2>&1 | tee models/rank_tid2013/log_tid2013 6 | -------------------------------------------------------------------------------- /src/__init__.py: -------------------------------------------------------------------------------- 1 | # Placeholder so this diectory acts like a python module. 2 | -------------------------------------------------------------------------------- /src/data_layer/__init__.py: -------------------------------------------------------------------------------- 1 | # Placeholder so this diectory acts like a python module. 2 | -------------------------------------------------------------------------------- /src/data_layer/ft_layer_live.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import caffe 3 | import numpy as np 4 | import multiprocessing as mtp 5 | import pdb 6 | import os.path as osp 7 | 8 | 9 | class DataLayer(caffe.Layer): 10 | def setup(self, bottom, top): 11 | 12 | self._name_to_top_map = {} 13 | self._name_to_top_map['data'] = 0 14 | self._name_to_top_map['label'] = 1 15 | # === Read input parameters === 16 | self.workers= mtp.Pool(10) 17 | # params is a python dictionary with layer parameters. 18 | params = eval(self.param_str) 19 | 20 | # Check the paramameters for validity. 21 | check_params(params) 22 | 23 | # store input as class variables 24 | self.batch_size = params['batch_size'] 25 | self.pascal_root = params['pascal_root'] 26 | self.im_shape = params['im_shape'] 27 | # get list of image indexes. 28 | list_file = params['split'] + '.txt' 29 | filename = [line.rstrip('\n') for line in open( 30 | osp.join(self.pascal_root, list_file))] 31 | self._roidb = [] 32 | self.scores =[] 33 | for i in filename: 34 | self._roidb.append(i.split()[0]) 35 | self.scores.append(float(i.split()[1])) 36 | self._perm = None 37 | self._cur = 0 38 | self._shuffle_roidb_inds() 39 | 40 | top[0].reshape( 41 | self.batch_size, 3, params['im_shape'][0], params['im_shape'][1]) 42 | 43 | top[1].reshape(self.batch_size, 1) 44 | def _shuffle_roidb_inds(self): 45 | """Randomly permute the training roidb.""" 46 | self._perm = np.random.permutation(np.arange(len(self._roidb))) 47 | self._cur = 0 48 | 49 | def _get_next_minibatch_inds(self): 50 | """Return the roidb indices for the next minibatch.""" 51 | # TODO(rbg): remove duplicated code 52 | if self._cur + self.batch_size >= len(self._roidb): 53 | self._shuffle_roidb_inds() 54 | 55 | db_inds = self._perm[self._cur:self._cur + self.batch_size ] 56 | self._cur += self.batch_size 57 | return db_inds 58 | def get_minibatch(self,minibatch_db): 59 | """Given a roidb, construct a minibatch sampled from it.""" 60 | 61 | jobs =self.workers.map(preprocess,minibatch_db) 62 | #print len(jobs) 63 | index = 0 64 | images_train = np.zeros([self.batch_size,3,224,224],np.float32) 65 | #pdb.set_trace() 66 | for index_job in range(len(jobs)): 67 | images_train[index,:,:,:] = jobs[index_job] 68 | index += 1 69 | 70 | blobs = {'data': images_train} 71 | return blobs 72 | 73 | def forward(self, bottom, top): 74 | """Get blobs and copy them into this layer's top blob vector.""" 75 | 76 | 77 | db_inds = self._get_next_minibatch_inds() 78 | minibatch_db = [] 79 | for i in range(len(db_inds)): 80 | minibatch_db.append(self._roidb[int(db_inds[i])]) 81 | #minibatch_db = [self._roidb[i] for i in db_inds] 82 | #print minibatch_db 83 | scores = [] 84 | for i in range(len(db_inds)): 85 | scores.append(self.scores[int(db_inds[i])]) 86 | blobs = self.get_minibatch(minibatch_db) 87 | blobs ['label'] =np.asarray(scores) 88 | for blob_name, blob in blobs.iteritems(): 89 | top_ind = self._name_to_top_map[blob_name] 90 | # Reshape net's input blobs 91 | top[top_ind].reshape(*(blob.shape)) 92 | # Copy data into net's input blobs 93 | top[top_ind].data[...] = blob.astype(np.float32, copy=False) 94 | 95 | def backward(self, top, propagate_down, bottom): 96 | """This layer does not propagate gradients.""" 97 | pass 98 | 99 | def reshape(self, bottom, top): 100 | """Reshaping happens during the call to forward.""" 101 | pass 102 | 103 | def preprocess(data): 104 | 105 | im = np.asarray(cv2.imread(data)) 106 | x = im.shape[0] 107 | y = im.shape[1] 108 | x_p = np.random.randint(x-224,size=1)[0] 109 | y_p = np.random.randint(y-224,size=1)[0] 110 | #print x_p,y_p 111 | images = im[x_p:x_p+224,y_p:y_p+224,:].transpose([2,0,1]) 112 | #print images.shape 113 | return images 114 | 115 | def check_params(params): 116 | """ 117 | A utility function to check the parameters for the data layers. 118 | """ 119 | assert 'split' in params.keys( 120 | ), 'Params must include split (train, val, or test).' 121 | 122 | required = ['batch_size', 'pascal_root', 'im_shape'] 123 | for r in required: 124 | assert r in params.keys(), 'Params must include {}'.format(r) 125 | -------------------------------------------------------------------------------- /src/data_layer/ft_layer_tid2013.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import caffe 3 | import numpy as np 4 | import multiprocessing as mtp 5 | import pdb 6 | import os.path as osp 7 | 8 | class DataLayer(caffe.Layer): 9 | 10 | def setup(self, bottom, top): 11 | 12 | self._name_to_top_map = {} 13 | self._name_to_top_map['data'] = 0 14 | self._name_to_top_map['label'] = 1 15 | # === Read input parameters === 16 | self.workers= mtp.Pool(10) 17 | # params is a python dictionary with layer parameters. 18 | params = eval(self.param_str) 19 | 20 | # Check the paramameters for validity. 21 | check_params(params) 22 | 23 | # store input as class variables 24 | self.batch_size = params['batch_size'] 25 | self.pascal_root = params['pascal_root'] 26 | self.im_shape = params['im_shape'] 27 | # get list of image indexes. 28 | list_file = params['split'] + '.txt' 29 | filename = [line.rstrip('\n') for line in open( 30 | osp.join(self.pascal_root, list_file))] 31 | self._roidb = [] 32 | self.scores =[] 33 | for i in filename: 34 | self._roidb.append(i.split()[0]) 35 | self.scores.append(float(i.split()[1])) 36 | self._perm = None 37 | self._cur = 0 38 | self._shuffle_roidb_inds() 39 | 40 | top[0].reshape( 41 | self.batch_size, 3, params['im_shape'][0], params['im_shape'][1]) 42 | 43 | top[1].reshape(self.batch_size, 1) 44 | def _shuffle_roidb_inds(self): 45 | """Randomly permute the training roidb.""" 46 | self._perm = np.random.permutation(np.arange(len(self._roidb))) 47 | self._cur = 0 48 | 49 | def _get_next_minibatch_inds(self): 50 | """Return the roidb indices for the next minibatch.""" 51 | # TODO(rbg): remove duplicated code 52 | if self._cur + self.batch_size >= len(self._roidb): 53 | self._shuffle_roidb_inds() 54 | 55 | db_inds = self._perm[self._cur:self._cur + self.batch_size ] 56 | self._cur += self.batch_size 57 | return db_inds 58 | def get_minibatch(self,minibatch_db): 59 | """Given a roidb, construct a minibatch sampled from it.""" 60 | 61 | jobs =self.workers.map(preprocess,minibatch_db) 62 | #print len(jobs) 63 | index = 0 64 | images_train = np.zeros([self.batch_size,3,224,224],np.float32) 65 | #pdb.set_trace() 66 | for index_job in range(len(jobs)): 67 | images_train[index,:,:,:] = jobs[index_job] 68 | index += 1 69 | 70 | 71 | blobs = {'data': images_train} 72 | return blobs 73 | 74 | def forward(self, bottom, top): 75 | """Get blobs and copy them into this layer's top blob vector.""" 76 | 77 | 78 | db_inds = self._get_next_minibatch_inds() 79 | minibatch_db = [] 80 | for i in range(len(db_inds)): 81 | minibatch_db.append(self._roidb[int(db_inds[i])]) 82 | #minibatch_db = [self._roidb[i] for i in db_inds] 83 | #print minibatch_db 84 | scores = [] 85 | for i in range(len(db_inds)): 86 | scores.append(self.scores[int(db_inds[i])]) 87 | ind = np.argsort(scores) 88 | ind_minibatch_db = [] 89 | for i in range(len(ind)-1,-1,-1): 90 | ind_minibatch_db.append(minibatch_db[ind[i]]) 91 | blobs = self.get_minibatch(ind_minibatch_db) 92 | blobs ['label'] =np.asarray(sorted(scores,reverse=True)) 93 | for blob_name, blob in blobs.iteritems(): 94 | top_ind = self._name_to_top_map[blob_name] 95 | # Reshape net's input blobs 96 | top[top_ind].reshape(*(blob.shape)) 97 | # Copy data into net's input blobs 98 | top[top_ind].data[...] = blob.astype(np.float32, copy=False) 99 | 100 | def backward(self, top, propagate_down, bottom): 101 | """This layer does not propagate gradients.""" 102 | pass 103 | 104 | def reshape(self, bottom, top): 105 | """Reshaping happens during the call to forward.""" 106 | pass 107 | 108 | def preprocess(data): 109 | 110 | im = np.asarray(cv2.imread(data)) 111 | x = im.shape[0] 112 | y = im.shape[1] 113 | x_p = np.random.randint(x-224,size=1)[0] 114 | y_p = np.random.randint(y-224,size=1)[0] 115 | #print x_p,y_p 116 | images = im[x_p:x_p+224,y_p:y_p+224,:].transpose([2,0,1]) 117 | #print images.shape 118 | return images 119 | 120 | def check_params(params): 121 | """ 122 | A utility function to check the parameters for the data layers. 123 | """ 124 | assert 'split' in params.keys( 125 | ), 'Params must include split (train, val, or test).' 126 | 127 | required = ['batch_size', 'pascal_root', 'im_shape'] 128 | for r in required: 129 | assert r in params.keys(), 'Params must include {}'.format(r) 130 | -------------------------------------------------------------------------------- /src/data_layer/rank_layer_live.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import caffe 3 | import numpy as np 4 | import multiprocessing as mtp 5 | import pdb 6 | import os.path as osp 7 | 8 | 9 | class DataLayer(caffe.Layer): 10 | 11 | def setup(self, bottom, top): 12 | 13 | self._name_to_top_map = {} 14 | self._name_to_top_map['data'] = 0 15 | self._name_to_top_map['label'] = 1 16 | # === Read input parameters === 17 | self.workers= mtp.Pool(10) 18 | # params is a python dictionary with layer parameters. 19 | params = eval(self.param_str) 20 | 21 | # Check the paramameters for validity. 22 | check_params(params) 23 | 24 | # store input as class variables 25 | self.batch_size = params['batch_size'] 26 | self.pascal_root = params['pascal_root'] 27 | self.im_shape = params['im_shape'] 28 | # get list of image indexes. 29 | list_file = params['split'] + '.txt' 30 | filename = [line.rstrip('\n') for line in open( 31 | osp.join(self.pascal_root, list_file))] 32 | self._roidb = [] 33 | self.scores =[] 34 | for i in filename: 35 | self._roidb.append(i.split()[0]) 36 | self.scores.append(float(i.split()[1])) 37 | self._perm = None 38 | self._cur = 0 39 | self.num =0 40 | 41 | top[0].reshape( 42 | self.batch_size, 3, params['im_shape'][0], params['im_shape'][1]) 43 | 44 | top[1].reshape(self.batch_size, 1) 45 | 46 | def _get_next_minibatch_inds(self): 47 | """Return the roidb indices for the next minibatch.""" 48 | db_inds = [] 49 | dis = 4 # total number of distortions in live dataset 50 | batch = 2 # number of images for each distortion level 51 | level = 6 # distortion levels for each mini_batch = level * dis_mini*batch 52 | #shuff = np.random.permutation(range(dis)) 53 | Num = len(self.scores)/dis/level 54 | for k in range(dis): 55 | for i in range(level): 56 | temp = self.num 57 | for j in range(batch): 58 | db_inds.append(len(self.scores)/dis*k+i*Num+temp) 59 | temp = temp +1 60 | self.num = self.num+batch 61 | if Num-self.num