My MATLAB code for transmitting and receiving an image using 16-QAM results in the received image being divided into 16 parts
How can I fix it?
clear; clc; close all;
% Source Encoding: Converting Image to Binary Sequence
imresize_scale = 0.5; % Resizing the original image by 0.5
img = imread('cameraman.tif'); % Loading 'cameraman.tif' image file
img1 = imresize(img, imresize_scale); % Resizing image using bicubic interpolation
img2 = imbinarize(img1); % Binarizing the image using Otsu's algorithm
bits = img2(:); % Creating a binary sequence from the image
% 16-QAM Symbol Mapping (Modulation)
M = 16; % For 16QAM, M is set to 16
bits_reshape = reshape(bits, log2(M), length(bits)/log2(M)).'; % Reshaping bit sequence for 16QAM
symbol_16qam = qammod(bi2de(bits_reshape), M, 'UnitAveragePower', true); % Modulating using 16QAM
% Multiplexing using OFDM
N_subcarrier = 256; % Setting the number of subcarriers to 256
N_cyclicprefix = 32; % Setting the length of Cyclic Prefix (CP) to 32
% Converting Serial Data to Parallel Data and Creating OFDM Symbols
symbols_frequency = {}; % Initializing a cell array to store symbols in frequency domain
for i = 1:length(symbol_16qam)/(N_subcarrier/2)
symbols_frequency{end+1} = [0; symbol_16qam(N_subcarrier/2*(i-1)+1:N_subcarrier/2*(i))];
symbols_frequency{end} = [symbols_frequency{end}; flip(conj(symbols_frequency{end}(2:end-1)))];
end
% Converting from Frequency Domain to Time Domain using IFFT
symbols_time = {}; % Initializing a cell array to store symbols in time domain
for i = 1:length(symbols_frequency)
symbols_time{end+1} = ifft(symbols_frequency{i}).*sqrt(length(symbols_frequency{i})); % Performing IFFT and power normalization
end
% Inserting Cyclic Prefix (CP)
for i = 1:length(symbols_time)
symbols_time{i} = [symbols_time{i}(end-N_cyclicprefix+1:end); symbols_time{i}];
end
% Adding Pilot Signal (for Channel Estimation and Synchronization)
pilot_frequency = ones(N_subcarrier,1); % Setting the pilot signal in frequency domain
pilot_time = ifft(pilot_frequency).*sqrt(length(pilot_frequency)); % Converting to time domain using IFFT and power normalization
pilot_time = [pilot_time(end-N_cyclicprefix+1:end); pilot_time]; % Adding CP to the pilot signal
% Converting Parallel Data to Serial Data to Create Final Transmit Signal
tx_signal = [pilot_time]; % Adding the first pilot signal
for i = 1:length(symbols_time)
tx_signal = [tx_signal; symbols_time{i}]; % Adding each OFDM symbol
if mod(i,4) == 0 && i ~= length(symbols_time) % Adding pilot signal every 4th symbol (except the last symbol)
tx_signal = [tx_signal; pilot_time];
end
end
% Setting AWGN Channel and Adding AWGN to the Transmit Signal
EbNo = 100; % Setting the Energy per Bit to Noise Power Spectral Density Ratio (Eb/N0) value
k = log2(M); % For M-ary QAM, k is the number of bits per symbol
snr = EbNo + 10*log10(k); % Calculating SNR
tx_signal_with_noise = awgn(tx_signal, snr, 'measured'); % Adding AWGN to the transmit signal
% Receiver Code
rx_signal = tx_signal_with_noise; % Setting the transmitted signal through AWGN channel as the received signal
% Serial to Parallel and FFT
OFDM_blocks = {};
demodulated_OFDM_blocks = {};
for i = 1:length(rx_signal)/(N_subcarrier+N_cyclicprefix)
block = rx_signal((i-1)*(N_subcarrier+N_cyclicprefix)+1:i*(N_subcarrier+N_cyclicprefix));
OFDM_blocks{end+1} = block(N_cyclicprefix+1:end); % Removing CP
demodulated_OFDM_blocks{end+1} = fft(OFDM_blocks{end})./sqrt(N_subcarrier); % Performing FFT
end
% Channel Estimation and Equalization
equalized_symbols = {};
pilot_block = demodulated_OFDM_blocks{1};
channel_estimate = pilot_block./pilot_frequency;
for i = 2:length(demodulated_OFDM_blocks)
equalized_symbols{end+1} = demodulated_OFDM_blocks{i}./channel_estimate;
end
% Gathering Equalized Symbols
all_equalized_symbols = [];
for i = 1:length(equalized_symbols)
all_equalized_symbols = [all_equalized_symbols; equalized_symbols{i}(2:N_subcarrier/2+1)];
end
% Plotting IQ Scatter Plot of Equalized Symbols
figure;
sPlotFig = scatterplot(all_equalized_symbols, 1, 0, 'g.'); % Received symbols in green
hold on;
scatterplot(symbol_16qam, 1, 0, 'r*', sPlotFig); % Transmitted symbols in red
title('IQ Scatter Plot of Transmitted and Received Symbols');
xlabel('In-phase');
ylabel('Quadrature');
legend('Received Symbols', 'Transmitted Symbols');
% Calculating EVM (Error Vector Magnitude)
evm_values = []; % Initializing an array to store EVM values
for i = 1:min(length(symbol_16qam), length(all_equalized_symbols))
error_vector = symbol_16qam(i) - all_equalized_symbols(i);
evm_values(end+1) = abs(error_vector);
end
% Calculating Mean or RMS Value of EVM
mean_evm = mean(evm_values);
rms_evm = sqrt(mean(evm_values.^2));
% Displaying EVM Results
disp(['Mean EVM: ', num2str(mean_evm)]);
disp(['RMS EVM: ', num2str(rms_evm)]);
% Plotting EVM Distribution Graph
figure;
histogram(evm_values, 50); % Histogram of EVM values
title('EVM Distribution');
xlabel('EVM');
ylabel('Frequency');
% 16-QAM Demodulation and Conversion to Bits
rx_bits = [];
for i = 1:length(equalized_symbols)
valid_symbols = equalized_symbols{i}(2:N_subcarrier/2+1); % Extracting valid symbols
demod_symbols = qamdemod(valid_symbols, M, 'UnitAveragePower', true); % Demodulating 16QAM
rx_bits = [rx_bits; de2bi(demod_symbols, log2(M), 'left-msb')]; % Converting to bits
end
rx_bits = rx_bits(:);
% Calculating BER (Bit Error Rate)
BER = sum(bits ~= rx_bits(1:length(bits)))/length(bits); % Calculating the number of different bits between transmitted and received bits to calculate BER
% Displaying Results
disp(['Bit Error Rate (BER): ', num2str(BER)]);
% Displaying Received Image
figure(1);
rx_img = reshape(rx_bits(1:length(bits)), size(img2));
subplot(1,2,1); imshow(img2);
subplot(1,2,2); imshow(rx_img);