zhaodongsun / contrast-phys

[TPAMI & ECCV 2022] Contrast-Phys & Contrast-Phys+ for facial video-based remote physiological signal measurement
https://ieeexplore.ieee.org/document/10440521
MIT License
68 stars 14 forks source link

There is a problem with the hr_fft_batch function in the utils_sig.py file #10

Open BugMaker2002 opened 8 months ago

BugMaker2002 commented 8 months ago

Some errors occurred when I used the following code to calculateMAE, RMSE,and Pearson coefficients:

for h5_path in test_list:
        h5_path = str(h5_path)

        with h5py.File(h5_path, 'r') as f:
            imgs = f['imgs']
            subject_name = os.path.basename(h5_path)[:-3]
            bvp_path = f"/share2/data/zhouwenqing/UBFC_rPPG/dataset2/{subject_name}/ground_truth.txt"
            bvp = np.loadtxt(bvp_path).reshape((-1, 1))
            # bvppeak = f['bvp_peak']
            fs = config_train['fs']

            # duration表示秒数,fs表示frame per seccond 
            duration = np.min([imgs.shape[0], bvp.shape[0]]) / fs
            num_blocks = int(duration // time_interval)
            # 从整个视频当中截取出num_blocks个视频片段,这些片段之间是连续的(指从原视频当中截取的方式)
            rppg_list = []
            bvp_list = []
            # bvppeak_list = []
            for b in range(num_blocks):
                rppg_clip = dl_model(imgs[b*time_interval*fs:(b+1)*time_interval*fs])
                rppg_list.append(rppg_clip)

                bvp_list.append(bvp[b*time_interval*fs:(b+1)*time_interval*fs])
                # bvppeak_list.append(bvppeak[b*time_interval*fs:(b+1)*time_interval*fs])

            rppg_list = np.array(rppg_list)
            bvp_list = np.array(bvp_list)
            results = {'rppg_list': rppg_list, 'bvp_list': bvp_list}
            np.save(pred_exp_dir+'/'+h5_path.split('/')[-1][:-3], results)

            bvp_list = bvp_list.reshape(num_blocks, -1)

            # 通带滤波
            hr_pred = butter_bandpass_batch(rppg_list, lowcut=0.6, highcut=4, fs=30)
            hr_gt = butter_bandpass_batch(bvp_list, lowcut=0.6, highcut=4, fs=30)
            print("通带滤波 hr_pred.shape: ", hr_pred.shape)
            print("通带滤波 hr_gt.shape: ", hr_gt.shape)

            # 计算预测心率和地面真值心率
            hr_pred = torch.tensor(hr_fft_batch(hr_pred, 30))
            hr_gt = torch.tensor(hr_fft_batch(hr_gt, 30))
            print("hr_fft_batch hr_pred.shape: ", hr_pred.shape)
            print("hr_fft_batch hr_gt.shape: ", hr_gt.shape)

            mae_all = mae_loss_func(hr_pred, hr_gt)
            mse_all = mse_loss_func(hr_pred, hr_gt)
            rmse = np.sqrt(mse_all)
            correlation_coefficients = []
            for i in range(num_blocks):
                # 计算每个维度的皮尔逊相关系数
                correlation_coefficient, _ = pearsonr(hr_pred[i].flatten(), hr_gt[i].flatten())
                correlation_coefficients.append(correlation_coefficient)
            print("Evaluation Result\n MAE: {:.4f}; RMSE: {:.4f}; R: {:.4f};".format(
                mae_all, rmse, sum(correlation_coefficients) / len(correlation_coefficients)))

The output of the above code shows: a tensor with shape of (2, 900) after hr_fft_batch() function shape changed to(2,), and then I applied the output tensor to the scipy.stats.pearsonr functionto find the Pearson coefficient, but error:

File "test.py", line 132, in my_main
correlation_coefficient, _ = pearsonr(hr_pred[i].flatten(), hr_gt[i].flatten())
The File "/ share1 / home/zhouwenqing/anaconda3 / envs/RPPG/lib/python3.6 / site - packages/scipy/stats/stats. Py", line 3838, in pearsonr
raise ValueError('x and y must have length at least 2.')
ValueError: x and y must have length at least 2.

That is, thepearsonr()function requires that the input arrays x and y have at least two elements, because the Pearson correlation coefficient is a statistic that measures the strength and direction of the linear relationship between two variables. What should I do about it?

zhaodongsun commented 8 months ago

To calculate Pearson correlation, you should first get the predicted HR values and GT HR values from all your video clips. Then input them into scipy.stats.pearsonr to get the Pearson correlation.

BugMaker2002 commented 8 months ago

To calculate Pearson correlation, you should first get the predicted HR values and GT HR values from all your video clips. Then input them into scipy.stats.pearsonr to get the Pearson correlation.

But isn't the function hr_fft_batch() used to calculate heart rate? The aforementioned error information indicates that the scipy.stats.pearsonr function requires that the input arrays x and y have at least two elements, however, the function hr_fft_batch() changes the tensor with shape (2, 900) to (2, 1)

zhaodongsun commented 8 months ago

hi, you should convert (2,1) to (2,) before input to scipy.stats.pearsonr.