I am embedding audio into an DICOM Image using DCT Method .But after extraction am not able to extract the original Audio.

2 views (last 30 days)
% Embed and Extract Audio using DCT-based Steganography in DICOM Image
% Read the DICOM image file
dicomInfo = dicominfo('ID_0000_AGE_0060_CONTRAST_1_CT.dcm'); % Replace with your DICOM image file
Error using dicom_getFileDetails
Unable to load file "ID_0000_AGE_0060_CONTRAST_1_CT.dcm".

Error in dicominfo (line 20)
fileDetails = dicom_getFileDetails(filename);
dicomImage = dicomread(dicomInfo);
% Read the audio file
[audio, sampleRate] = audioread('original_audio.wav'); % Replace with your audio file
% Normalize audio to the range of -1 to 1
audio = audio / max(abs(audio));
% Get the number of audio samples
numSamples = numel(audio);
% Flatten the DICOM image into a single column vector
dicomVector = double(dicomImage(:));
% Calculate the maximum number of audio samples that can be hidden in the image
maxSamples = numel(dicomVector);
% Check if the audio file exceeds the capacity of the DICOM image
if numSamples > maxSamples
error('Audio file too large to hide in the DICOM image.');
end
% Measure insertion time
insertionStartTime = tic;
% Perform DCT on DICOM image blocks
blockSize = 8; % Size of DCT blocks
dctDicomImage = blockproc(dicomVector, [blockSize blockSize], @(block_struct) dct2(block_struct.data));
% Embed audio samples in the DCT coefficients
audioIndex = 1; % Index of audio sample
for row = 1:blockSize:size(dctDicomImage, 1)
for col = 1:blockSize:size(dctDicomImage, 2)
if audioIndex <= numSamples
dctDicomImage(row, col) = dctDicomImage(row, col) + audio(audioIndex)*10; % Multiply by 10 for amplification
audioIndex = audioIndex + 1;
end
end
end
% Perform inverse DCT on modified DCT DICOM image
idctDicomImage = blockproc(dctDicomImage, [blockSize blockSize], @(block_struct) idct2(block_struct.data));
% Clip the pixel values to the valid intensity range [0, 255]
idctDicomImage(idctDicomImage < 0) = 0;
idctDicomImage(idctDicomImage > 255) = 255;
% Reshape the modified DICOM image vector back to its original size
stegoDicomImage = uint8(reshape(idctDicomImage, size(dicomImage)));
% Save the stego DICOM image
dicomwrite(stegoDicomImage, 'stego_dicom_image.dcm', dicomInfo, 'CreateMode', 'copy');
% Measure insertion time
insertionTime = toc(insertionStartTime);
% Extract audio from the stego DICOM image
stegoDicomVector = double(stegoDicomImage(:));
% Measure extraction time
extractionStartTime = tic;
% Perform DCT on stego DICOM image blocks
dctStegoDicomImage = blockproc(stegoDicomVector, [blockSize blockSize], @(block_struct) dct2(block_struct.data));
% Extract audio from the stego DICOM image
dctOrigDicomImage = blockproc(dicomVector, [blockSize blockSize], @(block_struct) dct2(block_struct.data));
% Extract audio samples from the difference in DCT coefficients
extractedAudio = zeros(numSamples, 1); % Initialize the extracted audio array
audioIndex = 1; % Index of extracted audio sample
for row = 1:blockSize:size(dctStegoDicomImage, 1)
for col = 1:blockSize:size(dctStegoDicomImage, 2)
if audioIndex <= numSamples
extractedAudio(audioIndex) = (dctStegoDicomImage(row, col) - dctOrigDicomImage(row, col))/10; % Divide by 10 to reverse amplification
audioIndex = audioIndex + 1;
end
end
end
% Measure extraction time
extractionTime = toc(extractionStartTime);
% Rescale extracted audio to the original range
extractedAudio = extractedAudio - mean(extractedAudio);
extractedAudio = extractedAudio / max(abs(extractedAudio));
extractedAudio = extractedAudio * max(abs(audio));
% Save the extracted audio
audiowrite('extracted_audio_from_dicom.wav', extractedAudio, sampleRate);
% Convert dicomImage to uint8 for PSNR calculation
dicomImage = uint8(dicomImage);
% Compute PSNR, SSIM, and MSE
psnrValue = psnr(stegoDicomImage, dicomImage);
ssimValue = ssim(stegoDicomImage, dicomImage);
mseValue = immse(stegoDicomImage, dicomImage);
% Display PSNR, SSIM, and MSE values
disp(['PSNR: ', num2str(psnrValue)]);
disp(['SSIM: ', num2str(ssimValue)]);
disp(['MSE: ', num2str(mseValue)]);
% Display insertion and extraction times
disp(['Insertion Time: ', num2str(insertionTime), ' seconds']);
disp(['Extraction Time: ', num2str(extractionTime), ' seconds']);
% Display original and stego images
figure;
% Display original image
subplot(2, 2, 1);
imshow(dicomImage, []);
title('Original DICOM Image');
% Display stego image
subplot(2, 2, 2);
imshow(stegoDicomImage, []);
title('Stego DICOM Image');
% Display original audio signal
subplot(2, 2, 3);
plot(audio);
title('Original Audio Signal');
xlabel('Sample Index');
ylabel('Amplitude');
% Display extracted audio signal
subplot(2, 2, 4);
plot(extractedAudio);
title('Extracted Audio Signal');
xlabel('Sample Index');
ylabel('Amplitude');

