How can i save the name of objects in python in specific order?
Question:
I am trying to save the name of objects as image in specific order. Like if there are seven objects detected in image and their names are [chair, tv, bed, chair ,bed, chair, chair]. I want that it should be saved as [chair.png, chair1.png, chair2.png, chair3.png, bed.png, bed1.png, tv.png]
. No matter what objects comes first but its numbers should remains in sequential order respectively. I am trying but is it giving me results like: [bed.png, bed2.png, chair.png, chair1.png, chair3.png, chair4.png, tv.png]
. I guess i have not setted the count variable correctly but I am unable to find it out
My code:
%cd /content/drive/MyDrive/Now_fine/yolov7-mask/binary_masks_images
folder_name = 'my_folder_' + time.strftime("%Y_%m_%d_%H_%M_%S")
os.mkdir(folder_name)
count = 0
for one_mask, bbox, cls, conf in zip(pred_masks_np, nbboxes, pred_cls, pred_conf):
if conf < 0.25:
continue
else:
label = names[int(cls)]
print(label)
if os.path.exists('/content/drive/MyDrive/Now_fine/yolov7-mask/binary_masks_images/'+folder_name+'/'+label+'.png'):
count+=1
plt.imsave('/content/drive/MyDrive/Now_fine/yolov7-mask/binary_masks_images/'+folder_name+'/'+label+str(count)+'.png', one_mask, cmap='gray')
else:
plt.imsave('/content/drive/MyDrive/Now_fine/yolov7-mask/binary_masks_images/'+folder_name+'/'+label+'.png', one_mask, cmap='gray')
Answers:
The issue is that you are not counting different items, but incrementing the counter for every new item. One option would be to keep different counts in a dictionary e.g. item_counts = {'chair': 0, 'bed': 1, 'tv': 0}
or sort the source data so that items always come in correct order. Other solution would be to count the existing items with a helper functions such as this before saving:
def count_files(filename):
dir_path = r'.'
count = 0
for path in os.listdir(dir_path):
if os.path.isfile(os.path.join(dir_path, path)) and filename in path:
count += 1
return count
# Counts files with word 'bed' in name
print(count_files('bed'))
You use the same count
for all names – but for every name you should have separated count
.
You could create dictionary at start
count = {} # dictionary
Inside loop you could check if label
exists in dictionary
if label not in count:
count[label] = 0
and you could use it to count and generate filename
count[label] += 1
name = f'{label}{count[label]}.png'
plt.imsave('/content/drive/MyDrive/Now_fine/yolov7-mask/binary_masks_images/'+folder_name+'/'+name, one_mask, cmap='gray')
Something like this:
BASE = '/content/drive/MyDrive/Now_fine/yolov7-mask/binary_masks_images/'
count = {} # dictionary
for one_mask, bbox, cls, conf in zip(pred_masks_np, nbboxes, pred_cls, pred_conf):
if conf < 0.25:
continue
else:
label = names[int(cls)]
print(label)
if label not in count:
count[label] = 0
if os.path.exists(os.path.join(BASE, folder_name, f'{label}.png')):
count[label] += 1
name = f'{label}{count[label]}.png'
else:
name = f'{label}png'
plt.imsave(os.path.join(BASE, folder_name, name), one_mask, cmap='gray')
You could even use count
instead of exists
BASE = '/content/drive/MyDrive/Now_fine/yolov7-mask/binary_masks_images/'
count = {} # dictionary
for one_mask, bbox, cls, conf in zip(pred_masks_np, nbboxes, pred_cls, pred_conf):
if conf < 0.25:
continue
else:
label = names[int(cls)]
print(label)
if label not in count:
count[label] = 0
if count[label] == 0:
name = f'{label}png'
else:
name = f'{label}{count[label]}.png'
plt.imsave(os.path.join(BASE, folder_name, name), one_mask, cmap='gray')
count[label] += 1
Frankly I would start names with 0
– chair0.png
, bed0.png
, etc. Or I would use 1
for first image – chair1.png
instead of chair.png
This way all code would be simpler.
If you use many images then I would use names like chair001.png
to keep order – because Python (and system) will sort string "10"
before "2"
, but it will keep order if you use "02"
# use :03 to get 3 digits filled with `0` - like `002`
name = f'{label}{count[label]:03}.png'
I am trying to save the name of objects as image in specific order. Like if there are seven objects detected in image and their names are [chair, tv, bed, chair ,bed, chair, chair]. I want that it should be saved as [chair.png, chair1.png, chair2.png, chair3.png, bed.png, bed1.png, tv.png]
. No matter what objects comes first but its numbers should remains in sequential order respectively. I am trying but is it giving me results like: [bed.png, bed2.png, chair.png, chair1.png, chair3.png, chair4.png, tv.png]
. I guess i have not setted the count variable correctly but I am unable to find it out
My code:
%cd /content/drive/MyDrive/Now_fine/yolov7-mask/binary_masks_images
folder_name = 'my_folder_' + time.strftime("%Y_%m_%d_%H_%M_%S")
os.mkdir(folder_name)
count = 0
for one_mask, bbox, cls, conf in zip(pred_masks_np, nbboxes, pred_cls, pred_conf):
if conf < 0.25:
continue
else:
label = names[int(cls)]
print(label)
if os.path.exists('/content/drive/MyDrive/Now_fine/yolov7-mask/binary_masks_images/'+folder_name+'/'+label+'.png'):
count+=1
plt.imsave('/content/drive/MyDrive/Now_fine/yolov7-mask/binary_masks_images/'+folder_name+'/'+label+str(count)+'.png', one_mask, cmap='gray')
else:
plt.imsave('/content/drive/MyDrive/Now_fine/yolov7-mask/binary_masks_images/'+folder_name+'/'+label+'.png', one_mask, cmap='gray')
The issue is that you are not counting different items, but incrementing the counter for every new item. One option would be to keep different counts in a dictionary e.g. item_counts = {'chair': 0, 'bed': 1, 'tv': 0}
or sort the source data so that items always come in correct order. Other solution would be to count the existing items with a helper functions such as this before saving:
def count_files(filename):
dir_path = r'.'
count = 0
for path in os.listdir(dir_path):
if os.path.isfile(os.path.join(dir_path, path)) and filename in path:
count += 1
return count
# Counts files with word 'bed' in name
print(count_files('bed'))
You use the same count
for all names – but for every name you should have separated count
.
You could create dictionary at start
count = {} # dictionary
Inside loop you could check if label
exists in dictionary
if label not in count:
count[label] = 0
and you could use it to count and generate filename
count[label] += 1
name = f'{label}{count[label]}.png'
plt.imsave('/content/drive/MyDrive/Now_fine/yolov7-mask/binary_masks_images/'+folder_name+'/'+name, one_mask, cmap='gray')
Something like this:
BASE = '/content/drive/MyDrive/Now_fine/yolov7-mask/binary_masks_images/'
count = {} # dictionary
for one_mask, bbox, cls, conf in zip(pred_masks_np, nbboxes, pred_cls, pred_conf):
if conf < 0.25:
continue
else:
label = names[int(cls)]
print(label)
if label not in count:
count[label] = 0
if os.path.exists(os.path.join(BASE, folder_name, f'{label}.png')):
count[label] += 1
name = f'{label}{count[label]}.png'
else:
name = f'{label}png'
plt.imsave(os.path.join(BASE, folder_name, name), one_mask, cmap='gray')
You could even use count
instead of exists
BASE = '/content/drive/MyDrive/Now_fine/yolov7-mask/binary_masks_images/'
count = {} # dictionary
for one_mask, bbox, cls, conf in zip(pred_masks_np, nbboxes, pred_cls, pred_conf):
if conf < 0.25:
continue
else:
label = names[int(cls)]
print(label)
if label not in count:
count[label] = 0
if count[label] == 0:
name = f'{label}png'
else:
name = f'{label}{count[label]}.png'
plt.imsave(os.path.join(BASE, folder_name, name), one_mask, cmap='gray')
count[label] += 1
Frankly I would start names with 0
– chair0.png
, bed0.png
, etc. Or I would use 1
for first image – chair1.png
instead of chair.png
This way all code would be simpler.
If you use many images then I would use names like chair001.png
to keep order – because Python (and system) will sort string "10"
before "2"
, but it will keep order if you use "02"
# use :03 to get 3 digits filled with `0` - like `002`
name = f'{label}{count[label]:03}.png'