├── hist.m ├── plant.m ├── trans.m ├── original.png ├── .gitignore ├── Calcu.m ├── resize.m ├── Get.m ├── Put.m ├── ind2wtree.m ├── Encipher.m ├── Dec2bin.m ├── Chg2bin.m ├── Generate.m ├── Insert.m ├── Adjustment.m ├── img2gray.m ├── sub.m ├── Encode.m ├── reserve.m ├── expansion.m ├── gray.m ├── evaluate.m ├── Room.m ├── Decode.m ├── multi.m ├── Select.m ├── jpg2png.m ├── refparams_vecgsm.m ├── main.py ├── SaveSpace.m ├── Extraction.m ├── distsub_est_M.m ├── Recover.m ├── Recovery.m ├── test2.m ├── README.md ├── main.m ├── apple.m ├── Embed1.m ├── Embedding.m ├── thumbnail.m ├── ifcvec.m └── Adjust.m /hist.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RMDE/ImageEncipher/HEAD/hist.m -------------------------------------------------------------------------------- /plant.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RMDE/ImageEncipher/HEAD/plant.m -------------------------------------------------------------------------------- /trans.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RMDE/ImageEncipher/HEAD/trans.m -------------------------------------------------------------------------------- /original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RMDE/ImageEncipher/HEAD/original.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.asv 2 | test.* 3 | *.pptx 4 | *.docx 5 | *.jpg 6 | *.eps 7 | *.pdf 8 | *.png 9 | *.tmp 10 | *.txt 11 | !original.png 12 | setting.code-workspace 13 | -------------------------------------------------------------------------------- /Calcu.m: -------------------------------------------------------------------------------- 1 | %file: Calcu.m 2 | %to calculate the low (8-MSB) bit of the pixel 3 | function res = Calcu( pixel , MSB) 4 | 5 | 6 | bits = dec2bin(pixel); 7 | [~,len] = size(bits); 8 | if len < (8-MSB) 9 | res = pixel; 10 | else 11 | bits = bits(len+MSB-7:len); 12 | res = bin2dec(bits); 13 | end 14 | 15 | end -------------------------------------------------------------------------------- /resize.m: -------------------------------------------------------------------------------- 1 | for mm =1:3 2 | b=".png"; 3 | c=num2str(mm); 4 | name=strcat("eva\me",c,b) 5 | origin=imread(name,"png"); 6 | [M,N] = size(origin); 7 | AjImage = imresize(origin,2); 8 | b=".png"; 9 | c=num2str(mm); 10 | res=strcat("eva\me",c,b); 11 | imwrite(AjImage,res,'png'); 12 | end -------------------------------------------------------------------------------- /Get.m: -------------------------------------------------------------------------------- 1 | %file:Get.m 2 | %get the MSB of pixel and store it into bits 3 | function bits = Get( bits, pixel, MSB ) 4 | b = dec2bin(pixel); 5 | [~,n] = size(b); 6 | if n < 8 7 | t = b; 8 | b(1:8-n) = '0'; 9 | b(8-n+1:8) = t(1:n); 10 | end 11 | [~,len] = size(bits); 12 | b = b(1:MSB); 13 | bits(len+1:len+MSB) = b(1:MSB)-'0'; 14 | end -------------------------------------------------------------------------------- /Put.m: -------------------------------------------------------------------------------- 1 | %file: Put.m 2 | %to cover the MSB of pixel with MSB in data 3 | function cover = Put( pixel , data , infono , MSB) 4 | 5 | cover = dec2bin(pixel); 6 | [~,n] = size(cover); 7 | if n < 8 8 | t = cover; 9 | cover(1:8-n) = '0'; 10 | cover(8-n+1:8) = t(1:n); 11 | end 12 | cover(1:MSB) = data(infono:infono+MSB-1)+'0'; 13 | cover = bin2dec(cover); 14 | 15 | end -------------------------------------------------------------------------------- /ind2wtree.m: -------------------------------------------------------------------------------- 1 | function wtree = ind2wtree(pyr, ind) 2 | 3 | %this function is called by vifvec.m 4 | % converts the output of Eero Simoncelli's pyramid routines into subbands in a cell array 5 | C=pyr; 6 | S=ind; 7 | 8 | offset=0; 9 | numsubs=size(ind,1); 10 | for i=1:numsubs 11 | wtree{numsubs-i+1}=reshape(C(offset+1:offset+prod(S(i,:))), S(i,1),S(i,2)); 12 | offset=offset+prod(S(i,:)); 13 | end 14 | -------------------------------------------------------------------------------- /Encipher.m: -------------------------------------------------------------------------------- 1 | %file: Encipher.m 2 | %to encipher the image after the saving space progress 3 | %origin: the image after saving space progress 4 | %key: the sub key to generate the stream key to encipher 5 | %using key expansion function 6 | function EnImage = Encipher( origin , key ) 7 | 8 | [M,N] = size(origin); 9 | rng('default'); 10 | rng(key); 11 | stream = uint8(randi(256,M,N)-1); 12 | x = size(stream); 13 | EnImage = bitxor(origin,stream); 14 | 15 | end -------------------------------------------------------------------------------- /Dec2bin.m: -------------------------------------------------------------------------------- 1 | %file:Dec2bin.m 2 | %change from function dec2bin 3 | %adding: the solution of negative integer 4 | function bits = Dec2bin( number ) 5 | bit=[]; 6 | if number > 0 7 | bits = dec2bin(number); 8 | elseif number == 0 9 | bits = '0'; 10 | else 11 | bit = Get(bit,-number,8); 12 | for i = 1 : 8 13 | if bit(i) == 0 14 | bits(i) = '1'; 15 | else 16 | bits(i) = '0'; 17 | end 18 | end 19 | bit = bin2dec(bits); 20 | bits= dec2bin(bit+1); 21 | end 22 | end -------------------------------------------------------------------------------- /Chg2bin.m: -------------------------------------------------------------------------------- 1 | %file:Chg2bin.m 2 | %change the number ( < 128 ) to bits 3 | function bits = Chg2bin( number ) 4 | 5 | if number == 0 6 | bits = [0,0,0]; 7 | else 8 | bits(7) = rem(number,2); 9 | number = floor(number/2); 10 | bits(6) = rem(number,2); 11 | number = floor(number/2); 12 | bits(5) = rem(number,2); 13 | number = floor(number/2); 14 | bits(4) = rem(number,2); 15 | number = floor(number/2); 16 | bits(3) = rem(number,2); 17 | number = floor(number/2); 18 | bits(2) = rem(number,2); 19 | number = floor(number/2); 20 | bits(1) = rem(number,2); 21 | end 22 | 23 | end -------------------------------------------------------------------------------- /Generate.m: -------------------------------------------------------------------------------- 1 | %file: Generate.m 2 | %to generate all possible 2**MSB value 3 | %because the MSB must smaller than four, so here using enumeration to save time 4 | function number = Generate(MSB) 5 | 6 | % if MSB==1 7 | % number = [128]; 8 | % elseif MSB==2 9 | % number = [64,128,192]; 10 | % elseif MSB==3 11 | % number = [32,64,96,128,160,192,224]; 12 | 13 | if MSB == 1 14 | number = [128]; 15 | elseif MSB == 2 16 | number = [128,64]; 17 | elseif MSB == 3 18 | number = [128,64,32]; 19 | elseif MSB == 4 20 | number = [128,64,32,16]; 21 | elseif MSB == 5 22 | number = [128,64,32,16,8]; 23 | elseif MSB == 6 24 | number = [128,64,32,16,8,4]; 25 | elseif MSB == 7 26 | number = [128,64,32,16,8,4,2]; 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /Insert.m: -------------------------------------------------------------------------------- 1 | %file:Insert.m 2 | %first: encode the 'data' -- when meeting '11111111' then add a '0' in the end 3 | %second: adding '01111111110' to the end of the data 4 | function DATA = Insert( data , DATA ) 5 | 6 | [~,len] = size(data); 7 | [~,index] = size(DATA); 8 | index = index+1; 9 | temp = [1,1,1,1,1,1,1,1,0]; 10 | ending = [0,1,1,1,1,1,1,1,1,1,0]; 11 | i=1;%index of data 12 | while i <= len 13 | if (i+7)<=len 14 | if data(i:i+7)==temp(1:8) 15 | DATA(index:index+8) = temp(1:9); 16 | index = index+9; 17 | i = i+8; 18 | continue; 19 | end 20 | end 21 | DATA(index) = data(i); 22 | index = index+1; 23 | i = i+1; 24 | end 25 | DATA(index:index+10) = ending(1:11); 26 | end -------------------------------------------------------------------------------- /Adjustment.m: -------------------------------------------------------------------------------- 1 | %file: Adjustment.m 2 | %to adjust the MSB of pixel in adjustment area in order to keep the Thumbnail the same 3 | %origin: the image after saving space and encipher progress 4 | %value: store the average pixel in every block of the original image 5 | %MSB: the number of every bit in adjustment area used for adjustment 6 | function [AjImage,res] = Adjustment( origin , blocksize , value , MSB) 7 | 8 | AjImage = origin; 9 | [M,N] = size(AjImage); 10 | m = M/blocksize; 11 | n = N/blocksize; 12 | sum = 0; 13 | for i = 1 : m 14 | for j = 1 : n 15 | x = (i-1)*blocksize+1; 16 | y = (j-1)*blocksize+1; 17 | [AjImage,x] = Adjust(AjImage,blocksize,x,y,MSB,value(i,j)); 18 | sum = sum+x; 19 | end 20 | end 21 | res=double(sum/(m*n)); 22 | 23 | end -------------------------------------------------------------------------------- /img2gray.m: -------------------------------------------------------------------------------- 1 | % sum = double(0); 2 | % str = ['head\','bust\','body\']; 3 | % for sub = 2:2 4 | % a1 = 'origin\'; 5 | % a1 = strcat(a1,str(sub*5+1:(sub+1)*5)); 6 | % for mm =1:60 7 | % b=".png"; 8 | % c=num2str(mm); 9 | % name=strcat(a1,c,b); 10 | % origin=imread(name,"png"); 11 | % [m,n,p] = size(origin); 12 | % if(mod(m,128)~=0 || mod(n,128)~=0) 13 | % name 14 | % end 15 | % if (size(size(origin))== [1,3]) 16 | % gray = rgb2gray(origin); 17 | % size(gray) 18 | % imwrite(gray,name,'png'); 19 | % end 20 | % end 21 | % end 22 | % 23 | origin=imread("me.png","png"); 24 | if (size(size(origin))== [1,3]) 25 | gray = rgb2gray(origin); 26 | size(gray) 27 | imwrite(gray,"me.png",'png'); 28 | end -------------------------------------------------------------------------------- /sub.m: -------------------------------------------------------------------------------- 1 | origin = imread("dec-sub1.png","png"); 2 | subimg = imread("me.png","png"); 3 | [M,N] = size(origin); 4 | blocksize = 128; 5 | imresize(subimg,[blocksize,blocksize]); 6 | size(subimg) 7 | MSB = 2; 8 | for i = 1 :32 9 | for j = 1 :32 10 | for x = i*4-3 : i*4 11 | for y = j*4-3 : j*4 12 | subimg(x,y) = origin(i,j); 13 | end 14 | end 15 | 16 | % subimg(i,j) = origin(blocksize*2+i,j); 17 | % subimg(i,j) = origin(M-blocksize*1+i,N-blocksize+j); 18 | end 19 | end 20 | imwrite(subimg,"dec-sub1(b).png","png"); 21 | % ori = imread("dec-sub6.png","png"); 22 | % value = ori(1,1); 23 | % [M,N] = size(ori); 24 | % for i = 1 : M 25 | % ori(i,2) = unifrnd (0,255); 26 | % ori(i,N-1) = unifrnd (0,255); 27 | % end 28 | % for i = 1 : N 29 | % ori(2,i) = unifrnd (0,255); 30 | % ori(M-1,i) = unifrnd (0,255); 31 | % end 32 | % imwrite(ori,"dec-sub6.png","png"); -------------------------------------------------------------------------------- /Encode.m: -------------------------------------------------------------------------------- 1 | %file: Encode.m 2 | %using run-length code to compress the embedded message 3 | function res = Encode( data ) 4 | 5 | [~,length] = size(data); 6 | i = 1;%the index of data 7 | count = 0;%to store the number of '0' or '1' 8 | res = [];%store the compression result, every progress result in one byte and the LSB is the type of number counted('0' or '1') 9 | l = 1;%index of res 10 | flag = 0;%means the number now to calculate is '0' 11 | while i <= length 12 | if data(i)==0 13 | while i<=length && data(i)==0 && count<127 %calculate the number of '0' 14 | count = count+1; 15 | i = i+1; 16 | end 17 | flag = 0; 18 | elseif data(i)==1 19 | while i<=length && data(i)==1 && count<127 %calculate the number of '0' 20 | count = count+1; 21 | i = i+1; 22 | end 23 | flag = 1; 24 | end 25 | t = Chg2bin(count); 26 | res(l:l+6) = t(1:7); 27 | res(l+7) = flag; 28 | l = l+8; 29 | count = 0; 30 | end 31 | 32 | 33 | end -------------------------------------------------------------------------------- /reserve.m: -------------------------------------------------------------------------------- 1 | %file:SaveSpace.m 2 | %save the MSB of adjustment area pixel in order to adjust 3 | %origin: original image blocksize: size of block 4 | %MSB: the number of every bit in adjustment area used for adjustment 5 | %count: the max number of elements in EN1 6 | function [embed_image,Cap,DATA] = reserve( origin , blocksize , MSB , count, bits) 7 | 8 | embed_image = origin; 9 | [M,N] = size(origin); 10 | m = M/blocksize; 11 | n = N/blocksize; 12 | DATA = [];%store the all message of every block to embedding 13 | Cap = 0; 14 | 15 | %collecting the embedding message 16 | for i = 1 : m 17 | for j = 1 : n 18 | x = (i-1)*blocksize+1; 19 | y = (j-1)*blocksize+1; 20 | [data,embed_image,capacity] = Embed1(embed_image,blocksize,x,y,MSB,count); 21 | [~,l] = size(DATA); 22 | [~,len] = size(data); 23 | DATA(l+1:l+len) = data(1:len); 24 | Cap = Cap + capacity; 25 | end 26 | end 27 | 28 | %embedding the data to the whole image 29 | index = 1; 30 | [~,len] = size(DATA) 31 | 32 | end 33 | -------------------------------------------------------------------------------- /expansion.m: -------------------------------------------------------------------------------- 1 | %file: expansion.m 2 | %%caculate the capacity of the encrypted image using difference expansion 3 | origin = imread("result.png"); 4 | [M,N] = size(origin); 5 | blocksize = 1024; 6 | m = M/blocksize; 7 | n = N/blocksize; 8 | num = 0; 9 | for p = 1:m 10 | for q =1:n 11 | x = (p-1)*blocksize+1; 12 | y = (q-1)*blocksize+1; 13 | for i = x+1 : 1 : x+blocksize-2 14 | for j = y+1 : 2 : y+blocksize-2 15 | l = floor(double(uint16(origin(i,j))+uint16(origin(i,j+1)))/2); 16 | h = double(double(origin(i,j))-double(origin(i,j+1))); 17 | min = 2*(255-l); 18 | b = 2*l+1; 19 | if( b < min ) 20 | min = b; 21 | end 22 | if h==0 || h==-1 23 | num = num+1; 24 | elseif abs(2*h+1) < min 25 | num = num+1; 26 | elseif abs(2*floor(h/2)+1) < min 27 | num=num+1; 28 | end 29 | end 30 | end 31 | end 32 | end 33 | num 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /gray.m: -------------------------------------------------------------------------------- 1 | for no = 1 : 18 2 | name = strcat("gray\",num2str(no),".png") 3 | origin = imread(name,"png"); 4 | [M,N] = size(origin); 5 | blocksize = 16; 6 | MSB = 2; 7 | count = 3000000; 8 | key = 1; 9 | m = M/blocksize; 10 | n = N/blocksize; 11 | values = zeros(m,n);%store the original average pixel of every block 12 | sub = zeros(blocksize); 13 | for i = 1 : m 14 | for j = 1 : n 15 | x = (i-1)*blocksize+1; 16 | y = (j-1)*blocksize+1; 17 | sub(1:blocksize,1:blocksize) = origin(x:x+blocksize-1,y:y+blocksize-1); 18 | values(i,j) = mean2(sub); 19 | end 20 | end 21 | embed_image = SaveSpace( origin , blocksize , MSB , count); 22 | EnImage = Encipher( embed_image , key ); %encipher 23 | [AjImage,s] = Adjustment( EnImage , blocksize , values , MSB); 24 | % origin = imresize(origin,[768,1024]); 25 | % if (size(size(origin))== [1,3]) 26 | % origin = rgb2gray(origin); 27 | % size(origin) 28 | % end 29 | % imwrite(origin,strcat("gray\",num2str(no),".png"),"png"); 30 | imwrite(AjImage,strcat("gray-res\",num2str(no),".png"),"png"); 31 | end -------------------------------------------------------------------------------- /evaluate.m: -------------------------------------------------------------------------------- 1 | % sum = 0; 2 | % str = ['head\','bust\','body\']; 3 | % for sub = 0:2 4 | % a1 = 'origin\'; 5 | % a1 = strcat(a1,str(sub*5+1:(sub+1)*5)); 6 | % a2 = 'result2\'; 7 | % a2 = strcat(a2,str(sub*5+1:(sub+1)*5)); 8 | % for mm =1:50 9 | % b=".png"; 10 | % c=num2str(mm); 11 | % name=strcat(a1,c,b); 12 | % ori=dir(name); 13 | % size1=ori.bytes/1024/1024; 14 | % b=".png"; 15 | % c=num2str(mm); 16 | % name=strcat(a2,c,b); 17 | % res=dir(name); 18 | % size2=res.bytes/1024/1024; 19 | % x = size2/size1; 20 | % sum = sum + x; 21 | % end 22 | % avg = sum/50 23 | % sum = 0; 24 | % end 25 | 26 | %psnr 27 | sum = 0; 28 | str = ['head\','bust\','body\']; 29 | for sub = 2:2 30 | a1 = 'thumbnail\'; 31 | a1 = strcat(a1,str(sub*5+1:(sub+1)*5)); 32 | a2 = 'result2\'; 33 | a2 = strcat(a2,str(sub*5+1:(sub+1)*5)); 34 | for mm =1:60 35 | b=".png"; 36 | c=num2str(mm); 37 | name=strcat(a1,c,b); 38 | ori=imread(name,"png"); 39 | b=".png"; 40 | c=num2str(mm); 41 | name=strcat(a2,c,b); 42 | res=imread(name,"png"); 43 | x = lpips(ori,res); 44 | sum = sum + x; 45 | end 46 | avg = sum/60 47 | sum = 0; 48 | end -------------------------------------------------------------------------------- /Room.m: -------------------------------------------------------------------------------- 1 | %file:SaveSpace.m 2 | %save the MSB of adjustment area pixel in order to adjust 3 | %origin: original image blocksize: size of block 4 | %MSB: the number of every bit in adjustment area used for adjustment 5 | %count: the max number of elements in EN1 6 | function embed_image = Room( origin , blocksize , DATA) 7 | [~,len] = size(DATA); 8 | embed_image = origin; 9 | [M,N] = size(origin); 10 | m = M/blocksize; 11 | n = N/blocksize; 12 | index = 1; 13 | for i = 1 : m 14 | for j = 1 : n 15 | x = (i-1)*blocksize+1; 16 | y = (j-1)*blocksize+1; 17 | 18 | for p = x+1 : 1 : x+blocksize-2 19 | for q = y+1 : 2 : y+blocksize-2 20 | l = floor(double(uint16(embed_image(p,q))+uint16(embed_image(p,q+1)))/2); 21 | h = double(double(embed_image(p,q))-double(embed_image(p,q+1))); 22 | min = 2*(255-l); 23 | b = 2*l+1; 24 | if( b < min ) 25 | min = b; 26 | end 27 | if abs(2*floor(h/2)+1) length 34 | index2 = length; 35 | end 36 | data = []; 37 | [~,x] = size(DATA); 38 | data(1:x) = DATA(:); 39 | data(x+1:x+index2-index+1) = bits(index:index2); 40 | embed_image = Room(embed_image,blocksize,data); 41 | index = index2+1; 42 | end 43 | EnImage = Encipher( embed_image , key); %encipher 44 | [AjImage,s] = Adjustment( EnImage , blocksize , values , MSB); 45 | toc 46 | DeImage = Encipher( AjImage , key); %decipher 47 | ReImage = Recover( DeImage , blocksize , MSB); 48 | imwrite(AjImage,"reserve.png","png"); 49 | -------------------------------------------------------------------------------- /Select.m: -------------------------------------------------------------------------------- 1 | function DATA = Select(origin,blocksize,MSB) 2 | [M,N] = size(origin); 3 | m = M/blocksize; 4 | n = N/blocksize; 5 | num = 4*blocksize-4 6 | DATA = []; 7 | for p = 1 : m 8 | for q = 1 : n 9 | x = (p-1)*blocksize+1; 10 | y = (q-1)*blocksize+1; 11 | bits = []; %store the highest MSB bits of pixels in adjustment area 12 | bit = []; 13 | for i = x : x+blocksize-1 14 | bit = Get(bit,origin(i,y),MSB); 15 | end 16 | for i = x : x+blocksize-1 17 | bit = Get(bit,origin(i,y+blocksize-1),MSB); 18 | end 19 | for j = y+1 : y+blocksize-2 20 | bit = Get(bit,origin(x,j),MSB); 21 | end 22 | for j = y+1 : y+blocksize-2 23 | bit = Get(bit,origin(x+blocksize-1,j),MSB); 24 | end 25 | [~,len] = size(DATA); 26 | if MSB == 1 27 | bits=bit; 28 | DATA(len+1:len+num) = bits(:); 29 | end 30 | if MSB == 2 31 | a = 4*blocksize-4; 32 | bits(1:a) = bit(1:2:2*a-1); 33 | bits(a+1:2*a) = bit(2:2:2*a); 34 | DATA(len+1:len+num*2) = bits(:); 35 | end 36 | if MSB == 3 37 | a = 4*blocksize-4; 38 | bits(1:a) = bit(1:3:3*a-2); 39 | bits(a+1:2*a) = bit(2:3:3*a-1); 40 | bits(2*a+1:3*a) = bit(3:3:3*a); 41 | DATA(len+1:len+num*3) = bits(:); 42 | end 43 | end 44 | end 45 | DATA = Encode(DATA); 46 | size(DATA) 47 | end -------------------------------------------------------------------------------- /jpg2png.m: -------------------------------------------------------------------------------- 1 | sum = double(0); 2 | for mm =1:50 3 | a='origin\body\'; 4 | b=".jpg"; 5 | c=num2str(mm); 6 | name=strcat(a,c,b); 7 | origin=imread(name,"jpg"); 8 | 9 | a='origin\body\'; 10 | b=".png"; 11 | c=num2str(mm); 12 | res=strcat(a,c,b); 13 | imwrite(origin,res,'png'); 14 | 15 | end 16 | 17 | % for photo = 1:28 18 | % name = strcat("eva\",num2str(photo),".png"); 19 | % whole=imread(name,"png"); 20 | % res = whole; 21 | % [M,N,C] = size(whole); 22 | % blocksize = 16; 23 | % MSB = 2; 24 | % count = 20000; 25 | % key = 1; 26 | % m = M/blocksize; 27 | % n = N/blocksize; 28 | % values = zeros(m,n);%store the original average pixel of every block 29 | % origin = whole(:,:,1); 30 | % sub = zeros(blocksize); 31 | % for channel = 1 : C 32 | % origin(:,:,1) = whole(:,:,channel); 33 | % for i = 1 : m 34 | % for j = 1 : n 35 | % x = (i-1)*blocksize+1; 36 | % y = (j-1)*blocksize+1; 37 | % sub(1:blocksize,1:blocksize) = origin(x:x+blocksize-1,y:y+blocksize-1); 38 | % values(i,j) = mean2(sub); 39 | % end 40 | % end 41 | % embed_image = SaveSpace( origin , blocksize , MSB , count); 42 | % EnImage = Encipher( embed_image , key); %encipher 43 | % [AjImage,s] = Adjustment( EnImage , blocksize , values , MSB); 44 | % res(:,:,channel) = AjImage(:,:,1); 45 | % end 46 | % imwrite(res,strcat("ave\",num2str(photo),".png"),'png'); 47 | % end -------------------------------------------------------------------------------- /refparams_vecgsm.m: -------------------------------------------------------------------------------- 1 | function [ssarr, l_arr, cu_arr]=refparams_vecgsm(org,subands,M) 2 | 3 | %This function computes the parameters of the reference image. This is 4 | %called by vifvec.m. 5 | 6 | for i=1:length(subands); 7 | sub=subands(i); 8 | y=org{sub}; 9 | 10 | sizey=floor(size(y)./M)*M; % crop to exact multiple size 11 | y=y(1:sizey(1),1:sizey(2)); 12 | 13 | 14 | % Collect MxM blocks. Rearrange each block into an 15 | % M^2 dimensional vector and collect all such vectors. 16 | % Collece ALL possible MXM blocks (even those overlapping) from the subband 17 | temp=[]; 18 | for j=1:M 19 | for k=1:M 20 | temp=cat(1,temp,reshape(y(k:end-(M-k), j:end-(M-j)),1,[])); 21 | end 22 | end 23 | 24 | % estimate mean and covariance 25 | mcu=mean(temp')'; 26 | cu=((temp-repmat(mcu,1,size(temp,2)))*(temp-repmat(mcu,1,size(temp,2)))')./size(temp,2); % covariance matrix for U 27 | 28 | % Collect MxM blocks as above. Use ONLY non-overlapping blocks to 29 | % calculate the S field 30 | temp=[]; 31 | for j=1:M 32 | for k=1:M 33 | temp=cat(1,temp,reshape(y(k:M:end, j:M:end),1,[])); 34 | end 35 | end 36 | 37 | % Calculate the S field 38 | ss=(inv(cu)*temp); 39 | ss=sum(ss.*temp)./(M*M); 40 | ss=reshape(ss,sizey/M); 41 | 42 | % Eigen-decomposition 43 | [v,d]=eig(cu); 44 | l_arr(sub,:)=diag(d)'; 45 | 46 | % rearrange for output 47 | ssarr{sub}=ss; 48 | temp=0; 49 | d=diag(d); 50 | cu_arr{sub}=cu; 51 | end 52 | 53 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import lpips 2 | 3 | 4 | class util_of_lpips(): 5 | def __init__(self, net, use_gpu=False): 6 | ''' 7 | Parameters 8 | ---------- 9 | net: str 10 | 抽取特征的网络,['alex', 'vgg'] 11 | use_gpu: bool 12 | 是否使用GPU,默认不使用 13 | Returns 14 | ------- 15 | References 16 | ------- 17 | https://github.com/richzhang/PerceptualSimilarity/blob/master/lpips_2imgs.py 18 | 19 | ''' 20 | ## Initializing the model 21 | self.loss_fn = lpips.LPIPS(net=net) 22 | self.use_gpu = use_gpu 23 | if use_gpu: 24 | self.loss_fn.cuda() 25 | 26 | def calc_lpips(self, img1_path, img2_path): 27 | ''' 28 | Parameters 29 | ---------- 30 | img1_path : str 31 | 图像1的路径. 32 | img2_path : str 33 | 图像2的路径. 34 | Returns 35 | ------- 36 | dist01 : torch.Tensor 37 | 学习的感知图像块相似度(Learned Perceptual Image Patch Similarity, LPIPS). 38 | 39 | References 40 | ------- 41 | https://github.com/richzhang/PerceptualSimilarity/blob/master/lpips_2imgs.py 42 | 43 | ''' 44 | # Load images 45 | img0 = lpips.im2tensor(lpips.load_image(img1_path)) # RGB image from [-1,1] 46 | img1 = lpips.im2tensor(lpips.load_image(img2_path)) 47 | 48 | if self.use_gpu: 49 | img0 = img0.cuda() 50 | img1 = img1.cuda() 51 | dist01 = self.loss_fn.forward(img0, img1) 52 | return dist01 53 | a = util_of_lpips('vgg') 54 | sum1 = float(0) 55 | for i in range(60): 56 | file1 = "D:/Project/ImageEncipher/thumbnail/body/"+str(i+1)+".png" 57 | file2 = "D:/Project/ImageEncipher/result2/body/"+str(i+1)+".png" 58 | d = a.calc_lpips(file1,file2) 59 | sum1 += float(d) 60 | print(sum1/60) 61 | -------------------------------------------------------------------------------- /SaveSpace.m: -------------------------------------------------------------------------------- 1 | %file:SaveSpace.m 2 | %save the MSB of adjustment area pixel in order to adjust 3 | %origin: original image blocksize: size of block 4 | %MSB: the number of every bit in adjustment area used for adjustment 5 | %count: the max number of elements in EN1 6 | function embed_image = SaveSpace( origin , blocksize , MSB , count) 7 | 8 | embed_image = origin; 9 | [M,N] = size(origin); 10 | m = M/blocksize; 11 | n = N/blocksize; 12 | DATA = [];%store the all message of every block to embedding 13 | Cap = 0; 14 | 15 | %collecting the embedding message 16 | for i = 1 : m 17 | for j = 1 : n 18 | x = (i-1)*blocksize+1; 19 | y = (j-1)*blocksize+1; 20 | [data,embed_image,capacity] = Embedding(embed_image,blocksize,x,y,MSB,count); 21 | DATA = Insert(data,DATA); 22 | Cap = Cap + capacity; 23 | end 24 | end 25 | 26 | %embedding the data to the whole image 27 | index = 1; 28 | [~,len] = size(DATA) 29 | Cap 30 | for i = 1 : m 31 | for j = 1 : n 32 | x = (i-1)*blocksize+1; 33 | y = (j-1)*blocksize+1; 34 | 35 | for p = x+1 : 1 : x+blocksize-2 36 | for q = y+1 : 2 : y+blocksize-2 37 | l = floor(double(uint16(embed_image(p,q))+uint16(embed_image(p,q+1)))/2); 38 | h = double(double(embed_image(p,q))-double(embed_image(p,q+1))); 39 | min = 2*(255-l); 40 | b = 2*l+1; 41 | if( b < min ) 42 | min = b; 43 | end 44 | if abs(2*floor(h/2)+1) 1 78 | b = uint32(board(t-1)); 79 | end 80 | data(1:a-b) = mess(b+1:a); 81 | ReImage = Extraction(ReImage,blocksize,x,y,MSB,data); 82 | end 83 | end 84 | 85 | 86 | end -------------------------------------------------------------------------------- /Recovery.m: -------------------------------------------------------------------------------- 1 | %file: Recovery.m 2 | %to recover the image 3 | %origin: the image after decipher progress 4 | %blocksize: size of block 5 | %MSB: the number of every bit in adjustment area used for adjustment 6 | function ReImage = Recovery( origin , blocksize , MSB ) 7 | 8 | ReImage = origin; 9 | [M,N] = size(origin); 10 | m = M/blocksize; 11 | n = N/blocksize; 12 | %divide all pixel into two different sets: CH & NC 13 | %(whether it is changable) 14 | %CH: EZ & EN & CN --- changable 15 | %NC: not changable 16 | DATA = zeros(1,((blocksize-2)*(blocksize-2))/2*m*n);%store the embedded message 17 | no = 0; %means the number of elements in data 18 | for i = 1 : m 19 | for j = 1 : n 20 | x = (i-1)*blocksize+1; 21 | y = (j-1)*blocksize+1; 22 | 23 | for p = x+1 : 1 : x+blocksize-2 24 | for q = y+1 : 2 : y+blocksize-2 25 | l = floor((origin(p,q)+origin(p,q+1))/2); 26 | h = double(double(origin(p,q))-double(origin(p,q+1))); 27 | min = 2*(255-l); 28 | b = 2*l+1; 29 | if b < min 30 | min = b; 31 | end 32 | if abs(2*floor(h/2)+1) < min %changable 33 | no = no+1; 34 | a = Dec2bin(h); 35 | [~,len] = size(a); 36 | DATA(no) = a(len)-'0'; %the lowest of h is the embedded message 37 | end 38 | end 39 | end 40 | end 41 | end 42 | 43 | 44 | %calculate every block's data according to the DATA 45 | board =zeros(1,m*n); 46 | mess = zeros(1,((blocksize-2)*(blocksize-2))/2*m*n); 47 | j = 1;%index of board 48 | i = 1;%index of DATA 49 | no = 1;%index of mess 50 | temp = [1,1,1,1,1,1,1,1,0]; 51 | ending = [0,1,1,1,1,1,1,1,1,1,0]; 52 | 53 | while j <= m*n 54 | if DATA(i:i+10) == ending(1:11) 55 | board(j) = no-1; 56 | j = j+1; 57 | i = i+11; 58 | elseif DATA(i:i+8) == temp(1:9) 59 | mess(no:no+7) = temp(1:8); 60 | no = no+8; 61 | i = i+9; 62 | else 63 | mess(no) = DATA(i); 64 | no = no+1; 65 | i = i+1; 66 | end 67 | end 68 | 69 | b = 0; 70 | for i = 1 : m 71 | for j = 1 : n 72 | data = []; 73 | x = (i-1)*blocksize+1; 74 | y = (j-1)*blocksize+1; 75 | t = (i-1)*m+j; 76 | a = uint32(board(t)); 77 | if t > 1 78 | b = uint32(board(t-1)); 79 | end 80 | data(1:a-b) = mess(b+1:a); 81 | ReImage = Extraction(ReImage,blocksize,x,y,MSB,data); 82 | end 83 | end 84 | 85 | 86 | end -------------------------------------------------------------------------------- /test2.m: -------------------------------------------------------------------------------- 1 | % % x = imread("origin-th.png","png"); 2 | % % y = imread("thumbnail.png","png"); 3 | % % [M,N] = size(x); 4 | % % dif = double(0); 5 | % % for i = 1:M 6 | % % for j = 1:N 7 | % % p = double(x(i,j)); 8 | % % q = double(y(i,j)); 9 | % % s = double(abs(p-q)); 10 | % % dif = dif + s/double(x(i,j)); 11 | % % end 12 | % % end 13 | % % dif = dif/double((M*N)) 14 | % 15 | % %file: main.m 16 | % %%the main function of the project 17 | % whole = imread("apple.png","png"); 18 | % [M,N,C] = size(whole); 19 | % blocksize = 32; 20 | % MSB = 2; 21 | % count = 20000; 22 | % key = 1; 23 | % m = M/blocksize; 24 | % n = N/blocksize; 25 | % values = zeros(m,n);%store the original average pixel of every block 26 | % sub1 = zeros(blocksize); 27 | % sub2 = zeros(blocksize); 28 | % for chanal = 1 : C 29 | % origin = whole(:,:,chanal); 30 | % for i = 1 : m 31 | % for j = 1 : n 32 | % x = (i-1)*blocksize+1; 33 | % y = (j-1)*blocksize+1; 34 | % sub1(1:blocksize,1:blocksize) = origin(x:x+blocksize-1,y:y+blocksize-1); 35 | % values(i,j) = mean2(sub1); 36 | % end 37 | % end 38 | % 39 | % embed_image = SaveSpace( origin , blocksize , MSB , count); 40 | % EnImage = Encipher( embed_image , key); %encipher 41 | % [AjImage,s] = Adjustment( EnImage , blocksize , values , MSB); 42 | % whole(:,:,chanal) = AjImage(:,:); 43 | % end 44 | % imwrite(whole,"apple-res.png","png"); 45 | % 46 | % 47 | 48 | 49 | % Img=imread('dream\dream-.png'); 50 | % BW = Img; 51 | % R=BW(:,:,1); 52 | % [REDcounts,x] = imhist(R); 53 | % G=BW(:,:,2); 54 | % [Greencounts,y] = imhist(R); 55 | % B=BW(:,:,3); 56 | % [Bluecounts,z] = imhist(R); 57 | % figure; 58 | % subplot(131);imhist(R);title('Red'); 59 | % subplot(132);imhist(G);title('Green'); 60 | % subplot(133);imhist(B);title('Blue'); 61 | 62 | %file: main.m 63 | %%the main function of the project 64 | for pic = 1:20 65 | whole = imread(strcat("temp\",num2str(pic),".jpeg"),"jpeg"); 66 | [M,N,C] = size(whole); 67 | blocksize = 16; 68 | MSB = 2; 69 | count = 20000; 70 | key = 1; 71 | m = M/blocksize; 72 | n = N/blocksize; 73 | values = zeros(m,n);%store the original average pixel of every block 74 | for chanal = 1 : C 75 | origin = whole(:,:,chanal); 76 | for i = 1 : m 77 | for j = 1 : n 78 | x = (i-1)*blocksize+1; 79 | y = (j-1)*blocksize+1; 80 | sub1(1:blocksize,1:blocksize) = origin(x:x+blocksize-1,y:y+blocksize-1); 81 | values(i,j) = mean2(sub1); 82 | end 83 | end 84 | 85 | embed_image = SaveSpace( origin , blocksize , MSB , count); 86 | EnImage = Encipher( embed_image , key); %encipher 87 | [AjImage,s] = Adjustment( EnImage , blocksize , values , MSB); 88 | whole(:,:,chanal) = AjImage(:,:); 89 | end 90 | 91 | imwrite(whole,strcat("temp\res-",num2str(pic),".png"),"png"); 92 | end 93 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 基于差分扩展的缩略图保持加密技术 2 | ## 环境配置 3 | - matlab 4 | ## 基本原理 5 | - 以块为单位,将块分为调整区和嵌入区,利用差分扩展将调整区中的像素的MSB嵌入嵌入区,加密后通过改变调整区像素的MSB使块平均像素与原始平均像素值基本一致从而达到缩略图保持。 6 | ## 应用场景 7 | - 云端的图片保存等 8 | ## 具体步骤 9 | ### 一.腾空间 10 | #### 对块进行处理 11 | 1. 记录调整区的MSB 12 | 2. 对嵌入区的像素进行分类 13 | - 每两个像素为一组 14 | - 计算两个像素之间的平均值以及差值 15 | - l = [x+y]/2 16 | - h = x-y 17 | - 通过判断 |2*h+b| , |2*[h/2]+b| 与 min(2(255-l),2l+1) 之间的关系,从而对每组像素进行分类 18 | - EZ :h=0 || h=-1 19 | - EN : |2*h+b| <= min(2(255-l), 2l+1) 即可拓展集合 20 | - CN : |2*[h/2]+b| <= min(2(255-l), 2l+1 即可变集合 21 | - NC : 不满足上述两个条件,即不可变区 22 | - 考虑到空间因素,将EN分为EN1和EN2两部分一部分作为可拓展部分,一部分作为可变部分 23 | 3. 生成待嵌入数据 24 | - locate-map用于标记可拓展像素组 25 | - 对属于EN2和CN集合的像素组的h的LSB部分进行收集(h=1 || h=-2时不用记录) 26 | - 调整区的MSB部分 27 | - (若MSB>1,则将每个像素的同一位一起保存,例如将每个像素的最高位收集在一起,然后将次高位收集存在所有最高位之后) 28 | - 将locate-map以及MSB部分进行游程编码来进行压缩 29 | - 整合为块嵌入数据: data = Encode(locate-map) + LSB + Encode(MSB) 30 | 4. 进行预备工作 31 | - 对于可拓展像素组 32 | - h' = 2*h 33 | - 对于可变像素组 34 | - h' = 2*[h/2] 35 | - x' = l+[(h'+1)/2] 36 | - y' = l-[h'/2] 37 | #### 对图像整体进行处理 38 | 5. 整合待嵌入数据 39 | - 对块内得到的数据信息进行编码,这里采用的是当遇到连续8个‘1’时,在后面加上‘0’ 40 | - 对块与块数据之间插入分隔符‘01111111110’用于区别 41 | 6. 对图像整体进行数据嵌入 42 | - 通过判断 |2*[h/2]+b| 与 min(2(255-l),2l+1) 之间的关系,从而对每组像素进行分类 43 | - CH :|2*[h/2]+b| <= min(2(255-l), 2l+1 即可变集合 44 | - NC :不可变区 45 | - 对于可变像素组 46 | - h' = h+b (b为待嵌入比特) 47 | - 若数据已经嵌入完成,则不再进行嵌入操作 48 | - x' = l+[(h'+1)/2] 49 | - y' = l-[h'/2] 50 | ### 二.加密 51 | - 此处用简单的流加密方式进行加密,当然可以采用更安全的加密方式(包括会改变像素位置的加密方式,但一定要记录可调整区像素位置用于调整) 52 | ### 三.调整 53 | - 通过不断改变调整区像素的MSB,找出所有可能中最接近于原图像块平均像素的一组数据(即遍历查找) 54 | ### 四.解密 55 | - 此处和加密一致,直接将加密过程用于解密即可 56 | ### 五.提取 57 | #### 对图像整体进行处理 58 | 1. 将嵌入区的像素组分类 59 | - 两个像素一组 60 | - 计算两个像素之间的平均值以及差值 61 | - l = [x+y]/2 62 | - hh = x-y 63 | - 通过判断 |2*[h/2]+b| 与 min(2(255-l),2l+1) 之间的关系,从而对每组像素进行分类 64 | - CH :|2*[h/2]+b| <= min(2(255-l), 2l+1 即可变集合 65 | - NC :不可变区 66 | 2. 可变集合CH中的hh的LSB位即为嵌入的信息 67 | 3. 对提取的信息进行解码,并根据分隔符将整体嵌入信息分解为各个块的嵌入信息 68 | #### 对块进行处理 69 | 4. 计算出嵌入信息各组成部分压缩前的大小 70 | - locate-map:(blocksize-2)*(blocksize-2)/2 71 | - MSB:blocksize*4-4 72 | - LSB:size(data) - size(locate-map) - size(MSB) 73 | 5. 对经过压缩的嵌入数据进行还原 74 | - 从data的首部开始:边还原MAP边对已经还原的MAP元素个数进行计算,当达到locate-map原大小时停止 75 | - 从data的尾部开始:边还原MSB边对已经还原的MSB元素个数进行计算,当达到MSB原大小时停止 76 | - 两部分中间的即为LSB部分 77 | 6. 将嵌入区的像素组分类 78 | - 两个像素一组 79 | - 计算两个像素之间的平均值以及差值 80 | - l = [x+y]/2 81 | - hh = x-y 82 | - 通过判断 |2*[h/2]+b| 与 min(2(255-l),2l+1) 之间的关系,从而对每组像素进行分类 83 | - CH :|2*[h/2]+b| <= min(2(255-l), 2l+1 即可变集合 84 | - NC :不可变区 85 | 7. 对可变区的像素进行还原 86 | - 对于属于EZ & EN1的像素组(即locate-map中值为1): h = [hh/2] 87 | - 0 <= hh <= 1: h = 1 88 | - 12 <= hh <= -1: h = -2 89 | - else: h = 2*[hh/2]+LSB 90 | - x = l+[(h+1)/2] 91 | - y = l-[h/2] 92 | 8. 对调整区像素进行还原 93 | - pixel = pixel(8-MSB)+MSB -------------------------------------------------------------------------------- /main.m: -------------------------------------------------------------------------------- 1 | %file: main.m 2 | %%the main function of the project 3 | origin = imread("original.png",'png'); 4 | [M,N] = size(origin); 5 | blocksize = 16; 6 | MSB = 2; 7 | count = 20000; 8 | key = 1; 9 | m = M/blocksize; 10 | n = N/blocksize; 11 | values = zeros(m,n);%store the original average pixel of every block 12 | sub1 = zeros(blocksize); 13 | sub2 = zeros(blocksize); 14 | sub3 = zeros(blocksize); 15 | for i = 1 : m 16 | for j = 1 : n 17 | x = (i-1)*blocksize+1; 18 | y = (j-1)*blocksize+1; 19 | sub1(1:blocksize,1:blocksize) = origin(x:x+blocksize-1,y:y+blocksize-1); 20 | values(i,j) = mean2(sub1); 21 | end 22 | end 23 | tic 24 | embed_image = SaveSpace( origin , blocksize , MSB , count); 25 | EnImage = Encipher( embed_image , key); %encipher 26 | [AjImage,s] = Adjustment( EnImage , blocksize , values , MSB); 27 | toc 28 | DeImage = Encipher( AjImage , key); %decipher 29 | ReImage = Recovery( DeImage , blocksize , MSB); 30 | for i = 1 : 1 : M 31 | for j = 1 : 1 : N 32 | if origin(i,j) ~= ReImage(i,j) 33 | i,j 34 | break; 35 | end 36 | end 37 | end 38 | imwrite(embed_image,"room.png","png"); 39 | imwrite(EnImage,"cipher.png",'png'); 40 | imwrite(AjImage,"result.png",'png'); 41 | imwrite(DeImage,"decipher.png","png"); 42 | imwrite(ReImage,'recover.png','png'); 43 | % res_values = zeros(m,n);%store the original average pixel of every block 44 | % for i = 1 : m 45 | % for j = 1 : n 46 | % x = (i-1)*blocksize+1; 47 | % y = (j-1)*blocksize+1; 48 | % sub(1:blocksize,1:blocksize) = AjImage(x:x+blocksize-1,y:y+blocksize-1); 49 | % res_values(i,j) = mean2(sub); 50 | % end 51 | % end 52 | % 53 | % %caculate the difference between origin image and AjImage 54 | % sum = 0; 55 | % for i = 1 : m 56 | % for j = 1 : n 57 | % t = abs(res_values(i,j)-values(i,j)); 58 | % if t <= 5 59 | % sum = sum+1; 60 | % end 61 | % end 62 | % end 63 | % % difference = sum/(m*n) 64 | % result1 = origin; 65 | % result2 = origin; 66 | % % result3 = origin; 67 | % for i = 1 : m 68 | % for j = 1 : n 69 | % x = (i-1)*blocksize+1; 70 | % y = (j-1)*blocksize+1; 71 | % sub1(1:blocksize,1:blocksize) = AjImage(x:x+blocksize-1,y:y+blocksize-1); 72 | % sub2(1:blocksize,1:blocksize) = origin(x:x+blocksize-1,y:y+blocksize-1); 73 | % sub3(1:blocksize,1:blocksize) = EnImage(x:x+blocksize-1,y:y+blocksize-1); 74 | % value1 = mean2(sub1); 75 | % value2 = mean2(sub2); 76 | % value3 = mean2(sub3); 77 | % for p = x : x+blocksize-1 78 | % for q = y : y+blocksize-1 79 | % result1(p,q) = value1; 80 | % result2(p,q) = value2; 81 | % % result3(p,q) = value3; 82 | % end 83 | % end 84 | % end 85 | % end 86 | % imwrite(result1,"thumbnail.png",'png'); 87 | % imwrite(result2,"origin-th.png",'png'); 88 | % imwrite(result3,"cipher-th.png","png"); 89 | 90 | -------------------------------------------------------------------------------- /apple.m: -------------------------------------------------------------------------------- 1 | %file: apple.m 2 | %to encrypt the apple image 3 | whole = imread("apple.png","png"); 4 | [M,N,C] = size(whole); 5 | blocksize = 16; 6 | MSB = 2; 7 | count = 20000; 8 | key = 1; 9 | m = M/blocksize; 10 | n = N/blocksize; 11 | values = zeros(m,n);%store the original average pixel of every block 12 | sub1 = zeros(blocksize); 13 | result1 = whole; 14 | result2 = whole; 15 | for chanal = 1 : C 16 | origin = whole(:,:,chanal); 17 | for i = 1 : m 18 | for j = 1 : n 19 | x = (i-1)*blocksize+1; 20 | y = (j-1)*blocksize+1; 21 | sub1(1:blocksize,1:blocksize) = origin(x:x+blocksize-1,y:y+blocksize-1); 22 | values(i,j) = mean2(sub1); 23 | end 24 | end 25 | 26 | embed_image = SaveSpace( origin , blocksize , MSB , count); 27 | EnImage = Encipher( embed_image , key); %encipher 28 | [AjImage,s] = Adjustment( EnImage , blocksize , values , MSB); 29 | whole(:,:,chanal) = AjImage(:,:,1); 30 | end 31 | imwrite(whole,"apple-res.png","png"); 32 | 33 | for chanal = 1 : C 34 | for i = 1 : m 35 | for j = 1 : n 36 | x = (i-1)*blocksize+1; 37 | y = (j-1)*blocksize+1; 38 | sub1(1:blocksize,1:blocksize) = whole(x:x+blocksize-1,y:y+blocksize-1,chanal); 39 | value1 = mean2(sub1); 40 | for p = x : x+blocksize-1 41 | for q = y : y+blocksize-1 42 | result1(p,q,chanal) = value1; 43 | end 44 | end 45 | end 46 | end 47 | end 48 | imwrite(result1,"thumbnail.png","png"); 49 | 50 | 51 | % for mm = 1 : 1 : 6 52 | % name = strcat("trump\",char(mm+'0'),".jpg"); 53 | % whole = imread(name,"jpg"); 54 | % [M,N,C] = size(whole); 55 | % blocksize = 16; 56 | % MSB = 2; 57 | % count = 20000; 58 | % key = 1; 59 | % m = M/blocksize; 60 | % n = N/blocksize; 61 | % values = zeros(m,n);%store the original average pixel of every block 62 | % sub1 = zeros(blocksize); 63 | % result1 = whole; 64 | % result2 = whole; 65 | % for chanal = 1 : C 66 | % origin = whole(:,:,chanal); 67 | % for i = 1 : m 68 | % for j = 1 : n 69 | % x = (i-1)*blocksize+1; 70 | % y = (j-1)*blocksize+1; 71 | % sub1(1:blocksize,1:blocksize) = origin(x:x+blocksize-1,y:y+blocksize-1); 72 | % values(i,j) = mean2(sub1); 73 | % end 74 | % end 75 | % 76 | % embed_image = SaveSpace( origin , blocksize , MSB , count); 77 | % EnImage = Encipher( embed_image , key); %encipher 78 | % [AjImage,s] = Adjustment( EnImage , blocksize , values , MSB); 79 | % whole(:,:,chanal) = AjImage(:,:,1); 80 | % end 81 | % name_res = strcat("trump\",char(mm+'0'),".png"); 82 | % imwrite(whole,name_res,"png"); 83 | % for chanal = 1 : C 84 | % for i = 1 : m 85 | % for j = 1 : n 86 | % x = (i-1)*blocksize+1; 87 | % y = (j-1)*blocksize+1; 88 | % sub1(1:blocksize,1:blocksize) = whole(x:x+blocksize-1,y:y+blocksize-1,chanal); 89 | % value1 = mean2(sub1); 90 | % for p = x : x+blocksize-1 91 | % for q = y : y+blocksize-1 92 | % result1(p,q,chanal) = value1; 93 | % end 94 | % end 95 | % end 96 | % end 97 | % end 98 | % name_res = strcat("trump\th_",char(mm+'0'),".png"); 99 | % imwrite(result1,name_res,"png"); 100 | % end -------------------------------------------------------------------------------- /Embed1.m: -------------------------------------------------------------------------------- 1 | %file:Embedding.m 2 | %origin: the original image blocksize: the size of block 3 | %x,y: the start location of block 4 | %MSB: the number of every bit in adjustment area used for adjustment 5 | %count: the max number of elements in EN1 6 | function [data,SubImage,capacity] = Embedding( origin, blocksize, x, y, MSB, count, bits) 7 | SubImage=origin; 8 | capacity = 0; 9 | %select the highest MSB bits of each pixel in adjustment area 10 | 11 | %1-divide all pixel into different sets: EZ & EN1 & EN2 & CN & NC 12 | %2-generate the lacation-map MAP 13 | %3-store the lowest bit of each pixel in EN2 and CN 14 | %EZ: h=0 || h=-1 used as expandable 15 | %EN1: expandable and used as expandable 16 | %EN2: expandable but used as changable 17 | %CN: changable and used as changable 18 | %NC: not changable and never use 19 | SORT = zeros(blocksize,blocksize);%to store the kind of the pixel NC: 0; EZ&EN1: 1; EN2&CN: 2; 20 | MAP = zeros(blocksize-2,(blocksize-2)/2);%MAP: store the location map to tell which pixel used as expandable 21 | LSB = [];%LSB: store the lowest bit of each pixel used as changable 22 | sum = 0; %calculate the number of elements in EN1 at present 23 | num = 0; %store the size of P 24 | for i = x+1 : 1 : x+blocksize-2 25 | for j = y+1 : 2 : y+blocksize-2 26 | l = floor(double(uint16(origin(i,j))+uint16(origin(i,j+1)))/2); 27 | h = double(double(origin(i,j))-double(origin(i,j+1))); 28 | min = 2*(255-l); 29 | b = 2*l+1; 30 | if( b < min ) 31 | min = b; 32 | end 33 | if h==0 || h==-1 34 | SORT(i-x,j-y) = 1; 35 | MAP(i-x,floor((j-y+1)/2)) = 1; 36 | elseif abs(2*h+1) < min 37 | if sum < count 38 | SORT(i-x,j-y) = 1; 39 | MAP(i-x,floor((j-y+1)/2)) = 1; 40 | sum = sum+1; 41 | else 42 | SORT(i-x,j-y) = 2; 43 | t = Dec2bin(h); 44 | if h~=1 && h~=-2 45 | num=num+1; 46 | [~,len]=size(t); 47 | LSB(num) = t(len)-'0'; 48 | end 49 | end 50 | elseif abs(2*floor(h/2)+1) < min 51 | SORT(i-x,j-y) = 2; 52 | t = Dec2bin(h); 53 | if h~=1 && h~=-2 %as such value could br determined by location map 54 | num=num+1; 55 | [~,len]=size(t); 56 | LSB(num) = t(len)-'0'; 57 | end 58 | end 59 | end 60 | end 61 | %encoding the MAP into L (using 01111110 as the ending of the data) 62 | %when meet five and more than five '1' ,use 0 in the ending of '11111' 63 | L = []; 64 | MAP=MAP'; 65 | MAP=MAP(:); 66 | MAP=MAP'; %to change the MAP to unidimensional matrix 67 | 68 | %embedding bit in L & LSB $ bits into embedding area: EZ & EN1 & EN2 & CN 69 | %in EZ & EN1: the h`=2*h+bit 70 | %in EN2 & CN: the h`=2*(h/2)+bit 71 | %l=(x+y)/2 h=x-y (as x and y are two pixel's value) 72 | %x`=l+(h`+1)/2 y`=l-(h`)/2 73 | %if there are more than len bits spare space, we embed 01111...1 in the end 74 | data=[]; 75 | MAP = Encode(MAP); 76 | [~,len1] = size(MAP); 77 | data(1:len1) = MAP(1:len1); 78 | [~,len2] = size(LSB); 79 | data(len1+1:len1+len2) = LSB(1:len2); 80 | 81 | no=1; %means the index of data to embed 82 | 83 | for i = x+1 : 1 : x+blocksize-2 84 | for j = y+1 : 2 : y+blocksize-2 85 | if SORT(i-x,j-y) == 0 86 | continue; 87 | end 88 | l = floor(double(uint16(origin(i,j))+uint16(origin(i,j+1)))/2); 89 | h = double(double(origin(i,j))-double(origin(i,j+1))); 90 | if SORT(i-x,j-y) == 1 %expandable 91 | hh = 2*h; 92 | capacity = capacity+1; 93 | elseif SORT(i-x,j-y) == 2 %changable 94 | hh = 2*floor(h/2); 95 | capacity = capacity+1; 96 | else 97 | hh = h; 98 | end 99 | no = no+1; 100 | SubImage(i,j) = uint8(l+floor((hh+1)/2)); 101 | SubImage(i,j+1) = uint8(l-floor(hh/2)); 102 | end 103 | end 104 | 105 | 106 | end -------------------------------------------------------------------------------- /Embedding.m: -------------------------------------------------------------------------------- 1 | %file:Embedding.m 2 | %origin: the original image blocksize: the size of block 3 | %x,y: the start location of block 4 | %MSB: the number of every bit in adjustment area used for adjustment 5 | %count: the max number of elements in EN1 6 | function [data,SubImage,capacity] = Embedding( origin, blocksize, x, y, MSB, count) 7 | SubImage=origin; 8 | capacity = 0; 9 | %select the highest MSB bits of each pixel in adjustment area 10 | bits = []; %store the highest MSB bits of pixels in adjustment area 11 | bit = []; 12 | for i = x : x+blocksize-1 13 | bit = Get(bit,origin(i,y),MSB); 14 | end 15 | for i = x : x+blocksize-1 16 | bit = Get(bit,origin(i,y+blocksize-1),MSB); 17 | end 18 | for j = y+1 : y+blocksize-2 19 | bit = Get(bit,origin(x,j),MSB); 20 | end 21 | for j = y+1 : y+blocksize-2 22 | bit = Get(bit,origin(x+blocksize-1,j),MSB); 23 | end 24 | if MSB == 1 25 | bits=bit; 26 | end 27 | if MSB == 2 28 | a = 4*blocksize-4; 29 | bits(1:a) = bit(1:2:2*a-1); 30 | bits(a+1:2*a) = bit(2:2:2*a); 31 | end 32 | if MSB == 3 33 | a = 4*blocksize-4; 34 | bits(1:a) = bit(1:3:3*a-2); 35 | bits(a+1:2*a) = bit(2:3:3*a-1); 36 | bits(2*a+1:3*a) = bit(3:3:3*a); 37 | end 38 | %1-divide all pixel into different sets: EZ & EN1 & EN2 & CN & NC 39 | %2-generate the lacation-map MAP 40 | %3-store the lowest bit of each pixel in EN2 and CN 41 | %EZ: h=0 || h=-1 used as expandable 42 | %EN1: expandable and used as expandable 43 | %EN2: expandable but used as changable 44 | %CN: changable and used as changable 45 | %NC: not changable and never use 46 | SORT = zeros(blocksize,blocksize);%to store the kind of the pixel NC: 0; EZ&EN1: 1; EN2&CN: 2; 47 | MAP = zeros(blocksize-2,(blocksize-2)/2);%MAP: store the location map to tell which pixel used as expandable 48 | LSB = [];%LSB: store the lowest bit of each pixel used as changable 49 | sum = 0; %calculate the number of elements in EN1 at present 50 | num = 0; %store the size of P 51 | for i = x+1 : 1 : x+blocksize-2 52 | for j = y+1 : 2 : y+blocksize-2 53 | l = floor(double(uint16(origin(i,j))+uint16(origin(i,j+1)))/2); 54 | h = double(double(origin(i,j))-double(origin(i,j+1))); 55 | min = 2*(255-l); 56 | b = 2*l+1; 57 | if( b < min ) 58 | min = b; 59 | end 60 | if h==0 || h==-1 61 | SORT(i-x,j-y) = 1; 62 | MAP(i-x,floor((j-y+1)/2)) = 1; 63 | elseif abs(2*h+1) < min 64 | if sum < count 65 | SORT(i-x,j-y) = 1; 66 | MAP(i-x,floor((j-y+1)/2)) = 1; 67 | sum = sum+1; 68 | else 69 | SORT(i-x,j-y) = 2; 70 | t = Dec2bin(h); 71 | if h~=1 && h~=-2 72 | num=num+1; 73 | [~,len]=size(t); 74 | LSB(num) = t(len)-'0'; 75 | end 76 | end 77 | elseif abs(2*floor(h/2)+1) < min 78 | SORT(i-x,j-y) = 2; 79 | t = Dec2bin(h); 80 | if h~=1 && h~=-2 %as such value could br determined by location map 81 | num=num+1; 82 | [~,len]=size(t); 83 | LSB(num) = t(len)-'0'; 84 | end 85 | end 86 | end 87 | end 88 | %encoding the MAP into L (using 01111110 as the ending of the data) 89 | %when meet five and more than five '1' ,use 0 in the ending of '11111' 90 | L = []; 91 | MAP=MAP'; 92 | MAP=MAP(:); 93 | MAP=MAP'; %to change the MAP to unidimensional matrix 94 | 95 | %embedding bit in L & LSB $ bits into embedding area: EZ & EN1 & EN2 & CN 96 | %in EZ & EN1: the h`=2*h+bit 97 | %in EN2 & CN: the h`=2*(h/2)+bit 98 | %l=(x+y)/2 h=x-y (as x and y are two pixel's value) 99 | %x`=l+(h`+1)/2 y`=l-(h`)/2 100 | %if there are more than len bits spare space, we embed 01111...1 in the end 101 | data=[]; 102 | MAP = Encode(MAP); 103 | [~,len1] = size(MAP); 104 | data(1:len1) = MAP(1:len1); 105 | [~,len2] = size(LSB); 106 | data(len1+1:len1+len2) = LSB(1:len2); 107 | bits = Encode(bits); 108 | [~,len3] = size(bits); 109 | data(len1+len2+1:len1+len2+len3) = bits(1:len3); 110 | no=1; %means the index of data to embed 111 | 112 | for i = x+1 : 1 : x+blocksize-2 113 | for j = y+1 : 2 : y+blocksize-2 114 | if SORT(i-x,j-y) == 0 115 | continue; 116 | end 117 | l = floor(double(uint16(origin(i,j))+uint16(origin(i,j+1)))/2); 118 | h = double(double(origin(i,j))-double(origin(i,j+1))); 119 | if SORT(i-x,j-y) == 1 %expandable 120 | hh = 2*h; 121 | capacity = capacity+1; 122 | elseif SORT(i-x,j-y) == 2 %changable 123 | hh = 2*floor(h/2); 124 | capacity = capacity+1; 125 | else 126 | hh = h; 127 | end 128 | no = no+1; 129 | SubImage(i,j) = uint8(l+floor((hh+1)/2)); 130 | SubImage(i,j+1) = uint8(l-floor(hh/2)); 131 | end 132 | end 133 | 134 | 135 | end -------------------------------------------------------------------------------- /thumbnail.m: -------------------------------------------------------------------------------- 1 | % for photo = 1:28 2 | % name = strcat("eva\flower(64,2)",".png"); 3 | % origin = imread(name,"png"); 4 | % [M,N,C] = size(origin); 5 | % blocksize = 64; 6 | % m = M/blocksize; 7 | % n = N/blocksize; 8 | % values = 0;%store the original average pixel of every block 9 | % sub = zeros(blocksize); 10 | % result = origin; 11 | % for channel = 1 : C 12 | % for i = 1 : m 13 | % for j = 1 : n 14 | % x = (i-1)*blocksize+1; 15 | % y = (j-1)*blocksize+1; 16 | % sub(1:blocksize,1:blocksize) = origin(x:x+blocksize-1,y:y+blocksize-1,channel); 17 | % values = mean2(sub); 18 | % for p = x : x+blocksize-1 19 | % for q = y : y+blocksize-1 20 | % result(p,q,channel) = values; 21 | % end 22 | % end 23 | % end 24 | % end 25 | % end 26 | % res = strcat("eva/t-flower(64,2)",".png"); 27 | % imwrite(result,res,'png'); 28 | % end 29 | 30 | 31 | blocksize = 8; 32 | sum = double(0); 33 | difference = double(0); 34 | str = ['head\','bust\','body\']; 35 | for subx = 2:2 36 | a1 = 'origin\'; 37 | a1 = strcat(a1,str(subx*5+1:(subx+1)*5)); 38 | a2 = 'thumbnail\'; 39 | a2 = strcat(a2,str(subx*5+1:(subx+1)*5)); 40 | for mm =1:60 41 | b=".png"; 42 | c=num2str(mm); 43 | name=strcat(a1,c,b); 44 | origin=imread(name,"png"); 45 | [M,N] = size(origin); 46 | m = M/blocksize; 47 | n = N/blocksize; 48 | sub = zeros(blocksize); 49 | result = origin; 50 | for i = 1 : m 51 | for j = 1 : n 52 | x = (i-1)*blocksize+1; 53 | y = (j-1)*blocksize+1; 54 | sub(1:blocksize,1:blocksize) = origin(x:x+blocksize-1,y:y+blocksize-1); 55 | values = mean2(sub); 56 | for p = x : x+blocksize-1 57 | for q = y : y+blocksize-1 58 | result(p,q) = values; 59 | end 60 | end 61 | end 62 | end 63 | b=".png"; 64 | c=num2str(mm); 65 | res=strcat(a2,c,b); 66 | imwrite(result,res,'png'); 67 | end 68 | end 69 | 70 | sum = double(0); 71 | difference = double(0); 72 | str = ['head\','bust\','body\']; 73 | for subx = 2:2 74 | a1 = 'result\'; 75 | a1 = strcat(a1,str(subx*5+1:(subx+1)*5)); 76 | a2 = 'result2\'; 77 | a2 = strcat(a2,str(subx*5+1:(subx+1)*5)); 78 | for mm =1:60 79 | b=".png"; 80 | c=num2str(mm); 81 | name=strcat(a1,c,b); 82 | origin=imread(name,"png"); 83 | [M,N] = size(origin); 84 | m = M/blocksize; 85 | n = N/blocksize; 86 | sub = zeros(blocksize); 87 | result = origin; 88 | for i = 1 : m 89 | for j = 1 : n 90 | x = (i-1)*blocksize+1; 91 | y = (j-1)*blocksize+1; 92 | sub(1:blocksize,1:blocksize) = origin(x:x+blocksize-1,y:y+blocksize-1); 93 | values = mean2(sub); 94 | for p = x : x+blocksize-1 95 | for q = y : y+blocksize-1 96 | result(p,q) = values; 97 | end 98 | end 99 | end 100 | end 101 | b=".png"; 102 | c=num2str(mm); 103 | res=strcat(a2,c,b); 104 | imwrite(result,res,'png'); 105 | end 106 | end 107 | % 108 | % sum = double(0); 109 | % difference = double(0); 110 | % str = ['head\','bust\','body\']; 111 | % level = double(0); 112 | % level2 = double(0); 113 | % for subx = 2:2 114 | % a1 = 'thumbnail\'; 115 | % a1 = strcat(a1,str(subx*5+1:(subx+1)*5)); 116 | % a2 = 'result2\'; 117 | % a2 = strcat(a2,str(subx*5+1:(subx+1)*5)); 118 | % for mm =1:60 119 | % b=".png"; 120 | % c=num2str(mm); 121 | % name=strcat(a1,c,b); 122 | % x=imread(name,"png"); 123 | % name2=strcat(a2,c,b); 124 | % y=imread(name2,"png"); 125 | % level = level + ssim(x,y); 126 | % level2 = level2 + psnr(x,y); 127 | % % [M,N] = size(x); 128 | % % dif = double(0); 129 | % % for i = 1:M 130 | % % for j = 1:N 131 | % % p = double(x(i,j)); 132 | % % q = double(y(i,j)); 133 | % % s = double(abs(p - q)); 134 | % % if( p == 0 ) 135 | % % % p = 1; 136 | % % continue; 137 | % % end 138 | % % dif = dif + s/double(p); 139 | % % end 140 | % % end 141 | % % dif = dif/double(M*N); 142 | % % level = level + dif; 143 | % end 144 | % end 145 | % level = level/60.0 146 | % level2 = level2/60.0 147 | 148 | % whole = imread("flower.png","png"); 149 | % [M,N,C] = size(whole); 150 | % blocksize =16; 151 | % MSB = 2; 152 | % count = 20000; 153 | % key = 1; 154 | % m = M/blocksize; 155 | % n = N/blocksize; 156 | % values = zeros(m,n);%store the original average pixel of every block 157 | % sub1 = zeros(blocksize); 158 | % sub2 = zeros(blocksize); 159 | % result1 = whole; 160 | % for chanal = 1:C 161 | % for i = 1 : m 162 | % for j = 1 : n 163 | % x = (i-1)*blocksize+1; 164 | % y = (j-1)*blocksize+1; 165 | % sub1(1:blocksize,1:blocksize) = whole(x:x+blocksize-1,y:y+blocksize-1,chanal); 166 | % value1 = mean2(sub1); 167 | % for p = x : x+blocksize-1 168 | % for q = y : y+blocksize-1 169 | % result1(p,q,chanal) = value1; 170 | % end 171 | % end 172 | % end 173 | % end 174 | % end 175 | % imwrite(result1,"thumbnail.png","png"); 176 | % % imwrite(result1,"ave.png","png"); -------------------------------------------------------------------------------- /ifcvec.m: -------------------------------------------------------------------------------- 1 | function ifc=ifcvec(imorg,imdist); 2 | 3 | 4 | % -----------COPYRIGHT NOTICE STARTS WITH THIS LINE------------ 5 | % Copyright (c) 2005 The University of Texas at Austin 6 | % All rights reserved. 7 | % 8 | % Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy, 9 | % modify, and distribute this code (the source files) and its documentation for 10 | % any purpose, provided that the copyright notice in its entirety appear in all copies of this code, and the 11 | % original source of this code, Laboratory for Image and Video Engineering (LIVE, http://live.ece.utexas.edu) 12 | % at the University of Texas at Austin (UT Austin, 13 | % http://www.utexas.edu), is acknowledged in any publication that reports research using this code. The research 14 | % is to be cited in the bibliography as: 15 | % 16 | % H. R. Sheikh, A. C. Bovik, and G. de Veciana, "An Information Fidelity Criterion for Image 17 | % Quality Assessment Using Natural Scene Statistics," IEEE Transactios on Image Processing, in publication, May 2005. 18 | % 19 | % 20 | % IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT AUSTIN BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, 21 | % OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS DATABASE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF TEXAS 22 | % AT AUSTIN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | % 24 | % THE UNIVERSITY OF TEXAS AT AUSTIN SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE DATABASE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, 26 | % AND THE UNIVERSITY OF TEXAS AT AUSTIN HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 27 | % 28 | % -----------COPYRIGHT NOTICE ENDS WITH THIS LINE------------ 29 | % 30 | %This is an implementation of the algorithm for calculating the 31 | %Information Fidelity Criterion (IFC) between two images. Please refer 32 | %to the following paper: 33 | % 34 | % H. R. Sheikh, A. C. Bovik, and G. de Veciana, "An Information Fidelity Criterion for Image 35 | % Quality Assessment Using Natural Scene Statistics," IEEE Transactios on Image Processing, in publication, May 2005. 36 | %Download manuscript draft from http://live.ece.utexas.edu in the 37 | %Publications link 38 | % 39 | %This implementation is slightly differnet from the one used to report 40 | %results in the paper above. The modification have to do with using more 41 | %subands than those used in the paper, better handling of image boundaries, 42 | %and a window that automatically resizes itself based on the scale. 43 | % 44 | %Report bugfixes and comments to hamid.sheikh@ieee.org 45 | % 46 | %---------------------------------------------------------------------- 47 | % Prerequisites: The Steerable Pyramid toolbox. Available at 48 | % http://www.cns.nyu.edu/~lcv/software.html 49 | % 50 | %Input : (1) img1: The reference image 51 | % (2) img2: The distorted image (order is important) 52 | % 53 | %Output: (1) The Information Fidelity between the two images 54 | 55 | %Default Usage: 56 | % Given 2 test images img1 and img2, whose dynamic range is 0-255 57 | % 58 | % ifc = ifcvec(img1, img2); 59 | % 60 | %Advanced Usage: 61 | % Users may want to modify the parameters in the code. 62 | % (1) MxM is the block size that denotes the size of a vector used in the 63 | % GSM model. 64 | % (2) subbands included in the computation 65 | %======================================================================== 66 | 67 | M=3; 68 | subbands=[4 7 10 13 16 19 22 25]; 69 | 70 | % Do wavelet decomposition. This requires the Steerable Pyramid. You can 71 | % use your own wavelet as long as the cell arrays org and dist contain 72 | % corresponding subbands from the reference and the distorted images 73 | % respectively. 74 | [pyr,pind] = buildSpyr(imorg, 4, 'sp5Filters', 'reflect1'); % compute transform 75 | org=ind2wtree(pyr,pind); % convert to cell array 76 | [pyr,pind] = buildSpyr(imdist, 4, 'sp5Filters', 'reflect1'); 77 | dist=ind2wtree(pyr,pind); 78 | 79 | % calculate the parameters of the distortion channel 80 | [g_all,vv_all]=distsub_est_m(org,dist,subbands,M); 81 | 82 | % calculate the parameters of the reference image 83 | [ssarr, larr, cuarr]=refparams_vecgsm(org,subbands,M); 84 | 85 | % reorder subbands. This is needed since the outputs of the above functions 86 | % are not in the same order 87 | vvtemp=cell(1,max(subbands)); 88 | ggtemp=vvtemp; 89 | for(kk=1:length(subbands)) 90 | vvtemp{subbands(kk)}=vv_all{kk}; 91 | ggtemp{subbands(kk)}=g_all{kk}; 92 | end 93 | 94 | 95 | % compute reference and distorted image information from each subband 96 | for i=1:length(subbands) 97 | sub=subbands(i); 98 | g=ggtemp{sub}; 99 | vv=vvtemp{sub}; 100 | ss=ssarr{sub}; 101 | lambda = larr(sub,:);, 102 | cu=cuarr{sub}; 103 | 104 | % how many eigenvalues to sum over. default is 1. 105 | neigvals=1; 106 | 107 | % compute the size of the window used in the distortion channel estimation, and use it to calculate the offset from subband borders 108 | % we do this to avoid all coefficients that may suffer from boundary 109 | % effects 110 | lev=ceil((sub-1)/6); 111 | winsize=2^lev+1; offset=(winsize-1)/2; 112 | offset=ceil(offset/M); 113 | 114 | 115 | % select only valid portion of the output. 116 | g=g(offset+1:end-offset,offset+1:end-offset); 117 | vv=vv(offset+1:end-offset,offset+1:end-offset); 118 | ss=ss(offset+1:end-offset,offset+1:end-offset); 119 | 120 | 121 | %IFC 122 | temp1=0; temp2=0; 123 | for j=1:length(lambda) 124 | temp1=temp1+sum(sum((log2(1+g.*g.*ss.*lambda(j)./(vv+1e-10))))); % IFC for the i'th subband. tolerence for zero variance 125 | end 126 | num(i)=temp1; 127 | 128 | end 129 | 130 | % compuate IFC and normalize to size of the image 131 | ifc=sum(num)/prod(size(imorg)); 132 | 133 | -------------------------------------------------------------------------------- /Adjust.m: -------------------------------------------------------------------------------- 1 | %file: Adjust.m 2 | %to adjust the MSB of pixel in adjustment area in order to keep the Thumbnail the same 3 | %origin: the image after saving space and encipher progress 4 | %(x,y): the start location of block 5 | %value: store the average pixel in every block of the original image 6 | %MSB: the number of every bit in adjustment area used for adjustment 7 | function [AjImage,success] = Adjust(origin,blocksize,x,y,MSB,value) 8 | 9 | %first: calculate the low (8-MSB) bit of all pixel --> sum 10 | %store the all adjustment area location in locationx and locationy 11 | AjImage = origin; 12 | success = 1; 13 | locationx = []; 14 | locationy = []; 15 | len = 1; 16 | success=0; 17 | locationx(len:len+blocksize-1) = x:x+blocksize-1; 18 | locationy(len:len+blocksize-1) = y; 19 | len = len+blocksize; 20 | locationx(len:len+blocksize-1) = x:x+blocksize-1; 21 | locationy(len:len+blocksize-1) = y+blocksize-1; 22 | len = len+blocksize; 23 | locationx(len:len+blocksize-3) = x; 24 | locationy(len:len+blocksize-3) = y+1:y+blocksize-2; 25 | len = len+blocksize-2; 26 | locationx(len:len+blocksize-3) = x+blocksize-1; 27 | locationy(len:len+blocksize-3) = y+1:y+blocksize-2; 28 | len = len+blocksize-3; 29 | sub = origin(x+1:x+blocksize-2,y+1:y+blocksize-2); 30 | Sum = double(sum(sub(:))); 31 | for i = 1 : len 32 | t = Calcu(origin(locationx(i),locationy(i)),MSB); 33 | Sum = Sum+double(t); 34 | end 35 | [~,limit] = size(locationx); 36 | for i = 1 : limit 37 | AjImage(locationx(i),locationy(i)) = Calcu(origin(locationx(i),locationy(i)),MSB); 38 | end 39 | diff = blocksize*blocksize*value - Sum; 40 | if diff < 0 41 | return ; 42 | end 43 | number = Generate(MSB); 44 | [~,count] = size(number); 45 | chan = zeros(1,count); 46 | for i = 1 : count 47 | res = floor(diff / number(i)); 48 | if res > limit 49 | res = limit; 50 | end 51 | chan(i) = res; 52 | diff = diff - res * number(i); 53 | if diff < 0 54 | break; 55 | end 56 | end 57 | 58 | for j = 1 : count 59 | for i = 1 : chan(j) 60 | AjImage(locationx(i),locationy(i)); 61 | AjImage(locationx(i),locationy(i)) = AjImage(locationx(i),locationy(i)) + number(j); 62 | AjImage(locationx(i),locationy(i)); 63 | end 64 | end 65 | sub = AjImage(x:x+blocksize-1,y:y+blocksize-1); 66 | s = double(sum(sub(:))); 67 | difference = abs(s-blocksize*blocksize*value); 68 | end 69 | 70 | 71 | % %second: calculate the difference between 'current' and blocksize*blocksize*value 72 | % number = Generate(MSB); 73 | % difference = blocksize*blocksize*value-Sum %generally the former must bigger than the later 74 | % 75 | % %third: search to find the perfect result 76 | % if difference