Python PIL 抛出未知扩展错误并显示 KeyError: ''

问题描述 投票:0回答:2

我正在尝试使用 Python 在 Colab 中运行图像平铺脚本,当我尝试重命名和保存文件时,Pillow 抛出错误

这是我的脚本

import pandas as pd
import numpy as np
from PIL import Image
from shapely.geometry import Polygon, Point
from matplotlib import pyplot as plt
import glob

# get all image names
imnames_train = glob.glob('/content/content/drive/My Drive/yolor/training_data/train/*.jpg')
imnames_val = glob.glob('/content/content/drive/My Drive/yolor/training_data/val/*.jpg')
# specify path for a new tiled dataset
newpath_train = '/content/content/drive/My Drive/yolor/sampletiled/train/'
falsepath_train = '/content/content/drive/My Drive/yolor/sampletiled/false_train/'
newpath_val = '/content/content/drive/My Drive/yolor/sampletiled/val/'
falsepath_val = '/content/content/drive/My Drive/yolor/sampletiled/false_val/'
# specify slice width=height
slice_size = 416

# tile all images in a loop

for imname_train in imnames_train:
    im = Image.open(imname_train)
    imr = np.array(im, dtype=np.uint8)
    height = imr.shape[0]
    width = imr.shape[1]
    labname = imname_train.replace('.jpg', '.txt')
    labels = pd.read_csv(labname, sep=' ', names=['class', 'x1', 'y1', 'w', 'h'])
    
    # we need to rescale coordinates from 0-1 to real image height and width
    labels[['x1', 'w']] = labels[['x1', 'w']] * width
    labels[['y1', 'h']] = labels[['y1', 'h']] * height
    
    boxes = []
    
    # convert bounding boxes to shapely polygons. We need to invert Y and find polygon vertices from center points
    for row in labels.iterrows():
        x1 = row[1]['x1'] - row[1]['w']/2
        y1 = (height - row[1]['y1']) - row[1]['h']/2
        x2 = row[1]['x1'] + row[1]['w']/2
        y2 = (height - row[1]['y1']) + row[1]['h']/2

        boxes.append((int(row[1]['class']), Polygon([(x1, y1), (x2, y1), (x2, y2), (x1, y2)])))
    
    counter = 0
    print('Image:', imname_train)
    # create tiles and find intersection with bounding boxes for each tile
    for i in range((height // slice_size)):
        for j in range((width // slice_size)):
            x1 = j*slice_size
            y1 = height - (i*slice_size)
            x2 = ((j+1)*slice_size) - 1
            y2 = (height - (i+1)*slice_size) + 1

            pol = Polygon([(x1, y1), (x2, y1), (x2, y2), (x1, y2)])
            imsaved = False
            slice_labels = []

            for box in boxes:
                if pol.intersects(box[1]):
                    inter = pol.intersection(box[1])        
                    
                    if not imsaved:
                        sliced = imr[i*slice_size:(i+1)*slice_size, j*slice_size:(j+1)*slice_size]
                        sliced_im = Image.fromarray(sliced)
                        filename = imname_train.split('/')[-1]
                        slice_path = newpath_train + filename.replace('.jpg', f'_{i}_{j}.jpg')
                        
                        slice_labels_path = newpath_train + filename.replace('.jpg', f'_{i}_{j}.txt')
                        
                        print(slice_path)
                        sliced_im.save(slice_path)
                        imsaved = True                    
                    
                    # get the smallest polygon (with sides parallel to the coordinate axes) that contains the intersection
                    new_box = inter.envelope 
                    
                    # get central point for the new bounding box 
                    centre = new_box.centroid
                    
                    # get coordinates of polygon vertices
                    x, y = new_box.exterior.coords.xy
                    
                    # get bounding box width and height normalized to slice size
                    new_width = (max(x) - min(x)) / slice_size
                    new_height = (max(y) - min(y)) / slice_size
                    
                    # we have to normalize central x and invert y for yolo format
                    new_x = (centre.coords.xy[0][0] - x1) / slice_size
                    new_y = (y1 - centre.coords.xy[1][0]) / slice_size
                    
                    counter += 1

                    slice_labels.append([box[0], new_x, new_y, new_width, new_height])
            
            # save txt with labels for the current tile
            if len(slice_labels) > 0:
                slice_df = pd.DataFrame(slice_labels, columns=['class', 'x1', 'y1', 'w', 'h'])
                print(slice_df)
                slice_df.to_csv(slice_labels_path, sep=' ', index=False, header=False, float_format='%.6f')
            
            # if there are no bounding boxes intersect current tile, save this tile to a separate folder 
            if not imsaved:
                sliced = imr[i*slice_size:(i+1)*slice_size, j*slice_size:(j+1)*slice_size]
                sliced_im = Image.fromarray(sliced)
                filename = imname_train.split('/')[2]
                slice_path = falsepath_train + filename.replace('.jpg', f'_{i}_{j}.jpg')                

                sliced_im.save(slice_path)
                print('Slice without boxes saved')
                imsaved = True

这是我在 colab 控制台中遇到的错误

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
/usr/local/lib/python3.7/dist-packages/PIL/Image.py in save(self, fp, format, **params)
   2113             try:
-> 2114                 format = EXTENSION[ext]
   2115             except KeyError:

KeyError: ''

During handling of the above exception, another exception occurred:

ValueError                                Traceback (most recent call last)
1 frames
/usr/local/lib/python3.7/dist-packages/PIL/Image.py in save(self, fp, format, **params)
   2114                 format = EXTENSION[ext]
   2115             except KeyError:
-> 2116                 raise ValueError("unknown file extension: {}".format(ext))
   2117 
   2118         if format.upper() not in SAVE:

ValueError: unknown file extension: 

在脚本底部的这一行抛出错误

sliced_im.save(slice_path)

我尝试将线路更改为

sliced_im.save(slice_path,format='JPG')

这只是给了我这个错误:

KeyError                                  Traceback (most recent call last)
<ipython-input-65-93619c93028b> in <module>()
    100                 slice_path = falsepath_train + filename.replace('.jpg', f'_{i}_{j}.jpg')
    101 
--> 102                 sliced_im.save(slice_path,format = '.jpg')
    103                 print('Slice without boxes saved')
    104                 imsaved = True

/usr/local/lib/python3.7/dist-packages/PIL/Image.py in save(self, fp, format, **params)
   2121             save_handler = SAVE_ALL[format.upper()]
   2122         else:
-> 2123             save_handler = SAVE[format.upper()]
   2124 
   2125         if open_fp:

KeyError: '.JPG'

有谁知道这是什么原因造成的吗?

python image file python-imaging-library file-extension
2个回答
0
投票

使用 PIL 时不要使用 jpg 格式尝试 png


0
投票

我实际上点击了这个,因为我试图保存文件的目录不存在,并且 PILLOW 没有检查它,所以没有返回可读的错误消息。

© www.soinside.com 2019 - 2024. All rights reserved.