Accepted Answer

Aishwarya
Aishwarya on 18 Dec 2023
Hi Ramya,
I understand that you are having issue with extracting the original audio after embedding audio into a DICOM image using DCT Method.
After reviewing the provided code, here are some suggestions that might help resolve or troubleshoot the issue.
  • DCT Coefficient Selection: In the code, the audio is embedded to first coefficient (DC term) of each DCT block. As the DC term represents average pixel value of the block, so modifying it could result in distortion in resultant image. Consider embedding the audio into less sensitive DCT coefficient. For example, you could choose the coefficient at position (4,4) in each block. Then the modified embedding and extraction steps are given below:
Embedding:
% Define the position for embedding within each block
embedRow = 4;
embedCol = 4;
% Embed the audio into the selected DCT coefficient
for row = 1:blockSize:size(dctDicomImage, 1)
for col = 1:blockSize:size(dctDicomImage, 2)
if audioIndex <= numSamples
dctDicomImage(row + embedRow - 1, col + embedCol - 1) = ...
dctDicomImage(row + embedRow - 1, col + embedCol - 1) + audio(audioIndex)*10;
audioIndex = audioIndex + 1;
end
end
end
Extraction:
% Extract the audio from the selected DCT coefficient
for row = 1:blockSize:size(dctStegoDicomImage, 1)
for col = 1:blockSize:size(dctStegoDicomImage, 2)
if audioIndex <= numSamples
extractedAudio(audioIndex) = (dctStegoDicomImage(row + embedRow - 1, col + embedCol - 1) - ...
dctOrigDicomImage(row + embedRow - 1, col + embedCol - 1))/10;
audioIndex = audioIndex + 1;
end
end
end
  • Block Size Mismatch: The DICOM image is flattened into single column vector and then applied to “blockproc” function. Here make sure that total number of elements in vector is multiple of block size squared (“blockSize^2”). Otherwise, the last block may not be processed correctly and could lead to problems during extracting.
  • Adjust Audio Amplification factor: Consider tuning the audio amplification factor. There is possibility that the modification to DCT coefficient causes them to go outside valid range of image data type, information may be lost during clipping.
  • Normalization and Rescaling of Audio: Check that the normalization and scaling of the audio signal are consistent and reversible.
  • Use Simple Audio signal: Test the embedding and extraction process on simpler audio signal (single tone or a series of tones).
Please refer to below documentation for more information on the functions used:
I hope these suggestions help resolve the issue.

More Answers (0)

Categories

Find more on DICOM Format in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!