CoolFace
Apppublic

HChandeepa/PulmoSense_AI

sourceHugging Facemitupdated 1y agoView on Hugging Face
0likes
spectrogram.py446 linesDownload Raw Back to root
1# import librosa2# import librosa.display3# import matplotlib.pyplot as plt4# import numpy as np5# import tensorflow as tf6# from flask import jsonify7 8# from classificationModel import do_primary_prediction, do_secondary_prediction9 10 11# def generate_mel_spec(audio):12#     mel = librosa.power_to_db(librosa.feature.melspectrogram(y=audio, sr=22050, n_mels=128, n_fft=2048, hop_length=512))13#     return mel14 15 16# def generate_mfcc(audio):17#     mfcc = librosa.feature.mfcc(y=audio, n_mfcc=128, n_fft=2048, hop_length=512)18#     return mfcc19 20 21# def generate_chroma(audio):22#     chroma = librosa.feature.chroma_stft(y=audio, sr=22050, n_chroma=128, n_fft=2048, hop_length=512)23#     return chroma24 25 26# def createSpectrogram(audio):27#     print("createSpectrogram called")28 29#     # Load audio file30#     y, sr = librosa.load(audio, sr=22500, duration=6 )31 32#     mel = generate_mel_spec(y)33#     mfcc_1 = generate_mfcc(y)34#     chroma_1 = generate_chroma(y)35 36#     three_chanel = np.stack((mel, mfcc_1, chroma_1), axis=2)37#     plt.figure(figsize=(4, 4))38#     plt.imshow(three_chanel)39#     plt.axis('off')40#     plt.subplots_adjust(left=0, right=1, bottom=0, top=1)41#     # plt.show()42#     # plt.savefig("stacked.png")43#     plt.close()44#     print("stacked.png saved")45 46#     # expanded_sample = tf.expand_dims(three_chanel, axis=0)47#     expanded_sample = np.array([three_chanel])48 49#     print("expanded spec shape",expanded_sample.shape)50#     print("expanded spec",expanded_sample)51 52#     result = do_primary_prediction(expanded_sample)53#     if not result:54#         result_data = {'result': False, 'diseases': {}}55#         return jsonify(result_data)56#     else:57#         severity = {58#             "Asthma": 1,59#             "Bronchiectasis": 1,60#             "Bronchiolitis": 2,61#             "Bronchitis": 3,62#             "COPD": 1,63#             "Lung Fibrosis": 2,64#             "Pleural Effusion": 3,65#             "Pneumonia": 2,66#             "URTI": 267#         }68#         secondary_result = do_secondary_prediction(expanded_sample)69#         severities = []70 71#         for disease in secondary_result['diseases']:72#             severities.append(severity[disease])73#         secondary_result['severities'] = severities74#         floated_probabilities = []75#         for i in secondary_result['probabilities']:76#             if isinstance(i, np.float32):77#                 floated_probabilities.append(float(i))78#         secondary_result['probabilities'] = floated_probabilities79#         print("secondary_result", secondary_result)80#         return secondary_result81 82#---------------------------------------------------------------------83# import librosa84# import librosa.display85# import matplotlib.pyplot as plt86# import numpy as np87# import soundfile as sf88# import tempfile89# import os90# from flask import jsonify91 92# from classificationModel import do_primary_prediction, do_secondary_prediction93 94# # Constants for fixed dimensions95# TARGET_LENGTH = 264  # The expected number of time steps in your model96# SAMPLE_RATE = 2205097# N_FFT = 204898# HOP_LENGTH = 51299 100# def generate_mel_spec(audio, sr=SAMPLE_RATE):101#     mel = librosa.power_to_db(librosa.feature.melspectrogram(102#         y=audio, sr=sr, n_mels=128, n_fft=N_FFT, hop_length=HOP_LENGTH))103#     return mel104 105# def generate_mfcc(audio, sr=SAMPLE_RATE):106#     mfcc = librosa.feature.mfcc(107#         y=audio, sr=sr, n_mfcc=128, n_fft=N_FFT, hop_length=HOP_LENGTH)108#     return mfcc109 110# def generate_chroma(audio, sr=SAMPLE_RATE):111#     chroma = librosa.feature.chroma_stft(112#         y=audio, sr=sr, n_chroma=128, n_fft=N_FFT, hop_length=HOP_LENGTH)113#     return chroma114 115# def fix_length(feature, target_length=TARGET_LENGTH):116#     """Pad or truncate feature to target length"""117#     if feature.shape[1] > target_length:118#         return feature[:, :target_length]119#     elif feature.shape[1] < target_length:120#         return np.pad(feature, ((0, 0), (0, target_length - feature.shape[1])))121#     return feature122 123# def createSpectrogram(audio_path):124#     print("createSpectrogram called")125    126#     try:127#         # Load audio with consistent parameters128#         try:129#             y, sr = sf.read(audio_path)130#             if sr != SAMPLE_RATE:131#                 y = librosa.resample(y, orig_sr=sr, target_sr=SAMPLE_RATE)132#         except Exception as e:133#             print(f"Soundfile read failed, falling back to librosa: {str(e)}")134#             y, sr = librosa.load(audio_path, sr=SAMPLE_RATE, duration=6, mono=True)135        136#         # Ensure proper audio characteristics137#         if len(y) < SAMPLE_RATE * 1:138#             raise ValueError("Audio file is too short")139            140#         if len(y.shape) > 1:141#             y = librosa.to_mono(y)142            143#         y = librosa.util.normalize(y)144        145#         # Generate features with fixed length146#         mel = fix_length(generate_mel_spec(y))147#         mfcc = fix_length(generate_mfcc(y))148#         chroma = fix_length(generate_chroma(y))149 150#         three_channel = np.stack((mel, mfcc, chroma), axis=2)151        152#         # Verify dimensions before prediction153#         if three_channel.shape != (128, TARGET_LENGTH, 3):154#             raise ValueError(f"Invalid spectrogram shape: {three_channel.shape}. Expected (128, {TARGET_LENGTH}, 3)")155        156#         # Save spectrogram for debugging157#         plt.figure(figsize=(4, 4))158#         plt.imshow(three_channel)159#         plt.axis('off')160#         plt.subplots_adjust(left=0, right=1, bottom=0, top=1)161#         temp_img_path = os.path.join(tempfile.gettempdir(), "stacked.png")162#         plt.savefig(temp_img_path)163#         plt.close()164#         print(f"Spectrogram saved at {temp_img_path}")165 166#         expanded_sample = np.array([three_channel])  # Shape becomes (1, 128, 264, 3)167#         print("Final input shape:", expanded_sample.shape)168 169#         # Primary prediction170#         result = do_primary_prediction(expanded_sample)171#         if not result:172#             return jsonify({'result': False, 'diseases': {}})173            174#         # Secondary prediction with severity175#         severity_map = {176#             "Asthma": 1, "Bronchiectasis": 1, "Bronchiolitis": 2,177#             "Bronchitis": 3, "COPD": 1, "Lung Fibrosis": 2,178#             "Pleural Effusion": 3, "Pneumonia": 2, "URTI": 2179#         }180        181#         secondary_result = do_secondary_prediction(expanded_sample)182#         secondary_result['severities'] = [183#             severity_map[disease] for disease in secondary_result['diseases']184#         ]185#         secondary_result['probabilities'] = [186#             float(p) for p in secondary_result['probabilities']]187        188#         return secondary_result189        190#     except Exception as e:191#         print(f"Processing error: {str(e)}")192#         return jsonify({193#             'error': str(e),194#             'message': 'Failed to process audio file',195#             'result': False196#         }), 400197 198#------------------------------------------------------------------------------------------------------------199# import librosa200# import librosa.display201# import matplotlib.pyplot as plt202# import numpy as np203# import soundfile as sf204# import tempfile205# import os206# from flask import jsonify207 208# from classificationModel import do_primary_prediction, do_secondary_prediction209 210# # Constants for fixed dimensions211# TARGET_LENGTH = 264  # The expected number of time steps in your model212# SAMPLE_RATE = 22050213# N_FFT = 2048214# HOP_LENGTH = 512215 216# def generate_mel_spec(audio, sr=SAMPLE_RATE):217#     mel = librosa.power_to_db(librosa.feature.melspectrogram(218#         y=audio, sr=sr, n_mels=128, n_fft=N_FFT, hop_length=HOP_LENGTH))219#     return mel220 221# def generate_mfcc(audio, sr=SAMPLE_RATE):222#     mfcc = librosa.feature.mfcc(223#         y=audio, sr=sr, n_mfcc=128, n_fft=N_FFT, hop_length=HOP_LENGTH)224#     return mfcc225 226# def generate_chroma(audio, sr=SAMPLE_RATE):227#     chroma = librosa.feature.chroma_stft(228#         y=audio, sr=sr, n_chroma=128, n_fft=N_FFT, hop_length=HOP_LENGTH)229#     return chroma230 231# def fix_length(feature, target_length=TARGET_LENGTH):232#     """Pad or truncate feature to target length"""233#     if feature.shape[1] > target_length:234#         return feature[:, :target_length]235#     elif feature.shape[1] < target_length:236#         return np.pad(feature, ((0, 0), (0, target_length - feature.shape[1])))237#     return feature238 239# def createSpectrogram(audio_path):240#     print("createSpectrogram called")241    242#     try:243#         # Load audio with consistent parameters244#         try:245#             y, sr = sf.read(audio_path)246#             if sr != SAMPLE_RATE:247#                 y = librosa.resample(y, orig_sr=sr, target_sr=SAMPLE_RATE)248#         except Exception as e:249#             print(f"Soundfile read failed, falling back to librosa: {str(e)}")250#             y, sr = librosa.load(audio_path, sr=SAMPLE_RATE, duration=6, mono=True)251        252#         # Ensure proper audio characteristics253#         if len(y) < SAMPLE_RATE * 1:254#             raise ValueError("Audio file is too short")255            256#         if len(y.shape) > 1:257#             y = librosa.to_mono(y)258            259#         y = librosa.util.normalize(y)260        261#         # Generate features with fixed length262#         mel = fix_length(generate_mel_spec(y))263#         mfcc = fix_length(generate_mfcc(y))264#         chroma = fix_length(generate_chroma(y))265 266#         three_channel = np.stack((mel, mfcc, chroma), axis=2)267        268#         # Verify dimensions before prediction269#         if three_channel.shape != (128, TARGET_LENGTH, 3):270#             raise ValueError(f"Invalid spectrogram shape: {three_channel.shape}. Expected (128, {TARGET_LENGTH}, 3)")271        272#         # Save spectrogram for debugging273#         plt.figure(figsize=(4, 4))274#         plt.imshow(three_channel)275#         plt.axis('off')276#         plt.subplots_adjust(left=0, right=1, bottom=0, top=1)277#         temp_img_path = os.path.join(tempfile.gettempdir(), "stacked.png")278#         plt.savefig(temp_img_path)279#         plt.close()280#         print(f"Spectrogram saved at {temp_img_path}")281 282#         expanded_sample = np.array([three_channel])  # Shape becomes (1, 128, 264, 3)283#         print("Final input shape:", expanded_sample.shape)284 285#         # Primary prediction286#         result = do_primary_prediction(expanded_sample)287#         if not result:288#             return jsonify({'result': False, 'diseases': []})289            290#         # Secondary prediction with severity291#         severity_map = {292#             "Asthma": "1", "Bronchiectasis": "1", "Bronchiolitis": "2",293#             "Bronchitis": "3", "COPD": "1", "Lung Fibrosis": "2",294#             "Pleural Effusion": "3", "Pneumonia": "2", "URTI": "2"295#         }296        297#         secondary_result = do_secondary_prediction(expanded_sample)298        299#         # Ensure all values are JSON serializable and properly typed300#         response = {301#             'diseases': [str(d) for d in secondary_result['diseases']],302#             'probabilities': [float(p) for p in secondary_result['probabilities']],303#             'severities': [str(severity_map[d]) for d in secondary_result['diseases']]304#         }305        306#         return jsonify(response)307        308#     except Exception as e:309#         print(f"Processing error: {str(e)}")310#         return jsonify({311#             'error': str(e),312#             'message': 'Failed to process audio file',313#             'result': False314#         }), 400315 316#------------------------------------------------------------------------------------------------------------------317import librosa318import librosa.display319import matplotlib.pyplot as plt320import numpy as np321import soundfile as sf322import tempfile323import os324from flask import jsonify325 326from classificationModel import do_primary_prediction, do_secondary_prediction327 328# Constants for fixed dimensions329TARGET_LENGTH = 264  # The expected number of time steps in your model330SAMPLE_RATE = 22050331N_FFT = 2048332HOP_LENGTH = 512333 334def generate_mel_spec(audio, sr=SAMPLE_RATE):335    mel = librosa.power_to_db(librosa.feature.melspectrogram(336        y=audio, sr=sr, n_mels=128, n_fft=N_FFT, hop_length=HOP_LENGTH))337    return mel338 339def generate_mfcc(audio, sr=SAMPLE_RATE):340    mfcc = librosa.feature.mfcc(341        y=audio, sr=sr, n_mfcc=128, n_fft=N_FFT, hop_length=HOP_LENGTH)342    return mfcc343 344def generate_chroma(audio, sr=SAMPLE_RATE):345    chroma = librosa.feature.chroma_stft(346        y=audio, sr=sr, n_chroma=128, n_fft=N_FFT, hop_length=HOP_LENGTH)347    return chroma348 349def fix_length(feature, target_length=TARGET_LENGTH):350    """Pad or truncate feature to target length"""351    if feature.shape[1] > target_length:352        return feature[:, :target_length]353    elif feature.shape[1] < target_length:354        return np.pad(feature, ((0, 0), (0, target_length - feature.shape[1])))355    return feature356def createSpectrogram(audio_path):357    print("createSpectrogram called")358    359    try:360        # Load audio with consistent parameters361        try:362            y, sr = sf.read(audio_path)363            if sr != SAMPLE_RATE:364                y = librosa.resample(y, orig_sr=sr, target_sr=SAMPLE_RATE)365        except Exception as e:366            print(f"Soundfile read failed, falling back to librosa: {str(e)}")367            y, sr = librosa.load(audio_path, sr=SAMPLE_RATE, duration=6, mono=True)368        369        # Ensure proper audio characteristics370        if len(y) < SAMPLE_RATE * 1:371            return jsonify({372                'result': False,373                'message': 'Audio file is too short',374                'diseases': [],375                'probabilities': [],376                'severities': []377            })378            379        if len(y.shape) > 1:380            y = librosa.to_mono(y)381            382        y = librosa.util.normalize(y)383        384        # Generate features with fixed length385        mel = fix_length(generate_mel_spec(y))386        mfcc = fix_length(generate_mfcc(y))387        chroma = fix_length(generate_chroma(y))388 389        three_channel = np.stack((mel, mfcc, chroma), axis=2)390        391        # Verify dimensions before prediction392        if three_channel.shape != (128, TARGET_LENGTH, 3):393            return jsonify({394                'result': False,395                'message': 'Invalid spectrogram dimensions',396                'diseases': [],397                'probabilities': [],398                'severities': []399            })400 401        expanded_sample = np.array([three_channel])402        403        # Primary prediction404        is_healthy = not do_primary_prediction(expanded_sample)405        if is_healthy:406            return jsonify({407                'result': False,408                'message': 'No lung diseases detected',409                'diseases': [],410                'probabilities': [],411                'severities': []412            })413            414        # Secondary prediction with severity415        severity_map = {416            "Asthma": "1", "Bronchiectasis": "1", "Bronchiolitis": "2",417            "Bronchitis": "3", "COPD": "1", "Lung Fibrosis": "2",418            "Pleural Effusion": "3", "Pneumonia": "2", "URTI": "2"419        }420        421        secondary_result = do_secondary_prediction(expanded_sample)422        423        # Ensure all values exist424        diseases = secondary_result.get('diseases', [])425        probabilities = secondary_result.get('probabilities', [])426        427        response = {428            'result': True,429            'diseases': [str(d) for d in diseases],430            'probabilities': [float(p) for p in probabilities],431            'severities': [str(severity_map.get(d, "0")) for d in diseases],432            'message': 'Potential lung diseases detected'433        }434        435        return jsonify(response)436        437    except Exception as e:438        print(f"Processing error: {str(e)}")439        return jsonify({440            'result': False,441            'error': str(e),442            'message': 'Failed to process audio file',443            'diseases': [],444            'probabilities': [],445            'severities': []446        }), 400