Fourier Transform In Image Steganography - 2

Roshan
3 min readJun 24, 2024

--

It is a continuation of part 1
if you missed check it out — PART1 (click on)

Embedding the Hidden Image

In many cases, changes in the chrominance channels are less perceptible to the human eye compared to changes in the luminance channel. Therefore, embedding information in the chrominance channels may be less noticeable to observers

The normalized hidden image is embedded into the high-frequency components of the cover image’s chrominance (a) channel.

hidden_image_normalized_high_freq = hidden_image_normalized .* high_freq_mask;
mag_a_high_freq = mag_a + hidden_image_normalized_high_freq;

This multiplies each pixel value of the normalized hidden image by the corresponding pixel value of the high-frequency mask. This operation ensures that the hidden image will be embedded primarily in the high-frequency components of the chrominance channel.

And then adds the high-frequency components of the hidden image to the magnitude spectrum of the chrominance ‘a’ channel of the cover image. This modifies the frequency representation of the cover image to include the hidden image data.

Reconstructing the Modified Chrominance Channels

  • the phase of the Fourier transform (phase_a and phase_b) contains the phase information of the original image's chrominance channels (a and b). This phase information is crucial for preserving the spatial structure of the image.
F_a_modified = mag_a_high_freq .* exp(1j * phase_a); 
F_b_modified = mag_b .* exp(1j * phase_b);

In MATLAB, exp(1j * phase) computes the complex exponential function e^jθ, where j represents the imaginary unit and θ(theta) is the phase angle.

a_modified = real(ifft2(F_a_modified)); 
b_modified = real(ifft2(F_b_modified));

After applying inverse Fourier transform we get modified chrominance a and b channel

Combining Channels and Converting Back to channel

lab_stego(:,:,1) = L; 
lab_stego(:,:,2) = a_modified;
lab_stego(:,:,3) = b_modified;
stego_image = lab2rgb(lab_stego);
  • The original luminance channel (L) is kept unchanged to preserve the overall brightness and contrast of the cover image.
  • The modified chrominance a channel (a_modified), which now includes the hidden image data, is assigned to the new Lab image.
  • The b_modified channel (or the original b if unmodified) is assigned to the new Lab image.
  • The modified Lab image is converted back to RGB, resulting in a stego image that visually appears similar to the original cover image but contains the embedded hidden image.

Extracting The hidden image

lab_stego = rgb2lab(stego_image); 
a_stego = lab_stego(:,:,2);
F_a_stego = fft2(a_stego);
mag_a_stego = abs(F_a_stego);
hidden_image_extracted = (mag_a_stego - mag_a) .* high_freq_mask;
hidden_image_extracted = mat2gray(hidden_image_extracted);

To extract the hidden image, the stego image is converted back to Lab color space, and the Fourier transform of the chrominance (a) channel is computed. The difference in the magnitudes of the stego and original chrominance channels is extracted, revealing the hidden image. The extracted image is then normalised, displayed, and saved.

Conclusion

In this application, I introduced you to a technique for image steganography, leveraging the discrete Fourier transform (DFT) in the Lab colour space. By embedding a hidden image into the high-frequency components of the chrominance channels, we successfully concealed the hidden image within the cover image while maintaining the cover image’s visual integrity.

The approach involved converting the cover image to the Lab color space, applying the Fourier transform to isolate high-frequency components, and strategically embedding the hidden image into these components. The final stego image appeared visually similar to the original cover image but contained hidden information that could be extracted using inverse operations.

THANK YOU!!!

Let me know if you need further assistance!

Linkedin: https://www.linkedin.com/in/roshantwinn09/

Github:https://github.com/Twinn-github09

--

--