复现ESRGAN程序时遭遇AttributeError及libpng读取错误求助
libpng error: Read Error & AttributeError: 'NoneType' object has no attribute 'astype' in ESRGAN Training Your error chain starts with a corrupted/unreadable PNG image that cv2.imread() can't parse, returning None. When the code tries to call img.astype(np.float32) on this None value, it throws the AttributeError. Here's how to diagnose and fix this step by step:
1. First: Identify the Broken Image File
The first priority is finding exactly which image is causing the failure. Modify your read_img function in /sda/ZTL/B/data/util.py to add error checking and logging:
def read_img(env, path): # read image by cv2 or from lmdb # return: Numpy float32, HWC, BGR, [0,1] if env is None: img = cv2.imread(path, cv2.IMREAD_UNCHANGED) # Add check for failed reads if img is None: print(f"CRITICAL: Failed to load image at path: {path}") raise ValueError(f"Corrupted or inaccessible image file: {path}") else: img = _read_lmdb_img(env, path) if img is None: print(f"CRITICAL: Failed to load LMDB image with key: {path}") raise ValueError(f"Corrupted LMDB image entry: {path}") img = img.astype(np.float32) / 255. if img.ndim == 2: img = np.expand_dims(img, axis=2) if img.shape[2] > 3: img = img[:, :, :3] return img
Run your training again—this will print the exact path of the problematic image, so you can target the issue directly.
2. Fix or Replace the Problematic Image
Once you have the failing image path:
- Try opening it with a standard image viewer (like Windows Photos, Preview on Mac, or GIMP). If it won't open, the file is corrupted—delete it or replace it with a valid image of the same dimensions.
- If it opens but still fails in OpenCV, save it as a standard PNG using an image editor (this fixes compatibility issues with non-standard PNG compression).
3. Add Fault Tolerance to Your Data Loader
If you're working with a large dataset and don't want to manually fix every broken image, modify the __getitem__ method in /sda/ZTL/B/data/LRHR_dataset.py to skip corrupted files automatically:
def __getitem__(self, index): HR_path, LR_path = None, None scale = self.opt['scale'] HR_size = self.opt['HR_size'] HR_path = self.paths_HR[index] # Handle corrupted HR images try: img_HR = util.read_img(self.HR_env, HR_path) except ValueError as e: print(f"Skipping corrupted HR image: {HR_path}") # Recursively get the next valid sample return self.__getitem__((index + 1) % len(self.paths_HR)) if self.opt['phase'] != 'train': img_HR = util.modcrop(img_HR, scale) if self.opt['color']: img_HR = util.channel_convert(img_HR.shape[2], self.opt['color'], [img_HR])[0] if self.paths_LR: LR_path = self.paths_LR[index] # Handle corrupted LR images try: img_LR = util.read_img(self.LR_env, LR_path) except ValueError as e: print(f"Skipping corrupted LR image: {LR_path}") return self.__getitem__((index + 1) % len(self.paths_HR)) else: # Existing code to generate LR images... if self.opt['phase'] == 'train': random_scale = random.choice(self.random_scale_list) H_s, W_s, _ = img_HR.shape def _mod(n, random_scale, scale, thres): rlt = int(n * random_scale) rlt = (rlt // scale) * scale return thres if rlt < thres else rlt H_s = _mod(H_s, random_scale, scale, HR_size) W_s = _mod(W_s, random_scale, scale, HR_size) img_HR = cv2.resize(np.copy(img_HR), (W_s, H_s), interpolation=cv2.INTER_LINEAR) if img_HR.ndim == 2: img_HR = cv2.cvtColor(img_HR, cv2.COLOR_GRAY2BGR) H, W, _ = img_HR.shape img_LR = util.imresize_np(img_HR, 1 / scale, True) if img_LR.ndim == 2: img_LR = np.expand_dims(img_LR, axis=2) # Remaining training code... if self.opt['phase'] == 'train': H, W, _ = img_HR.shape if H < HR_size or W < HR_size: img_HR = cv2.resize(np.copy(img_HR), (HR_size, HR_size), interpolation=cv2.INTER_LINEAR) img_LR = util.imresize_np(img_HR, 1 / scale, True) if img_LR.ndim == 2: img_LR = np.expand_dims(img_LR, axis=2) H, W, C = img_LR.shape LR_size = HR_size // scale rnd_h = random.randint(0, max(0, H - LR_size)) rnd_w = random.randint(0, max(0, W - LR_size)) img_LR = img_LR[rnd_h:rnd_h + LR_size, rnd_w:rnd_w + LR_size, :] rnd_h_HR, rnd_w_HR = int(rnd_h * scale), int(rnd_w * scale) img_HR = img_HR[rnd_h_HR:rnd_h_HR + HR_size, rnd_w_HR:rnd_w_HR + HR_size, :] img_LR, img_HR = util.augment([img_LR, img_HR], self.opt['use_flip'], self.opt['use_rot']) if self.opt['color']: img_LR = util.channel_convert(C, self.opt['color'], [img_LR])[0] if img_HR.shape[2] == 3: img_HR = img_HR[:, :, [2, 1, 0]] img_LR = img_LR[:, :, [2, 1, 0]] img_HR = torch.from_numpy(np.ascontiguousarray(np.transpose(img_HR, (2, 0, 1)))).float() img_LR = torch.from_numpy(np.ascontiguousarray(np.transpose(img_LR, (2, 0, 1)))).float() if LR_path is None: LR_path = HR_path return {'LR': img_LR, 'HR': img_HR, 'LR_path': LR_path, 'HR_path': HR_path}
This will skip any broken images and continue training without interruption.
4. Bonus: Check for Other Potential Issues
- Verify Dataset Paths: Double-check that
self.paths_HRandself.paths_LRcontain valid absolute paths (or paths relative to your training script's working directory). - Disk Health: Use
df -hto check if your disk is full, and review system logs to rule out IO errors that could cause partial/corrupted image files.
Error Context (From Your Report)
Full Error Stack:
libpng error: Read Error Traceback (most recent call last): File "/sda/ZTL/B/codes/train.py", line 173, in <module> main() File "/sda/ZTL/B/codes/train.py", line 97, in main for _, train_data in enumerate(train_loader): File "/root/anaconda3/lib/python3.6/site-packages/torch/utils/data/dataloader.py", line 637, in __next__ return self._process_next_batch(batch) File "/root/anaconda3/lib/python3.6/site-packages/torch/utils/data/dataloader.py", line 658, in _process_next_batch raise batch.exc_type(batch.exc_msg) AttributeError: Traceback (most recent call last): File "/root/anaconda3/lib/python3.6/site-packages/torch/utils/data/dataloader.py", line 138, in _worker_loop samples = collate_fn([dataset[i] for i in batch_indices]) File "/root/anaconda3/lib/python3.6/site-packages/torch/utils/data/dataloader.py", line 138, in <listcomp> samples = collate_fn([dataset[i] for i in batch_indices]) File "/sda/ZTL/B/data/LRHR_dataset.py", line 51, in __getitem__ img_HR = util.read_img(self.HR_env, HR_path) File "/sda/ZTL/B/data/util.py", line 79, in read_img img = img.astype(np.float32) / 255. AttributeError: 'NoneType' object has no attribute 'astype'
Training Log Snippet:
19-08-30 06:12:28.193 - INFO: l_g_pix: 3.9939e-03 l_g_fea: 2.3352e+00 l_g_gan: 1.0448e-01 l_d_real: 1.5721e-06 l_d_fake: 1.6599e-05 D_real: 7.0139e+00 D_fake: -1.3881e+01 19-08-30 06:14:34.038 - INFO: l_g_pix: 2.9632e-03 l_g_fea: 1.7633e+00 l_g_gan: 7.9122e-02 l_d_real: 5.6028e-06 l_d_fake: 4.7490e-05 D_real: 7.1848e+00 D_fake: -8.6396e+00 19-08-30 06:16:38.986 - INFO: l_g_pix: 3.6181e-03 l_g_fea: 2.2983e+00 l_g_gan: 3.5791e-02 l_d_real: 3.3302e-03 l_d_fake: 2.6311e-03 D_real: 1.6663e+01 D_fake: 9.5084e+00 19-08-30 06:18:42.645 - INFO: l_g_pix: 3.9908e-03 l_g_fea: 2.1037e+00 l_g_gan: 5.0026e-02 l_d_real: 2.2486e-04 l_d_fake: 7.5957e-04 D_real: 1.0516e+00 D_fake: -8.9531e+00 libpng error: Read Error Traceback (most recent call last): ………………
内容的提问来源于stack exchange,提问作者TimmyCheung

