Track-Anything icon indicating copy to clipboard operation
Track-Anything copied to clipboard

export masks?

Open TanvirHafiz opened this issue 1 year ago • 12 comments

Can I export the tracked object as a mask? is it built in to this? (I cant seem to find it). Also, I am no programmer!

TanvirHafiz avatar Apr 27 '23 12:04 TanvirHafiz

Here, you can uncomment this line to save the maks. https://github.com/gaomingqi/Track-Anything/blob/57c28bc6b6288f792435f8ddd6830626b2b7cf10/app.py#L380 And you can change the mask save directory here. https://github.com/gaomingqi/Track-Anything/blob/57c28bc6b6288f792435f8ddd6830626b2b7cf10/app.py#L278-L285

memoryunreal avatar Apr 27 '23 14:04 memoryunreal

the extracted files are ,npy is it possible to have them as a png or jpeg?

ahakagei avatar Apr 27 '23 16:04 ahakagei

the extracted files are ,npy is it possible to have them as a png or jpeg?

Yes, you can add

from PIL import Image

in the first line and replace line 284 with

Image.fromarray(mask).save("/xx/xx/{}.png".format(filename)) 

memoryunreal avatar Apr 27 '23 17:04 memoryunreal

It gives this error

result = context.run(func, *args) File "E:\Stabilized-Diffusion automatic1111\Track anything\Track-Anything\app.py", line 286, in vos_tracking_video Image.fromarray(mask).save("/xx/xx/{}.png".format(filename)) NameError: name 'filename' is not defined

EDIT: here is the full error:

