创建“for”或“if-else”选择器来检查动态大小的Python列表

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

我正在尝试像这样用

transformers
掩盖8752张图像

from transformers import pipeline
from PIL import Image
import requests
import cv2

import numpy as np
from matplotlib import pyplot as plt


semantic_segmentation_nvidia = pipeline("image-segmentation", "nvidia/segformer-b0-finetuned-ade-512-512")
jpeg_im = None
a = 0
mask_i = 0

f = open("masking_log.txt", "w")


for im in large_image_stack_512:
    i=0 
    while(i == 0):
        
        jpeg_im = Image.open(os.path.join(ROOT_DIR,im))
        print(os.path.join(ROOT_DIR,im))
        # Semantic segmentation
        segmentation = semantic_segmentation_nvidia(jpeg_im)
        print("the length of current segmentation labels are: ", len(segmentation))
        water_mask_label = segmentation[mask_i]["label"]
        print(water_mask_label)
        print("here")    
        if (water_mask_label == "water"):
            print("Successful labelling at: ", mask_i)
            water_mask = segmentation[mask_i]["mask"]
            print("here")
            imar = np.asarray(water_mask)
            print(water_mask_label)
            print("type im (array)", type(imar))
            f.write("image " + str(a) + "\nsuccess-label at " + str(mask_i) + "\nwith dir: " + str(im)  + "\n with mask labeled as: " + str(water_mask_label) + '\n\n')
            plt.imsave('D:\..\Data\'+'img_'+str(a)+'.jpg', imar, cmap="gray")  
            i=1
            a+=1
            mask_i= 0
            semantic_jpeg = None
            imar = None
            water_mask = None
            water_mask_label = None
            segmentation = None
            water_mask_label = None
        else:       
            print("not water")
            if (mask_i < len(segmentation)):
                mask_i += 1
            else:
                f.write("image " + str(a) + "\n unsuccess-labelling (has no 'water' label)" + "final mask_i value: " + str(mask_i) + "\nwith dir: " + str(im)  + "\n check later " +  + '\n\n')
                print("masking fails, check later image" + im)
                i = 1
                continue
            
            
        #plt.imshow(water_mask)
        #plt.show()
        #print("type jpeg_im (jpeg)", type(water_mask))
    continue   
       
#print(len(cropped))
f.close()

每个

segmentation = semantic_segmentation_nvidia(jpeg_im)
都会有不同大小的数组,例如在这张图片中,我里面有 11 个项目,如下所示:

代码(在 jupyter 笔记本行中执行此操作)

a_512 = semantic_segmentation_nvidia(image_512)
a_512

输出,

a_512
变量是一个
List
,里面有11个项目

[{'score': None,
  'label': 'wall',
  'mask': <PIL.Image.Image image mode=L size=512x512>},
 {'score': None,
  'label': 'building',
  'mask': <PIL.Image.Image image mode=L size=512x512>},
 {'score': None,
  'label': 'sky',
  'mask': <PIL.Image.Image image mode=L size=512x512>},
 {'score': None,
  'label': 'tree',
  'mask': <PIL.Image.Image image mode=L size=512x512>},
 {'score': None,
  'label': 'earth',
  'mask': <PIL.Image.Image image mode=L size=512x512>},
 {'score': None,
  'label': 'water',
  'mask': <PIL.Image.Image image mode=L size=512x512>},
 {'score': None,
  'label': 'fence',
  'mask': <PIL.Image.Image image mode=L size=512x512>},
 {'score': None,
  'label': 'railing',
  'mask': <PIL.Image.Image image mode=L size=512x512>},
 {'score': None,
  'label': 'bridge',
  'mask': <PIL.Image.Image image mode=L size=512x512>},
 {'score': None,
  'label': 'ship',
  'mask': <PIL.Image.Image image mode=L size=512x512>},
 {'score': None,
  'label': 'pier',
  'mask': <PIL.Image.Image image mode=L size=512x512>}]

要访问我需要的东西,可能是“标签”,我需要像这样访问每个列表项中的

PIL.Image.Image
数据

(a_512[5]["mask"]

在上面的代码中,我在这段代码中使用了一个变量来表示

5
,因为显然每个图像在检测到“水”作为标签以及所需的掩模时都有不同的顺序。

因为 python 可以比较字符串,所以我尝试制作一个

for loop
来检查每 8752 个图像列表中的每个项目。假设某些图像可以有 10-12 个项目,就像最终运行的输出一样。

D:\..\Data\cropped_512\img_2541.jpg
the length of current segmentation labels are:  15
car
here
not water
D:\..\Data\cropped_512\img_2541.jpg
the length of current segmentation labels are:  15
water
here
Successful labelling at:  7
here
water
type im (array) <class 'numpy.ndarray'>
D:\..\Data\cropped_512\img_2542.jpg
the length of current segmentation labels are:  12
wall
here
not water
D:\..\Data\cropped_512\img_2542.jpg
the length of current segmentation labels are:  12
building
here
not water
D:\..\Data\cropped_512\img_2542.jpg
the length of current segmentation labels are:  12
sky
here
not water
D:\..\Data\cropped_512\img_2542.jpg
the length of current segmentation labels are:  12
tree
here
not water
D:\..\Data\cropped_512\img_2542.jpg
the length of current segmentation labels are:  12
road
here
not water
D:\..\Data\cropped_512\img_2542.jpg
the length of current segmentation labels are:  12
mountain
here
not water
D:\..\Data\cropped_512\img_2542.jpg
the length of current segmentation labels are:  12
car
here
not water
D:\..\Data\cropped_512\img_2542.jpg
the length of current segmentation labels are:  12
sea
here
not water
D:\..\Data\cropped_512\img_2542.jpg
the length of current segmentation labels are:  12
fence
here
not water
D:\..\Data\cropped_512\img_2542.jpg
the length of current segmentation labels are:  12
bridge
here
not water
D:\..\Data\cropped_512\img_2542.jpg
the length of current segmentation labels are:  12
boat
here
not water
D:\..\Data\cropped_512\img_2542.jpg
the length of current segmentation labels are:  12
ship
here
not water
D:\..\Data\cropped_512\img_2542.jpg
the length of current segmentation labels are:  12

---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In[16], line 17
     15 segmentation = semantic_segmentation_nvidia(jpeg_im)
     16 print("the length of current segmentation labels are: ", len(segmentation))
---> 17 water_mask_label = segmentation[mask_i]["label"]
     18 print(water_mask_label)
     19 print("here")    

IndexError: list index out of range

正如您所看到的,索引不断增加,并且没有触及 if-else 比较器的最后一个 else,因此它超出了范围。我已经尝试过这个并在 for 循环上使用

range
但它不起作用并且仍然超出范围。我放置了break,它停止了循环,我放置了continue,它继续运行
out of bounds
。我做错了哪一部分并且对python比较器行为的理解不正确?

我还尝试将其记录到 .txt 文件中或使用

print
给出状态,但它并没有那样做并且总是超出范围。如果需要,我们很乐意添加更多详细信息。图像尺寸为 512 x 512。

python arrays list loops huggingface-transformers
1个回答
0
投票

根据@OldBoy输入移动增量解决问题。

完整代码

mask_i = 0
a = 0

f = open("masking_log.txt", "w")

for im in large_image_stack_512:
    image_success_flag = 0
    mask_i= 0
    
    while(image_success_flag < 1):
        jpeg_im = Image.open(os.path.join(ROOT_DIR,im))
        print(os.path.join(ROOT_DIR,im))
        # Semantic segmentation
        segmentation = semantic_segmentation_nvidia(jpeg_im)
        print("the length of current segmentation labels are: ", len(segmentation))
        while(mask_i < len(segmentation)):
           image_mask = segmentation[mask_i]["label"]
           print(image_mask)
           if(image_mask == "water"):
               print("correct mask")
               water_mask = segmentation[mask_i]["mask"]
               imar = np.asarray(water_mask)
               plt.imsave('D:/semester_12/Data_Irredeano/'+'img_'+str(a)+'.jpg', imar, cmap="gray") 
               print("here")
               f.write("image " + str(a) + "\nsuccess-label at " + str(mask_i) + "\nwith dir: " + str(im)  + "\n with mask labeled as: " + str(water_mask_label) + '\n\n')
               print("mask-succesfully saved")
               mask_i = 0 
               break
           elif(image_mask != "water"):
               mask_i+=1
               print("number of mask: ", mask_i)
               if(mask_i == len(segmentation)):
                    print("this image has no correct mask, check later")
                    f.write("image " + str(a) + "\n unsuccess-labelling (has no 'water' label) final \n mask_i value: " + str(mask_i) + "\nwith dir: " + str(im)  + "\n check later " + '\n\n')
               image_success_flag=+1  
        a+=1


f.close()

基本上不是通过检查

segmentation[mask_i]["label]
来选择掩码,而是检查“光标”或
mask_i
是否小于列表的长度(
len(segmentation)
)。
+=
也会导致问题,因为它先添加然后更改数字,如herehere所暗示的那样,因为我的“光标变量”可以在检查
segmentation[mask_i]["label]
之前移动到数组大小之外。但我认为除了增加之外我没有其他选择,因为 =+ 只是重新定义自己。

除此之外,我还添加了另一个 while 条件,以确保代码在

mask_i
低于列表大小时运行,因此程序变为“如果它仍低于列表大小,请检查掩码是否为“水”或不是“水”。

虽然程序已经完成并且可以屏蔽大部分图像,但我仍然需要记录几个不同的图像,因为并非所有图像都以“水”作为标签,而是像“海”这样接近的东西,我们人类可以直观地说它们是基本相同,但是计算机只能比较字符串而不是。

再次感谢所有愿意提供帮助的人,如果有更好的方法我会接受

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