You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

复现ESRGAN程序时遭遇AttributeError及libpng读取错误求助

Fixing 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_HR and self.paths_LR contain valid absolute paths (or paths relative to your training script's working directory).
  • Disk Health: Use df -h to 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:09:17