Tracking image: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 370/370 [02:42<00:00, 2.27it/s] For generating this tracking result, inference times: 2, click times: 2, positive: 2, negative: 0 save mask Traceback (most recent call last): File "C:\Users\Epic\AppData\Local\Programs\Python\Python310\lib\site-packages\gradio\routes.py", line 395, in run_predict output = await app.get_blocks().process_api( File "C:\Users\Epic\AppData\Local\Programs\Python\Python310\lib\site-packages\gradio\blocks.py", line 1193, in process_api result = await self.call_function( File "C:\Users\Epic\AppData\Local\Programs\Python\Python310\lib\site-packages\gradio\blocks.py", line 916, in call_function prediction = await anyio.to_thread.run_sync( File "C:\Users\Epic\AppData\Local\Programs\Python\Python310\lib\site-packages\anyio\to_thread.py", line 31, in run_sync return await get_asynclib().run_sync_in_worker_thread( File "C:\Users\Epic\AppData\Local\Programs\Python\Python310\lib\site-packages\anyio_backends_asyncio.py", line 937, in run_sync_in_worker_thread return await future File "C:\Users\Epic\AppData\Local\Programs\Python\Python310\lib\site-packages\anyio_backends_asyncio.py", line 867, in run result = context.run(func, *args) File "E:\Stabilized-Diffusion automatic1111\Track anything\Track-Anything\app.py", line 286, in vos_tracking_video Image.fromarray(mask).save("/xx/xx/{}.png".format(filename)) NameError: name 'filename' is not defined

ahakagei avatar Apr 27 '23 17:04 ahakagei

It gives this error

result = context.run(func, *args) File "E:\Stabilized-Diffusion automatic1111\Track anything\Track-Anything\app.py", line 286, in vos_tracking_video Image.fromarray(mask).save("/xx/xx/{}.png".format(filename)) NameError: name 'filename' is not defined

EDIT: here is the full error:

Tracking image: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 370/370 [02:42<00:00, 2.27it/s] For generating this tracking result, inference times: 2, click times: 2, positive: 2, negative: 0 save mask Traceback (most recent call last): File "C:\Users\Epic\AppData\Local\Programs\Python\Python310\lib\site-packages\gradio\routes.py", line 395, in run_predict output = await app.get_blocks().process_api( File "C:\Users\Epic\AppData\Local\Programs\Python\Python310\lib\site-packages\gradio\blocks.py", line 1193, in process_api result = await self.call_function( File "C:\Users\Epic\AppData\Local\Programs\Python\Python310\lib\site-packages\gradio\blocks.py", line 916, in call_function prediction = await anyio.to_thread.run_sync( File "C:\Users\Epic\AppData\Local\Programs\Python\Python310\lib\site-packages\anyio\to_thread.py", line 31, in run_sync return await get_asynclib().run_sync_in_worker_thread( File "C:\Users\Epic\AppData\Local\Programs\Python\Python310\lib\site-packages\anyio_backends_asyncio.py", line 937, in run_sync_in_worker_thread return await future File "C:\Users\Epic\AppData\Local\Programs\Python\Python310\lib\site-packages\anyio_backends_asyncio.py", line 867, in run result = context.run(func, *args) File "E:\Stabilized-Diffusion automatic1111\Track anything\Track-Anything\app.py", line 286, in vos_tracking_video Image.fromarray(mask).save("/xx/xx/{}.png".format(filename)) NameError: name 'filename' is not defined

You should replace /xx/xx with your local path, and the filename should be provided by yourself. I give you the template to save masks. You could use the variable i in the for loop to define the filename.

 if interactive_state["mask_save"]: 
     if not os.path.exists('./result/mask/{}'.format(video_state["video_name"].split('.')[0])): 
         os.makedirs('./result/mask/{}'.format(video_state["video_name"].split('.')[0])) 
     i = 0 
     print("save mask") 
     for mask in video_state["masks"]: 
         if interactive_state["mask_save"]: 
     if not os.path.exists('./result/mask/{}'.format(video_state["video_name"].split('.')[0])): 
         os.makedirs('./result/mask/{}'.format(video_state["video_name"].split('.')[0])) 
     i = 0 
     print("save mask") 
     for mask in video_state["masks"]: 
         Image.fromarray(mask).save(os.path.join('./result/mask/{}'.format(video_state["video_name"].split('.')[0]), '{:08d}.png'.format(i)))
         i+=1 

memoryunreal avatar Apr 27 '23 18:04 memoryunreal

I am wondering will this code save a binary mask (with undifferentiable 0 and 1 values) to that png file? Shall I multiply with the original frame before saving?

DavidTu21 avatar Apr 28 '23 00:04 DavidTu21

Hi! Thank you very much for your excellent project! How could I generate an MP4 video with black and white masks (white for the segmented area, and black for the background)? Thank you very much in advance!

chris-hndz avatar Apr 30 '23 13:04 chris-hndz

@chris-hndz hello. You can replace the lines in tracker/base_tracker.py

https://github.com/gaomingqi/Track-Anything/blob/b26b7fec95dbd9a51f3f897826f7bb3b12bee614/tracker/base_tracker.py#L99-L102

with:

painted_image = mask_painter(painted_image, (final_mask==0).astype('uint8'), mask_color=0, mask_alpha=1, contour_width=0)
painted_image = mask_painter(painted_image, (final_mask>0).astype('uint8'), mask_color=1, mask_alpha=1, contour_width=0)

, and run Track-Anything as usual. BTW, you can specify other colours to foreground (now is white, its colour index is 1) and background (now is black, its colour index is 0) with different indices. Check

https://github.com/gaomingqi/Track-Anything/blob/b26b7fec95dbd9a51f3f897826f7bb3b12bee614/assets/color_map_with_id.png

for more colours. You can also try different mask_alpha for different transparency of the mask.

Thanks.

gaomingqi avatar May 01 '23 03:05 gaomingqi

Hello @gaomingqi ! Thank you very much for your reply. I have tested it and it works very well!

Thank you very much again!

:D

chris-hndz avatar May 01 '23 14:05 chris-hndz

You should replace /xx/xx with your local path, and the filename should be provided by yourself. I give you the template to save masks. You could use the variable i in the for loop to define the filename.

 if interactive_state["mask_save"]: 
     if not os.path.exists('./result/mask/{}'.format(video_state["video_name"].split('.')[0])): 
         os.makedirs('./result/mask/{}'.format(video_state["video_name"].split('.')[0])) 
     i = 0 
     print("save mask") 
     for mask in video_state["masks"]: 
         if interactive_state["mask_save"]: 
     if not os.path.exists('./result/mask/{}'.format(video_state["video_name"].split('.')[0])): 
         os.makedirs('./result/mask/{}'.format(video_state["video_name"].split('.')[0])) 
     i = 0 
     print("save mask") 
     for mask in video_state["masks"]: 
         Image.fromarray(mask).save(os.path.join('./result/mask/{}'.format(video_state["video_name"].split('.')[0]), '{:08d}.png'.format(i)))
         i+=1 

Hi, this modification seems to work but I get png files with 2 colors: 0,0,0 and 1,1,1 which is hard to see and exploit without manually changing the colors afterwards.

Your suggestion to modify the mask color in the video output works for video.

Is there a way to specify the color for the png marks in a similar manner?

Nostrovx avatar May 01 '23 19:05 Nostrovx

Hi, im quite new to python, and the piece of code to save masks to png doesnt work for me. According to the code, it doesnt even create the result/mask dir - therefore I assume the first IF doesn't even trigger? if interactive_state["mask_save"]:

baaoh avatar May 11 '23 18:05 baaoh

Hi @gaomingqi please how can I save in png format the mask with its origin color pixel and a black background?

assia855 avatar Jan 19 '24 15:01 assia855