În transmiterea informației e util să putem trimite un mesaj secret, iar pentru aceasta trebuie să folosim diverse tehnici de codificare. Este, de asemenea, util să trimitem informație care aparent să nu conțină un mesaj ascuns. Steganografia presupune ascunderea unui mesaj sub forma de text, imagine, videoclip în cadrul altui mesaj sub forma text, imagine sau videoclip.
În acest laborator vom vedea cum putem transmite o imagine secretă, ascunsă în cadrul altei imagini (denumită imagine de transport).
Pentru a exemplifica tehnica, vom ascunde o imagine gri, de dimensiuni mai mici în cadrul unei imagini color mai mari. Pentru aceasta vom urma metoda descrisă aici: https://www.researchgate.net/publication/269705199_Digital_Image_Steganography_An_FFT_Approach
În mare, metoda constă în a calcula spectrul imaginii de trasnsport și a înlocui o parte dintre coeficienții Fourier cu valorile pixelilor imaginii secrete. Vom investiga ce coeficienți sunt mai potriviți pentru a fi înlocuiți, astfel încât imaginea transmisă să nu prezinte zgomot evident și astfel încât imaginea secretă să reziste, să fie invariantă la modificări ușoare ale imaginii transmise.
Primul lucru pe care îl vom investiga este importanța modulului și a fazei coeficienților Fourier (complecși). Fiecare coeficient din spectrul Fourier $s \in S$ este un număr complex $s \in \mathbb{C}$ cu o magnitudine $|s|$ și o fază: $e^{i\phi}$ astfel încât: $s = a + i \cdot b = |s| \cdot e^{i \phi}$ .
Pentru aceasta:
Vom observa că informația este păstrată în principal în una dintre cele 2, așa că putem să schimbăm cealaltă variantă înlocuind-o cu valorile imaginii pe care vrem să o ascundem.
Descărcați imaginea de aici: imagine. Pentru a decodifica imaginea ascunsă, citiți imaginea cu 'imread' și scrieți o funcție după urmatorii pași:
Scrieți o funcție care primește două imagini gri (două matrici), o imaginea secretă și o imagine de transport de cel puțin două ori mai mare și codifică imaginea secretă în spectrul imaginii de transport.
Urmați următorii pași:
Vrem să codificăm într-o imagine color o imagine gri sau mai multe. Pentru aceasta am putea codifica în fiecare dintre cele 3 canale RGB o imagine secretă. Pentru a avea totuși o imagine stego rezultată fară prea mult zgomot cauzat de encodarea imaginilor secrete vom avea altă abordare. Vom converti imaginea RGB în alt spațiu de culoare L*a*b, un spațiu de culoare cu 3 canale: L pentru luminanță care reprezintă majoritatea informației (echivalent cu imaginile gri cu care am lucrat până acum) și 2 canale de culoare a și b. Dacă modificăm doar canalele de culoare imaginea finală se modifică mult mai puțin sesizabil pentru un om, față de cazul în care modificăm canalele RGB sau Luminanța. De aceea vom encoda o singură imagine secretă (aceeași) în canalele a și b, lucrând cu ele individual ca și cum ar fi poze gri.
Folosind scheletul următor și funcțiile scrise precedent codificați o imagine gri într-o imagine color.
close all clear all height0 = 240; width0 = 320; height = 1 * height0; width = 1 * width0; %% citire % citim imaginea de transport si o convertim din spatiul de culoare RGB in % spatiul L*a*b* img = imread('sky.jpg'); img = imresize(img, [4 * height0 + 1, 4 * width0 + 1]); h = figure , image(img) title('imagine originala') print(h, '-dpng', 'steganography_imagine_originala.png'); img_lab = double(rgb2lab(img)) / 255; h = figure , image(img_lab) title('imagine originala in spatiul l*a*b') %citim imaginea secreta si o convertim in gri hid_img = imread('dog.jpeg'); hid_img = imresize(hid_img, [height,width]); hid_img = double(rgb2gray(hid_img)) / 255; h = figure, imshow(hid_img); title('imagine secreta') %% encodare stego_a = encode_hidden_image(img_lab(:,:,2), hid_img); stego_b = encode_hidden_image(img_lab(:,:,3), hid_img); figure, imagesc(stego_a); title('stego a') stego = img_lab; stego(:,:,2) = stego_a; stego(:,:,3) = stego_b; stego_rgb = lab2rgb(stego * 255); savefile = 'steno_img.bmp' % imwrite(stego_rgb,'stego_rgn.jpeg','jpeg','Mode','lossless','BitDepth',12); imwrite(stego_rgb,savefile,'bmp'); %% decodare stego_rgb_read = imread(savefile); h = figure , image(stego_rgb_read); title('imagine stego') stego_jpeg = double(rgb2lab(stego_rgb_read))/255; figure, imagesc(log(abs(fft2(stego_jpeg(:,:,2))))); hid1 = decode_stegano_image(stego_jpeg(:,:,2)); hid2 = decode_stegano_image(stego_jpeg(:,:,3)); hid = (hid1 + hid2) / 2; figure, imshow(hid);impixelinfo title('imagine secretă recuperată')
Vrem să verificăm cât de robustă este metoda noastră de codificare. Pentru aceasta obținem imaginea stego prin codificarea imaginii secrete în imaginea de transport, efectuăm diverse transformări pe aceasta și verificăm dacă imaginea secretă este încă prezentă.
Verificați următoarele transformări pe imaginea stego: