问题描述
我对编码还很陌生,因此感谢您的帮助,如果很明显,我们对此表示歉意。
full_image_list = glob.glob(WORKING_DIR+'/data/JPEGImages/*.jpg')
fnames,classes = [],[]
for jpg_fname in full_image_list:
fs,data = return_yolo_data(jpg_fname,ann_dir=WORKING_DIR+'/data/Annotations/')
for f,d in zip(fs,data):
fnames.append(f)
> ---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
~/.virtualenvs/dl4cv/lib/python3.8/site-packages/numpy/lib/npyio.py in genfromtxt(fname,dtype,comments,delimiter,skip_header,skip_footer,converters,missing_values,filling_values,usecols,names,excludelist,deletechars,replace_space,autostrip,case_sensitive,defaultfmt,unpack,usemask,loose,invalid_raise,max_rows,encoding)
1753 fid_ctx = contextlib_nullcontext(fid)
-> 1754 fhd = iter(fid)
1755 except TypeError:
TypeError: 'nonetype' object is not iterable
During handling of the above exception,another exception occurred:
TypeError Traceback (most recent call last)
<ipython-input-187-80766db0462f> in <module>
2
3 for jpg_fname in full_image_list:
----> 4 fs,ann_dir=WORKING_DIR+'/data/Annotations/')
5 for f,data):
6 fnames.append(f)
<ipython-input-159-ecbad441c355> in return_yolo_data(jpg_fname,ann_dir)
19 base_fname = jpg_fname.split('/')[-1] # no path
20 txt_fname = get_yolo_file(base_fname,dir_=ann_dir)
---> 21 data = np.genfromtxt(txt_fname,names='class,x,y,w,h')
22 # don't fail if there is only one labeled object in an image
23 data = np.atleast_1d(data)
~/.virtualenvs/dl4cv/lib/python3.8/site-packages/numpy/lib/npyio.py in genfromtxt(fname,encoding)
1754 fhd = iter(fid)
1755 except TypeError:
-> 1756 raise TypeError(
1757 "fname must be a string,filehandle,list of strings,"
1758 "or generator. Got %s instead." % type(fname))
TypeError: fname must be a string,or generator. Got <class 'nonetype'> instead.
如果我使用此代码:
full_image_list = glob.glob(WORKING_DIR+'/data/JPEGImages/*.jpg')
fnames,data):
print(f)
然后迭代显示每个文件的名称,每个文件都显示在单独的行中,并且没有逗号/语法,然后再显示相同的错误。
def get_yolo_file(fname,dir_=WORKING_DIR+'/data/Annotations/'):
'''
takes image filename and returns annotation filename
e.g. data/JPEGImages/IMG_XXX.jpg
data/Annotations/IMG_XXX.txt
'''
txt_file = fname.replace('.jpg','.txt')
full_path = '/'.join([dir_,txt_file])
if os.path.isfile(full_path):
return full_path
else:
print('ERROR')
return None
def return_yolo_data(jpg_fname,ann_dir=WORKING_DIR+'/data/Annotations/'):
'''
Reads annotation file,returns name and data
'''
base_fname = jpg_fname.split('/')[-1] # no path
txt_fname = get_yolo_file(base_fname,dir_=ann_dir)
data = np.genfromtxt(txt_fname,h')
# don't fail if there is only one labeled object in an image
data = np.atleast_1d(data)
# keep file name associated with each label
fname_arr = [base_fname]*data.shape[0]
return fname_arr,data
def str_class(val):
'''
Return string label for index.
YOLO is zero indexed.
'''
if val == 0:
return 'one'
elif val == 1:
return 'two'
elif val == 2:
return 'three'
elif val == 3:
return 'four'
elif val == 4:
return 'five'
elif val == 5:
return 'six'
def create_image_dict(image_list,ann_dir=WORKING_DIR+'/data/Annotations/'):
'''
For input list of images,return a dictionary with label information.
dictionary keys: image file,class (string),h,w
'''
# empty lists for dictionary
fnames,[]
x,w = [],[],[]
for jpg_fname in image_list:
fs,ann_dir=ann_dir)
for f,data):
fnames.append(f)
classes.append(str_class(d['class']))
x.append(d['x'])
y.append(d['y'])
h.append(d['h'])
w.append(d['w'])
out_dict = {'filename':fnames,'class':classes,'x':x,'y':y,'h':h,'w':w}
return out_dict
解决方法
Got <class 'NoneType'> instead.
此错误消息明确指出了问题... os.path.isfile(full_path)
返回False
,因此get_yolo_file
返回None
。
所以txt_fname == None
。正如错误所言,np.genfromtxt
的文件路径不能为None
。
因此,而不是“打印”错误(print('ERROR')
),您应该执行以下操作:
class MyException(Exception):
pass
def get_yolo_file(fname,dir_=WORKING_DIR+'/data/Annotations/'):
'''
takes image filename and returns annotation filename
e.g. data/JPEGImages/IMG_XXX.jpg
data/Annotations/IMG_XXX.txt
'''
txt_file = fname.replace('.jpg','.txt')
full_path = '/'.join([dir_,txt_file])
if os.path.isfile(full_path):
return full_path
else:
raise MyException("File path is wrong!")
这将引发一个错误,提示File path is wrong!
,并终止程序的执行。
关于os.path.isfile(full_path)
返回False
的原因,您将必须检查该文件在该位置是否实际存在,并且所创建的路径是否是该文件的实际路径。
有关自定义例外的更多信息,请参见custom exceptions
,def get_yolo_file(fname,dir_=WORKING_DIR+'/data/Annotations/'):
'''
takes image filename and returns annotation filename
e.g. data/JPEGImages/IMG_XXX.jpg
data/Annotations/IMG_XXX.txt
'''
txt_file = fname.replace('.jpg','.txt')
full_path = '/'.join([dir_,txt_file])
if os.path.isfile(full_path):
return full_path
else:
print('ERROR')
return None
我将full_path中的“ /”替换为“”。由于错误每次都被抛出,所以我知道所有文件都存在。这解决了这个问题。
然后注意到我缺少一个.txt文件(感谢@Hampus Larrson,让我走上正确的道路来解决这一部分)