如何在循环中保存PIL图像

4
我将尝试使用一个函数,该函数迭代图像位置的数据框并对这些图像进行转换,然后将它们保存回同一目录。
持有图像的数据框的头部

Head of the datafram that holds the images

我定义的函数如下:
from PIL import Image, ImageEnhance

def image_build(img, df):
    for img in df[img]:
        count = 1
        pic = df[img]
        if df['label'].any() == 0:
            im = Image.open(df[img])
            enh = ImageEnhance.Contrast(im)
            im = enh.enhance(1.9)
            im = im.rotate(90)
            im = im.transpose(Image.FLIP_LEFT_RIGHT)
            im = im.resize(224, 224)
            save_dir = 'N:/Users/Howell/Kaggle/X_Ray/chest_xray/train/NORMAL/'
            im.save(save_dir/'new_image_'+count+'.jpeg')
            count += count + 1
            print(count)

然后我尝试使用这个函数:
image_build('image', train_data)

但是我遇到了以下错误:
> --------------------------------------------------------------------------- KeyError                                  Traceback (most recent call
> last)
> C:\ProgramData\Anaconda3\envs\tensorflowenvironment\lib\site-packages\pandas\core\indexes\base.py
> in get_loc(self, key, method, tolerance)    2656             try:
> -> 2657                 return self._engine.get_loc(key)    2658             except KeyError:
> 
> pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()
> 
> pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()
> 
> pandas/_libs/hashtable_class_helper.pxi in
> pandas._libs.hashtable.PyObjectHashTable.get_item()
> 
> pandas/_libs/hashtable_class_helper.pxi in
> pandas._libs.hashtable.PyObjectHashTable.get_item()
> 
> KeyError:
> WindowsPath('N:/Users/Howell/Kaggle/X_Ray/chest_xray/train/NORMAL/IM-0580-0001.jpeg')
> 
> During handling of the above exception, another exception occurred:
> 
> KeyError                                  Traceback (most recent call
> last) <ipython-input-144-d17ac9ecd789> in <module>
> ----> 1 image_build('image', train_data)
> 
> <ipython-input-143-cf988e867715> in image_build(img, df)
>       2     for img in df[img]:
>       3         count = 1
> ----> 4         pic = df[img]
>       5         if df['label'].any() == 0:
>       6             im = Image.open(df[img])
> 
> C:\ProgramData\Anaconda3\envs\tensorflowenvironment\lib\site-packages\pandas\core\frame.py
> in __getitem__(self, key)    2925             if self.columns.nlevels
> > 1:    2926                 return self._getitem_multilevel(key)
> -> 2927             indexer = self.columns.get_loc(key)    2928             if is_integer(indexer):    2929                 indexer = [indexer]
> 
> C:\ProgramData\Anaconda3\envs\tensorflowenvironment\lib\site-packages\pandas\core\indexes\base.py
> in get_loc(self, key, method, tolerance)    2657                
> return self._engine.get_loc(key)    2658             except KeyError:
> -> 2659                 return self._engine.get_loc(self._maybe_cast_indexer(key))    2660        
> indexer = self.get_indexer([key], method=method, tolerance=tolerance) 
> 2661         if indexer.ndim > 1 or indexer.size > 1:
> 
> pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()
> 
> pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()
> 
> pandas/_libs/hashtable_class_helper.pxi in
> pandas._libs.hashtable.PyObjectHashTable.get_item()
> 
> pandas/_libs/hashtable_class_helper.pxi in
> pandas._libs.hashtable.PyObjectHashTable.get_item()
> 
> KeyError:
> WindowsPath('N:/Users/Howell/Kaggle/X_Ray/chest_xray/train/NORMAL/IM-0580-0001.jpeg')

我刚刚发现了Pillow,所以我不确定我做错了什么。
现在我将函数更改为以下内容,它可以运行而没有错误,但是什么也没有做…甚至没有print语句。
def image_build(img, df):
    for img in df[img]:
        count = 1

        if df['label'].any() == 0:
            print('pass_image')
            pic = df[img]
            im = Image.open(pic)
            enh = ImageEnhance.Contrast(im)
            img = enh.enhance(1.9)
            img = im.rotate(90)
            img = im.transpose(Image.FLIP_LEFT_RIGHT)
            img = im.resize(224, 224)
            save_dir = 'N:/Users/Howell/Kaggle/X_Ray/chest_xray/train/NORMAL/'
            img.save(save_dir / 'new_image_'+count+'.jpeg')
            count += 1

在多人的帮助下,以下代码可以运行,但只生成一张图片,并且在计数到 3 时停止打印。

from PIL import Image, ImageEnhance

def image_build(img, df):
    for index,row in df.iterrows():
        count = 1
        pic = row[img]
        if row['label'] == 0:
            im = Image.open(pic)
            enh = ImageEnhance.Contrast(im)
            im = enh.enhance(1.9)
            im = im.rotate(90)
            im = im.transpose(Image.FLIP_LEFT_RIGHT)
            im = im.resize((750, 500))
            save_dir = Path('N:/Users/Howell/Kaggle/X_Ray/chest_xray/train/NORMAL/')
            count2 = str(count)
            im.save(save_dir / str('new_image_'+count2+'.jpeg'))
            count += count + 1
            print(count)
        else:
            pass

