Watermark Image with MATLAB

I write down this article intentionally just to remind me that I used to made my first MATLAB based application couple years ago. I was researched about image watermarking technique at that time. The manual documentation related to it, I found somewhere over the internet and I was too curious to try it by my self.

Watermarking is a kind of common cryptography procedure to protect the owner file copyright. It supposed to support various of multimedia files such still images, videos and audio files. However, the process overview it self are quite simple, just embedding the original file with another key file refer to your digital signing. But, don’t ask about the programming. It’s so damn hard since you have to produce the result file which have similar quality as the original’s. Well, I am not planning to accept this kind of project again for the future…ever!

Why MATLAB? MATLAB are known as the scientist programming tool. It’s both analyze feature and simulation is great. You can find your self the standard example within the MATLAB setup, it is awesome anyway. The watermarking technique implementing matrix operation and mapping the source snap which has supported widely by the MATLAB. It’s overall composition to re-generate the watermark technique was the answer why I used this tool.

The core of watermarking should equipped with 2 main procedures such encode and decode. Encode functioned to embed the watermark file while decode is the reverse way back to the original file. These both procedures completely wrote down below:

clear; % ambil gambar watermark global file_watermark wmark = imread([file_watermark]); wmark = double(wmark); [M,N] = size(wmark); wmarkv = wmark(1,:); for i=2:M, wmarkv = [wmarkv wmark(i,:)];end; % set random # generator rand('state',13); % bangkitkan permutasi acak vektor indp = randperm(M*N); % bangkitkan vector wmark for i = 1:length(indp), wmarkvs(i) = wmarkv(indp(i));end; clear wmarkv indp; % gabung ke dalam gambar watermark for i=1:M, wmarks(i,:) = wmarkvs((i-1)*N+1:i*N);end; clear wmarkvs; % ambil gambar host global file_host host = imread([file_host]); %host = host(:,101:612); imwrite(host,gray(256),'original.jpg','quality',100); host = double(host); hostr = zeros(size(host)); % hitung nilai NOP dari variabel count dan Ctemp count = 0; Ctemp = 100; % nilai minimum perubahan block (value picked arbitrarily) - EDITABLE!!! Cmin = 1; % nilai alpha (value arbitrary) - EDITABLE!!! alpha = 0.1; [O,P] = size(host); % set random generator lagi rand('state',11); % bangkitkan baris embed acak dari watermark indrow = randperm(O/4); % set random generator lagi rand('state',7); % bangkitkan kolom embed acak dari watermark indcol = randperm(P/4); % set rand# generator ke keadaan random delta rand('state',sum(100*clock)); for i=1:P/4, for j=1:O/4, % bit yang akan diembed bit = wmarks(i,j); % baris/kolom dalam kotak blok target host irow = indrow(i)-1; icol = indcol(j)-1; rlo=4*irow+1; rhi=4*irow+4; clo=4*icol+1; chi=4*icol+4; blockv = [host(rlo,clo:chi) host(rlo+1,clo:chi) host(rlo+2,clo:chi) host(rlo+3,clo:chi)]; % ambil nilai mean, min, dan max gmean = sum(blockv)/16; gmax = max(blockv); gmin = min(blockv); % set nilai contrast blok Cb = max(Cmin,alpha*(gmax-gmin)); % potong kotak-kotak pixel diatas dan dibawah nilai mean lo = find(blockv <= gmean); hi = find(blockv > gmean); % ambil nilai region atas dan bawah means mlo = sum(blockv(lo))/length(blockv(lo)); mhi = sum(blockv(hi))/length(blockv(hi)); % vektor dari pixel blok target blockvr = zeros(size(blockv)); % algoritma embedding for k = 1:length(blockv), % perubahan nilai bit random delta = rand*Cb; if bit == 1, if blockv(k) > mhi, blockvr(k)=gmax; elseif (blockv(k) >= mlo) & (blockv(k) <> else blockvr(k) = blockv(k) + delta; end; end; if bit == 0, if blockv(k) <> elseif (blockv(k) >= gmean) & (blockv(k) <> else blockvr(k) = blockv(k) - delta; end; end; end; % gambar rekonstruksi host dengan bit yang terembed hostr(rlo:rhi,clo:chi) = [blockvr(1:4); blockvr(5:8); blockvr(9:12); blockvr(13:16)]; end; end; clear indrow indcol irow icol block blockr blockv blockvr gmean gmax gmin mhi mlo; clear bit Cb Cmin alpha delta hi lo M N O P i j k rlo rhi clo chi wmarks; % output-output: figure(1);clf; imshow(host,[0 255],'truesize');title('Gambar Original'); %figure('Position',[100 100 size(host,2) size(host,1)]); %image(host); set(gca,'Position',[0 0 1 1]) figure(2);clf; imshow(hostr,[0,255],'truesize');title('Gambar Hasil Rekonstruksi - opsi : truesize'); %figure('Position',[100 100 size(hostr,2) size(hostr,1)]); %image(hostr); set(gca,'Position',[0 0 1 1]) imwrite(hostr,gray(256),'hasil.bmp'); diff = hostr-host; average = mean(mean(diff)); mini = min(min(diff)) maxi = max(max(diff)) range = maxi-mini; diff = 255*(diff-mini)/range; results = [range average Ctemp count] figure(3);clf; imshow(diff,[0 255],'notruesize');title('Gambar Hasil Rekonstruksi - opsi : notruesize'); clear range average Ctemp count mini maxi; host = uint8(host); hostr = uint8(hostr); hdiff = uint8(diff); wmark = uint8(wmark); save 'encdata1' host wmark hdiff; save 'encdata2' hostr;
clear; load encdata1; %loading host and watermark data load encdata2; %loading host and watermark data clear hdiff; num = 10; wmarkr = zeros([size(wmark) num]); wdiff = zeros(size(wmarkr)); host = double(host); [O,P] = size(host); [M,N] = size(wmark); wmark = double(wmark); for tiddle=1:num, name = ['ho' num2str(tiddle)]; load(name); h = double(h); rand('state',11); %resetting rand#gen to state for decoding of watermark bit positions in host indrow = randperm(O/4); %row/column indices rand('state',7); indcol = randperm(P/4); wmarksr = zeros(O/4,P/4); for i=1:P/4, for j=1:O/4, irow = indrow(i)-1; icol = indcol(j)-1; blocko = host( 4*irow+1:4*irow+4,4*icol+1:4*icol+4 ); blockn = h( 4*irow+1:4*irow+4,4*icol+1:4*icol+4 ); sumo = sum(sum(blocko)); sumn = sum(sum(blockn)); if sumn <> elseif sumn >= sumo, wmarksr(i,j) = 1; end; end; end; clear h blocko blockn i j icol indcol irow indrow sumo sumn; wmarkvrs = wmarksr(1,:); %building the recovered, scrambled watermark vector for descrambling for i=2:M, wmarkvrs = [wmarkvrs wmarksr(i,:)];end; clear wmarksr; rand('state',13); %resetting the seed for the random # generator indd = randperm(M*N); %recovering the random index vector for descrambling wmarkvr = zeros(size(wmarkvrs)); for i=1:length(indd), wmarkvr(indd(i)) = wmarkvrs(i);end; %inverse scrambling operation clear wmarkvrs indd; %this loop reconstructs the wmark image from the decoded/descrambled wmark vector for i=1:M, wmarkr(i,:,tiddle) = wmarkvr((i-1)*N+1:i*N);end; clear i wmarkvr; diff = wmark-wmarkr(:,:,tiddle); wdiff(:,:,tiddle) = abs(diff); end; clear host name num M N O P tiddle; figure(13);clf; subplot(5,1,1);imshow(wmark,'notruesize');title('Original'); subplot(5,2,3);imshow(wmarkr(:,:,1),'notruesize');title('Straight'); subplot(5,2,4);imshow(wdiff(:,:,1),'notruesize');title('Diff'); subplot(5,2,5);imshow(wmarkr(:,:,2),'notruesize');title('Lowpass'); subplot(5,2,6);imshow(wdiff(:,:,2),'notruesize'); subplot(5,2,7);imshow(wmarkr(:,:,3),'notruesize');title('Median'); subplot(5,2,8);imshow(wdiff(:,:,3),'notruesize'); subplot(5,2,9);imshow(wmarkr(:,:,4),'notruesize');title('Scaled'); subplot(5,2,10);imshow(wdiff(:,:,4),'notruesize'); figure(14);clf; subplot(5,1,1);imshow(wmark,'notruesize');title('Original'); subplot(5,2,3);imshow(wmarkr(:,:,5),'notruesize');title('JPEG, 100'); subplot(5,2,4);imshow(wdiff(:,:,5),'notruesize');title('Diff'); subplot(5,2,5);imshow(wmarkr(:,:,6),'notruesize');title('JPEG, 75'); subplot(5,2,6);imshow(wdiff(:,:,6),'notruesize'); subplot(5,2,7);imshow(wmarkr(:,:,7),'notruesize');title('JPEG, 50'); subplot(5,2,8);imshow(wdiff(:,:,7),'notruesize'); subplot(5,2,9);imshow(wmarkr(:,:,8),'notruesize');title('JPEG, 25'); subplot(5,2,10);imshow(wdiff(:,:,8),'notruesize'); figure(15);clf; subplot(311);imshow(wmark,'notruesize');title('Original'); subplot(323);imshow(wmarkr(:,:,9),'notruesize');title('Cropped'); subplot(324);imshow(wdiff(:,:,9),'notruesize');title('Diff'); subplot(325);imshow(wmarkr(:,:,10),'notruesize');title('Rotated'); subplot(326);imshow(wdiff(:,:,10),'notruesize'); wmarkr = uint8(255*wmarkr); wdiff = uint8(255*wdiff); save 'decdata' wmarkr wdiff;
This is the original file

This is the watermark file

And this is the result


Eko Wahyudiharto
PS: If you've benefit from this blog,
you can support it by making a small contribution.

Enter your email address:

Delivered by FeedBurner

Post a Comment Bookmark and Share


  1. Anonymous Anonymous said,

    Thursday, November 16, 2006 4:46:00 PM

    hi,apa makna simbol <> dalam matlab code dibawah?

    elseif (blockv(k) >= mlo) & (blockv(k) <>
    else blockvr(k) = blockv(k) + delta;
    if bit == 0, if blockv(k) <> elseif (blockv(k) >= gmean) & (blockv(k) <> else blockvr(k) = blockv(k) - delta;

  2. Blogger Eko Wahyudiharto said,

    Friday, November 17, 2006 8:15:00 AM

    elseif (blockv(k) >= mlo) & (blockv(k) <>
    else blockvr(k) = blockv(k) + delta;
    if bit == 0, if blockv(k) <> elseif (blockv(k) >= gmean) & (blockv(k) <> else blockvr(k) = blockv(k) - delta;

    Wah... jeli juga ya? Source ini memang "sengaja" di-begini-kan. You know what i mean lah...

Post a Comment

Leave comments here...