├── LICENSE ├── README.md └── gan_img_detection_fea.m /LICENSE: -------------------------------------------------------------------------------- 1 | COPYRIGHT © 2018 2 | Haodong Li, Bin Li, Shunquan Tan, Jiwu Huang 3 | 4 | 5 | Permission to use, copy, and modify the program for educational, research and 6 | non-profit purposes, without fee, and without a written agreement is hereby 7 | granted, provided that this copyright notice appears in all copies. The 8 | program is supplied "AS IS". The authors do not warrant the operation of the 9 | program will be uninterrupted or error-free. The users should understand that 10 | the program was developed for research purposes and is advised not to rely 11 | exclusively on the program for any reason. The authors shall not be liable to 12 | any kind of damages, including lost profits, arising out of the use of the 13 | program. The authors disclaim any warranties, and have no obligations to 14 | provide maintenance, support, updates, enhancements or modifications. 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Identification of GAN Generated Images 2 | 3 | This is an implementation of the paper [Identification of deep network generated images using disparities in color components](https://doi.org/10.1016/j.sigpro.2020.107616). 4 | 5 | 6 | ### Requirements 7 | - Matlab R2015b+ 8 | 9 | 10 | ### Usage 11 | Simply call the function `gan_img_detection_fea` to calculate the features proposed in the paper. 12 | ``` 13 | Fea = gan_img_detection_fea(Img) 14 | ``` 15 | 16 | Note: To train and test on a dataset, please use the code of [ensembles](http://dde.binghamton.edu/download/ensemble/) (for sample-aware and model-aware detection) / [SVM](https://www.csie.ntu.edu.tw/~cjlin/libsvm/) (for model-unaware detection) classifiers. 17 | 18 | ## Citation 19 | If you use our code please cite: 20 | ``` 21 | @article{li2020identification, 22 | title={Identification of Deep Network Generated Images Using Disparities in Color Components}, 23 | author={Li, Haodong and Li, Bin and Tan, Shunquan and Huang, Jiwu}, 24 | journal={Signal Processing}, 25 | volume = {174}, 26 | pages={107616}, 27 | year={2020}, 28 | issn = {0165-1684}, 29 | doi = {https://doi.org/10.1016/j.sigpro.2020.107616}, 30 | } 31 | ``` 32 | -------------------------------------------------------------------------------- /gan_img_detection_fea.m: -------------------------------------------------------------------------------- 1 | function F = gan_img_detection_fea(IMG) 2 | %GAN_IMG_DETECTION_FEA Extract features for detecting GAN generated images. 3 | % 4 | % Input: 5 | % - IMG: An image array or a path to the image file. 6 | % 7 | % Output: 8 | % - F: The 300-D feature for GAN generated image detection. 9 | % 10 | % The algorithm is proposed in the following paper: 11 | % @article{li2020identification, 12 | % title={Identification of Deep Network Generated Images Using Disparities in Color Components}, 13 | % author={Li, Haodong and Li, Bin and Tan, Shunquan and Huang, Jiwu}, 14 | % journal={Signal Processing}, 15 | % volume = {174}, 16 | % pages={107616}, 17 | % year={2020}, 18 | % issn = {0165-1684}, 19 | % doi = {https://doi.org/10.1016/j.sigpro.2020.107616}, 20 | % } 21 | 22 | if ischar(IMG) 23 | IMG = imread(IMG); 24 | end 25 | 26 | HSV = double(im2uint8(rgb2hsv(IMG))); 27 | YCC = double(rgb2ycbcr(IMG)); 28 | % IMG = double(IMG); 29 | 30 | F = cat(2,... % matrix_cooc_3D(IMG,true),... 31 | matrix_cooc_2D(HSV(:,:,1),true),... 32 | matrix_cooc_2D(HSV(:,:,2),true),... 33 | matrix_cooc_2D(YCC(:,:,2),true),... 34 | matrix_cooc_2D(YCC(:,:,3),true)); 35 | 36 | 37 | 38 | function F = matrix_cooc_2D(IMG,symm) 39 | I_x = IMG(2:end-1,2:end-1); 40 | I_n = {IMG(2:end-1,3:end); 41 | IMG(2:end-1,1:end-2); 42 | IMG(3:end, 2:end-1); 43 | IMG(1:end-2,2:end-1)}; 44 | 45 | clips = [-inf -2; 46 | -1 -1; 47 | 0 0; 48 | 1 1; 49 | 2 inf]; 50 | N = size(clips,1); 51 | P = zeros(N,N,N); 52 | for j = 1:length(I_n) 53 | D = I_x - I_n{j}; 54 | D_ = zeros(size(D)); 55 | for i = 1:N 56 | D_(D>=clips(i,1) & D<=clips(i,2)) = i; 57 | end 58 | 59 | D_1 = D_(:,1:end-2); 60 | D_2 = D_(:,2:end-1); 61 | D_3 = D_(:,3:end); 62 | M = zeros(N,N,N); 63 | for k = 1:numel(D_1) 64 | if symm && D_1(k)>D_3(k) 65 | M(D_3(k),D_2(k),D_1(k)) = M(D_3(k),D_2(k),D_1(k))+1; 66 | else 67 | M(D_1(k),D_2(k),D_3(k)) = M(D_1(k),D_2(k),D_3(k))+1; 68 | end 69 | end 70 | P = P+M./numel(D_1); 71 | 72 | D_1 = D_(1:end-2,:); 73 | D_2 = D_(2:end-1,:); 74 | D_3 = D_(3:end,:); 75 | M = zeros(N,N,N); 76 | for k = 1:numel(D_1) 77 | if symm && D_1(k)>D_3(k) 78 | M(D_3(k),D_2(k),D_1(k)) = M(D_3(k),D_2(k),D_1(k))+1; 79 | else 80 | M(D_1(k),D_2(k),D_3(k)) = M(D_1(k),D_2(k),D_3(k))+1; 81 | end 82 | end 83 | P = P+M./numel(D_1); 84 | end 85 | 86 | if symm 87 | P_ = false(N,N,N); 88 | for i = 1:N 89 | for j = 1:N 90 | for k = 1:N 91 | if i <= k 92 | P_(i,j,k) = 1; 93 | end 94 | end 95 | end 96 | end 97 | F = P(P_)'; 98 | else 99 | F = P(:)'; 100 | end 101 | 102 | function F = matrix_cooc_3D(IMG,symm) 103 | I_x = IMG(2:end-1,2:end-1,:); 104 | I_n = {IMG(2:end-1,3:end ,:); 105 | IMG(2:end-1,1:end-2,:); 106 | IMG(3:end, 2:end-1,:); 107 | IMG(1:end-2,2:end-1,:)}; 108 | 109 | base = 2; 110 | N = base^3; 111 | P = zeros(N,N,N); 112 | for j = 1:length(I_n) 113 | D = I_x > I_n{j}; 114 | D_= D(:,:,1)*base^0+D(:,:,2)*base^1+D(:,:,3)*base^2+1; 115 | 116 | D_1 = D_(:,1:end-2); 117 | D_2 = D_(:,2:end-1); 118 | D_3 = D_(:,3:end); 119 | M = zeros(N,N,N); 120 | for k = 1:numel(D_1) 121 | if symm && D_1(k)>D_3(k) 122 | M(D_3(k),D_2(k),D_1(k)) = M(D_3(k),D_2(k),D_1(k))+1; 123 | else 124 | M(D_1(k),D_2(k),D_3(k)) = M(D_1(k),D_2(k),D_3(k))+1; 125 | end 126 | end 127 | P = P+M./numel(D_1); 128 | 129 | D_1 = D_(1:end-2,:); 130 | D_2 = D_(2:end-1,:); 131 | D_3 = D_(3:end,:); 132 | M = zeros(N,N,N); 133 | for k = 1:numel(D_1) 134 | if symm && D_1(k)>D_3(k) 135 | M(D_3(k),D_2(k),D_1(k)) = M(D_3(k),D_2(k),D_1(k))+1; 136 | else 137 | M(D_1(k),D_2(k),D_3(k)) = M(D_1(k),D_2(k),D_3(k))+1; 138 | end 139 | end 140 | P = P+M./numel(D_1); 141 | end 142 | 143 | if symm 144 | P_ = false(N,N,N); 145 | for i = 1:N 146 | for j = 1:N 147 | for k = 1:N 148 | if i <= k 149 | P_(i,j,k) = 1; 150 | end 151 | end 152 | end 153 | end 154 | F = P(P_)'; 155 | else 156 | F = P(:)'; 157 | end --------------------------------------------------------------------------------