尝试使用 count += 1 而不是 Count += count + 1,因为它们是不同的。如果你想让计数器在每次迭代中增加一次,那么应该使用 count+=1。 - Chetan Vashisth
谢谢@ChetanVashisth,但是还是出现了相同的错误。 - Jordan
@Jordon,请检查您为图像定义的路径?只是为了确保。 - Chetan Vashisth
1
我做到了。当我将图像序列从循环中取出并在Image.open()命令中运行train_data['image'][0]时,它可以工作。 - Jordan
如果可以的话,尝试下面的代码,兄弟 @Jordon - Chetan Vashisth
4个回答

1
你再次使用了相同的变量img。
from PIL import Image, ImageEnhance

def image_build(img, df):
    for index,row in df.iterrows():
        count = 1
        pic = row[img]
        if row['label'] == 0:
            im = Image.open(pic)
            enh = ImageEnhance.Contrast(im)
            im = enh.enhance(1.9)
            im = im.rotate(90)
            im = im.transpose(Image.FLIP_LEFT_RIGHT)
            im = im.resize(224, 224)
            save_dir = 'N:/Users/Howell/Kaggle/X_Ray/chest_xray/train/NORMAL'
            im.save(f'{save_dir}/new_image_{count}.jpeg'))
            count += count + 1
            print(count)

谢谢,我收到了 TypeError: 'WindowsPath' object is not subscriptable 的错误。 - Jordan
使用相同的变量img并不重要,兄弟。我已经执行了我发布的相同代码,并且它可以正常运行,没有任何错误。 - Chetan Vashisth

AttributeError Traceback (most recent call last): <ipython-input-330-d17ac9ecd789> in <module> ----> 1 image_build('image', train_data)<ipython-input-329-1bf389a1a05c> in image_build(img, df) 5 count = 1 6 pic = row[img] ----> 7 if row['label'].any() == 0: 8 im = Image.open(pic) 9 enh = ImageEnhance.Contrast(im)属性错误:'int'对象没有属性 'any'。
- Jordan
15 im.save(save_dir/'new_image_'+count+'.jpeg') 16 count += count + 1 17 print(count)类型错误:不支持在字符串和字符串之间使用“/”操作符。 - Jordan
好的@SmartManoj。 我已经让循环运行了,但是它只生成了一个图像到文件夹中。 请查看我的上面的编辑。 - Jordan
谢谢SmartManoj。我已经解决了。请看我的答案。将count = 1放在for语句外面。 - Jordan

0

如果可以的话,请尝试这个:

def image_build(img, df):
    count = 1  #  define count here so that it do not get intialised for each iteration
    for img in df[img]:
        pic = df[img]
        if df['label'].any() == 0:
            im = Image.open('your_image_path')
            enh = ImageEnhance.Contrast(im)
            img = enh.enhance(1.9)
            img = im.rotate(90)
            img = im.transpose(Image.FLIP_LEFT_RIGHT)
            img = im.resize((224, 224))
            save_dir = 'your path'
            img.save(save_dir + 'new_image_'+'1'+'.jpeg')
            count += 1 

KeyError: WindowsPath('N:/Users/Howell/Kaggle/X_Ray/chest_xray/train/PNEUMONIA/person1286_bacteria_3249.jpeg') - Jordan
我不确定它选择了哪条路径,因为它对应的“标签”是1而不是0。 - Jordan
你想对图像执行不同的操作,然后将它们以新名称保存回同一目录中,是吗?这正是你想做的事情吗? - Chetan Vashisth
尝试使用此链接,它将帮助您 https://www.sitepoint.com/manipulating-images-with-the-python-imaging-library/ - Chetan Vashisth
我认为可能是我的 if 语句的问题。请查看更新后的问题。现在它可以运行而没有错误,但是没有生成任何图片。 - Jordan
显示剩余2条评论

0

好的。我终于搞定了!将计数器移到 iterrows() 之前。

已编辑

from PIL import Image, ImageEnhance

def image_build(img, df):
    count = 1
    for index,row in df.iterrows():
        pic = row[img]
        if row['label'] == 0:
            im = Image.open(pic)
            enh = ImageEnhance.Contrast(im)
            im = enh.enhance(1.9)
            im = im.rotate(90)
            im = im.transpose(Image.FLIP_LEFT_RIGHT)
            im = im.resize((750, 500))
            save_dir = Path('N:/Users/Howell/Kaggle/X_Ray/chest_xray/train/NORMAL/')
            count2 = str(count)
            im.save(save_dir + str('new_image_'+count2+'.jpeg'))
            count += count + 1
            print(count)
        else:
            pass

-2

我认为这个问题出在文件路径上。将 / 替换为 \\(双反斜杠)或者 \


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接