我正在尝试像这样用
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。
根据@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)
)。 +=
也会导致问题,因为它先添加然后更改数字,如here和here所暗示的那样,因为我的“光标变量”可以在检查segmentation[mask_i]["label]
之前移动到数组大小之外。但我认为除了增加之外我没有其他选择,因为 =+ 只是重新定义自己。
除此之外,我还添加了另一个 while 条件,以确保代码在
mask_i
低于列表大小时运行,因此程序变为“如果它仍低于列表大小,请检查掩码是否为“水”或不是“水”。
虽然程序已经完成并且可以屏蔽大部分图像,但我仍然需要记录几个不同的图像,因为并非所有图像都以“水”作为标签,而是像“海”这样接近的东西,我们人类可以直观地说它们是基本相同,但是计算机只能比较字符串而不是。
再次感谢所有愿意提供帮助的人,如果有更好的方法我会接受