Code covered by the BSD License  

Highlights from
Binary Image Watermarking/Data Hiding: Data, Algorithms, and Distortion Measure

Binary Image Watermarking/Data Hiding: Data, Algorithms, and Distortion Measure

by

 

26 Apr 2012 (Updated )

A package on binary image watermarking/data hiding, including data, algorithms & distortion measure.

fembed(ecc_col,maxflip)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function fembed(ecc_col,maxflip)
%function fembed(testimg)
%maxflip=5;
%ecc_col=5;

testimg='french-4';
%skwid=3;
blksize=8; 
%IF THIS IS NOT SATISFIED, THEN IN EMBEDDING, REVERSE SHIFTING SHOULD BE MORE COMPLICATED.

%testimg='ccitt4';%'french-4';
save Results\paras blksize testimg maxflip ecc_col
%clear all
load Results\paras
ImIn = imread(['..\test_images\',testimg,'.tif']);

[inRows, inCols]=size(ImIn);
RowsNum=double(floor(inRows/blksize));
ColsNum=double(floor(inCols/blksize));
Rows=blksize*RowsNum;
Cols=blksize*ColsNum;
Im0=zeros(Rows,Cols);%ignore rest if blocks don't fit well. Testing purpose only. Zero-padding in practice.
Im0=ImIn(1:Rows,1:Cols);

clear ImIn 

Im0=double(Im0);
h = fspecial('gaussian',5,0.7);%1);
Im0pp=ones(Rows+6,Cols+6);
Im0pp(4:(Rows+3),4:(Cols+3))=Im0;
FImgpp=filter2(h,Im0pp);
FImg=FImgpp(4:(Rows+3),4:(Cols+3));

%Watermark geneartion
nubn_blksize=mark_length(Im0,blksize,RowsNum,ColsNum,1);
disp(['There are ', num2str(nubn_blksize),' non-uniform ', num2str(blksize), 'x', num2str(blksize),' blocks out of ',num2str(RowsNum*ColsNum)]);
%ECC BCH
%ECC parameters
ecc_n=30;%6;
%ecc_col=5;%3;
ecc_paras=bchpoly(ecc_n);
ecc_n=ecc_paras(ecc_col,1);
ecc_k=ecc_paras(ecc_col,2);
codeword_num=floor(nubn_blksize/ecc_n);
wm_len=codeword_num*ecc_k;
wmecc_len=codeword_num*ecc_n;
% wmb4ecc=rand(wm_len,1);
% wmb4ecc=double(im2bw(wmb4ecc));
load wmb4ecc
wmecced=encode(wmb4ecc,ecc_n,ecc_k,'bch/binary');
data2hide=wmecced;
save Results\ecc ecc_n ecc_k
save Results\datahidden data2hide wmb4ecc
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%key initialization
key=zeros(RowsNum*ColsNum,1);

Im_1=Im0;
blkrows = 1:blksize;
blkcols = blkrows;
wk=0;
kk=0;
MaxMinDRDM=0;
biwmblk=zeros(8);
cnew=0;
for i=0:(RowsNum-1)
    for j=0:(ColsNum-1)
        blk0_0=Im0(i*blksize+blkrows, j*blksize+blkcols);
        kk=kk+1;        
        if max(max(blk0_0))~=min(min(blk0_0))          
            olddc=sum(sum(blk0_0));
            key(kk)=olddc;
            blk0=FImg(i*8+blkrows, j*8+blkcols);            
            blkmax=max(max(blk0));
            blkmin=min(min(blk0));
            
            countfb=0;
            wk=wk+1;
            if data2hide(wk)==1
                bias=0.05;                
                %Tbib=(blkmin+blkmax)*(0.5-bias*);            
            else
                bias=-0.05;                
                %Tbib=(blkmin+blkmax)*(0.5+bias);            
            end
            while countfb<20%use feedback to guarantee success and low distortion
                countfb=countfb+1;
                Tbib=(blkmin+blkmax)*(0.5-bias); 
                for ii=1:8
                    for jj=1:8
                        if blk0(ii, jj)>=Tbib
                            biwmblk(ii, jj)=1;
                        else
                            biwmblk(ii, jj)=0;
                        end
                    end
                end
                newdc=sum(sum(biwmblk));
                if newdc>=olddc && data2hide(wk)==0 %want decrease but increased, raise T
                    bias=bias*1.5;
                elseif newdc<=olddc && data2hide(wk)==1 %want to increase but decreased,lower T
                    bias=bias*1.5;
                elseif abs(newdc-olddc)>maxflip
                    bias=bias*0.5;
                else 
                    break;
                end
            end
            if (newdc<olddc && data2hide(wk)==0) || (newdc>olddc && data2hide(wk)==1)
                Im_1(i*8+blkrows, j*8+blkcols)=biwmblk;       
            else
                cnew=cnew+1;
            end
        end
        if wk==wmecc_len,   break;end;
    end
    if wk==wmecc_len,   break;end;    
end
disp(['Amount of real data hidden is ',num2str(wm_len),' bits']);
disp(['Amount of data with ECC hidden is ',num2str(wk),' bits']);
save Results\key key

embedpara=['_e_',num2str(ecc_col),'_f_',num2str(maxflip)];
imwrite(Im_1, ['Results\',testimg,'-wm',embedpara,'.tif']);
diffimg=xor(Im_1,Im0);
imwrite(diffimg,['Results\',testimg,'-dif',embedpara,'.tif']);
changednum=sum(sum(diffimg));
disp(['The number of changed pixels are ',num2str(changednum)]);
baseimg=0.8+Im0*0.2;
[diffm,diffn]=find(diffimg==1);
for i=1:changednum
    baseimg(diffm(i),diffn(i))=0;
end
imwrite(mat2gray(baseimg),['Results\',testimg,'-supdif',embedpara,'.tif']);

psnr_value=psnr(Im_1,double(Im0));
disp(['PNSR is ',num2str(psnr_value)]);
DRDM_value=CalDRDM(['..\test_images\',testimg,'.tif'],['Results\',testimg,'-wm',embedpara,'.tif'],5,nubn_blksize);
DRDM_pxlave=DRDM_value*nubn_blksize/changednum;
disp(['DRDM for the image is ',num2str(DRDM_value)]);
disp(['Average DRDM per pixel is ',num2str(DRDM_pxlave)]);

fid=fopen(['Results\',testimg,'-LOG',embedpara,'.tex'],'w');
fprintf(fid,'Document Image Name: %s',testimg);
fprintf(fid,'\nImage is of size %d x %d',Rows, Cols);
fprintf(fid,'\nThere are %d non-uniform  %d by %d, blocks out of %d blocks.',nubn_blksize,blksize,blksize,RowsNum*ColsNum);
fprintf(fid,'\nAmount of real data hidden is  %d bits',wm_len);
fprintf(fid,'\nAmount of data with ECC hidden is  %d bits',wk);
fprintf(fid,'\nThe number of changed pixels are %d pixels',changednum);
fprintf(fid,'\nPNSR is %fdB',psnr_value);
fprintf(fid,'\nDRDM for the image is %f with m = 5',DRDM_value);
fprintf(fid,'\nAverage DRDM per pixel is %f with m = 5',DRDM_pxlave);
fclose(fid);



clear all 
fextract
cropping
noises

Contact us