From 25921298c347e4af34b5a5dc753c0c16700a0006 Mon Sep 17 00:00:00 2001 From: Emilio Martinez Date: Mon, 26 Jun 2023 20:05:50 -0300 Subject: [PATCH] Updated DTutils and folder simultarion (logs, reception errors, etc) --- KAIR/folder_simulation.py | 83 ++++++++++++++++++++++++++------------- KAIR/utils/DTutils.py | 30 +++++++------- 2 files changed, 70 insertions(+), 43 deletions(-) diff --git a/KAIR/folder_simulation.py b/KAIR/folder_simulation.py index a995d13..d77007c 100644 --- a/KAIR/folder_simulation.py +++ b/KAIR/folder_simulation.py @@ -22,6 +22,9 @@ from scipy import signal from PIL import Image from utils.DTutils import TMDS_encoding_original, TMDS_serial import sys +import logging +from utils import utils_logger +from datetime import datetime #%% @@ -47,7 +50,7 @@ def image_transmition_simulation(I, blanking=False): return I_TMDS_Tx, I_TMDS.shape def image_capture_simulation(I_Tx, h_total, v_total, N_harmonic, noise_std=0, - fps=60): + fps=60, freq_error=0, phase_error=0): # Compute pixelrate and bitrate px_rate = h_total*v_total*fps @@ -75,13 +78,14 @@ def image_capture_simulation(I_Tx, h_total, v_total, N_harmonic, noise_std=0, # AM modulation frequency according to pixel harmonic harm = N_harmonic*px_rate - # Harmonic oscilator - baseband_exponential = np.exp(2j*np.pi*harm*t_continuous) + # Harmonic oscilator (including frequency and phase error) + baseband_exponential = np.exp(2j*np.pi*(harm+freq_error)*t_continuous + 1j*phase_error) usrp_rate = 50e6 + usrp_BW = usrp_rate/2 # AM modulation and SDR sampling - I_Rx = signal.resample_poly(I_Tx_noisy*baseband_exponential,up=int(usrp_rate), down=sample_rate) + I_Rx = signal.resample_poly(I_Tx_noisy*baseband_exponential,up=int(usrp_BW), down=sample_rate) # Reshape signal to the image size I_capture = signal.resample(I_Rx, h_total*v_total).reshape(v_total,h_total) @@ -97,58 +101,81 @@ def save_simulation_image(I,path_and_name): I_real = np.real(I) I_imag = np.imag(I) - realmax = I_real.max() - realmin = I_real.min() - imagmax = I_imag.max() - imagmin = I_imag.min() - - # Stretch contrast on every channel - I_save[:,:,0] = 255*(I_real-realmin)/(realmax-realmin) - I_save[:,:,1] = 255*(I_imag-imagmin)/(imagmax-imagmin) + I_save[:,:,0], I_save[:,:,1] = I_real, I_imag + min_value, max_value = np.min(I_save[:,:,:2]), np.max(I_save[:,:,:2]) + I_save[:,:,0] = 255*(I_real-min_value)/(max_value-min_value) + I_save[:,:,1] = 255*(I_imag-min_value)/(max_value-min_value) im = Image.fromarray(I_save.astype('uint8')) im.save(path_and_name) def main(): - + + logs_dir = './logfiles/' + # Create logs directory if not exist + if not os.path.exists(logs_dir): + os.mkdir(logs_dir) + + logger_name = 'simulations_'+datetime.now().strftime("%d-%m-%Y_%H:%M:%S") + utils_logger.logger_info(logger_name, logs_dir+logger_name+'.log') + logger = logging.getLogger(logger_name) + + # Get foldername argument foldername = sys.argv[-1] + message = f'Tempest capture simulation for image folder {foldername}\n' + logger.info(message) + # Get images and subfolders names images = get_images_names_from_folder(foldername) - simulations_folder = foldername+'/simulations/' - - os.mkdir(simulations_folder) + # Create simulation directory if not exist at the folder path + simulations_path = foldername+'/simulations/' + if not os.path.exists(simulations_path): + os.mkdir(simulations_path) + message = f'Created simulation directory at {simulations_path}\n' + logger.info(message) - # timestamp for simulation starting - t1_image = time.time() + # Possible noise std values + # noise_stds = np.array([ 0, 5, 10, 15, 20, 25]) + for image in images: + # timestamp for simulation starting + t1_image = time.time() + # Read image image_path = foldername+'/'+image I = imread(image_path) - - # TMDS coding and bit serialization - I_Tx, resolution = image_transmition_simulation(I) - v_res, h_res, _ = resolution # Choose random pixelrate harmonic number N_harmonic = np.random.randint(1,10) + + + message = f'Initiate simulation for image {image} with {N_harmonic} pixel harmonic frequency' + logger.info(message) + + # TMDS coding and bit serialization + I_Tx, resolution = image_transmition_simulation(I, blanking=True) + v_res, h_res, _ = resolution + I_capture = image_capture_simulation(I_Tx, h_res, v_res, N_harmonic) - path = simulations_folder+image + path = simulations_path+image save_simulation_image(I_capture,path) - # timestamp for simulation ending - t2_image = time.time() + # timestamp for simulation ending + t2_image = time.time() + + t_images = t2_image-t1_image + + message = 'Processing time: {:.2f}'.format(t_images)+'s\n' + logger.info(message) - t_images = t2_images-t1_images - - print('\nTiempo total de las '+str(len(images))+' simulaciones:','{:.2f}'.format(t_images)+'s\n') if __name__ == "__main__": main() diff --git a/KAIR/utils/DTutils.py b/KAIR/utils/DTutils.py index 8ac8e58..48c64f5 100644 --- a/KAIR/utils/DTutils.py +++ b/KAIR/utils/DTutils.py @@ -106,37 +106,37 @@ def TMDS_pixel_rare (pix): Outputs: - pix_out: TDMS coded 16-bit pixel (only 10 useful) - - cnt: 0's and 1's balance updated with new pixel coding + - cnt: 0's and 1's balance updated with new pixel coding """ # Convert 8-bit pixel to binary list D - D = uint8_to_binarray(pix) + d = uint8_to_binarray(pix) # Initialize output q - qm = [D[0]] + Qm = [d[0]] # 1's unbalanced condition at current pixel - N1_D = np.sum(D) + N1_D = np.sum(d) - if N1_D>4 or (N1_D==4 and not(D[0])): + if N1_D>4 or (N1_D==4 and not(d[0])): # XNOR of consecutive bits for k in range(1,8): - qm.append( not(qm[k-1] ^ D[k]) ) - qm.append(0) + Qm.append( not(Qm[k-1] ^ d[k]) ) + Qm.append(0) else: # XOR of consecutive bits for k in range(1,8): - qm.append( qm[k-1] ^ D[k] ) - qm.append(1) + Qm.append( Qm[k-1] ^ d[k] ) + Qm.append(1) - qm.append(np.random.choice([0,1])) + Qm.append(np.random.choice([0,1])) # Return the TMDS coded pixel as uint and 0's y 1's balance - return binarray_to_uint(qm) + return binarray_to_uint(Qm) @jit(nopython=True) def TMDS_pixel_numba(pix:uint8, cnt:int8)->tuple: @@ -293,11 +293,11 @@ def TMDS_encoding_original (I, blanking = False): if blanking: # Get blanking resolution for input image - v = (v_in==1080)*1125 + (v_in==720)*750 + (v_in==600)*628 + (v_in==480)*525 - h = (h_in==1920)*2200 + (h_in==1280)*1650 + (h_in==800)*1056 + (h_in==640)*800 + v = (v_in==1080)*1125 + (v_in==900)*1000 + (v_in==720)*750 + (v_in==600)*628 + (v_in==480)*525 + h = (h_in==1920)*2200 + (h_in==1600)*1800 + (h_in==1280)*1650 + (h_in==800)*1056 + (h_in==640)*800 - vdiff = v - v_in - hdiff = h - h_in + v_diff = v - v_in + h_diff = h - h_in # Create image with blanking and change type to uint16 # Assuming the blanking corresponds to 10bit number [0, 0, 1, 0, 1, 0, 1, 0, 1, 1] (LSB first)