bowang-lab / MedSAMSlicer

3D Slicer Plugin for Segment anything in medical images
https://www.nature.com/articles/s41467-024-44824-z
173 stars 20 forks source link

Inference step fails #1

Closed dzenanz closed 9 months ago

dzenanz commented 10 months ago

I followed the installation and usage instructions, only to get the below errors in the log when clicking "Segmentation" button. This happens with both Slicer's sample data "CBCT-MR Head, and with my private data.

sending infer request...
Starting new HTTP connection (1): 127.0.0.1:5555
93 [0, 134, 86, 239] [58, 128]
INFO:     127.0.0.1:56739 - "POST /infer HTTP/1.1" 500 Internal Server Error
http://127.0.0.1:5555 "POST /infer HTTP/1.1" 500 21
ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 404, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\uvicorn\middleware\proxy_headers.py", line 84, in __call__
Traceback (most recent call last):
    return await self.app(scope, receive, send)
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\fastapi\applications.py", line 1054, in __call__
  File "C:/Dev/Work/MedSAMSlicer-0.01/MedSAM/MedSAMLite/MedSAMLite.py", line 236, in <lambda>
    await super().__call__(scope, receive, send)
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\starlette\applications.py", line 123, in __call__
    await self.middleware_stack(scope, receive, send)
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\starlette\middleware\errors.py", line 186, in __call__
    raise exc
    self.ui.pbSegment.connect('clicked(bool)', lambda: self.logic.applySegmentation())
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__
  File "C:/Dev/Work/MedSAMSlicer-0.01/MedSAM/MedSAMLite/MedSAMLite.py", line 606, in applySegmentation
    await self.app(scope, receive, _send)
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\starlette\middleware\exceptions.py", line 62, in __call__
    await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\starlette\_exception_handler.py", line 64, in wrapped_app
    raise exc
    segmentation_mask = self.inferSegmentation(serverUrl)
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
  File "C:/Dev/Work/MedSAMSlicer-0.01/MedSAM/MedSAMLite/MedSAMLite.py", line 579, in inferSegmentation
    await app(scope, receive, sender)
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\starlette\routing.py", line 762, in __call__
    await self.middleware_stack(scope, receive, send)
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\starlette\routing.py", line 782, in app
    await route.handle(scope, receive, send)
    response.raise_for_status()
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\starlette\routing.py", line 297, in handle
    await self.app(scope, receive, send)
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\requests\models.py", line 1021, in raise_for_status
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\starlette\routing.py", line 77, in app
    await wrap_app_handling_exceptions(app, request)(scope, receive, send)
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\starlette\_exception_handler.py", line 64, in wrapped_app
    raise exc
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
    await app(scope, receive, sender)
    raise HTTPError(http_error_msg, response=self)
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\starlette\routing.py", line 72, in app
    response = await func(request)
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\fastapi\routing.py", line 299, in app
    raise e
requests.exceptions.HTTPError: 500 Server Error: Internal Server Error for url: http://127.0.0.1:5555/infer
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\fastapi\routing.py", line 294, in app
    raw_response = await run_endpoint_function(
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\fastapi\routing.py", line 193, in run_endpoint_function
    return await run_in_threadpool(dependant.call, **values)
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\starlette\concurrency.py", line 40, in run_in_threadpool
    return await anyio.to_thread.run_sync(func, *args)
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\anyio\to_thread.py", line 56, in run_sync
    return await get_async_backend().run_sync_in_worker_thread(
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\anyio\_backends\_asyncio.py", line 2134, in run_sync_in_worker_thread
    return await future
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\anyio\_backends\_asyncio.py", line 851, in run
    result = context.run(func, *args)
  File "C:\Dev\Work\MedSAMSlicer-0.01\_deps\server_essentials\server.py", line 316, in infer
    res[csidx], bbox_1024_prev = inf(bbox_1024_prev)
  File "C:\Dev\Work\MedSAMSlicer-0.01\_deps\server_essentials\server.py", line 313, in inf
    return mask.tolist(), [get_bbox1024(mask_t)]
  File "C:\Dev\Work\MedSAMSlicer-0.01\_deps\server_essentials\server.py", line 263, in get_bbox1024
    x_min, x_max = np.min(x_indices), np.max(x_indices)
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\numpy\core\fromnumeric.py", line 2953, in min
    return _wrapreduction(a, np.minimum, 'min', axis, None, out,
  File "C:\Users\Dzenan\AppData\Local\slicer.org\Slicer 5.6.1\lib\Python\Lib\site-packages\numpy\core\fromnumeric.py", line 88, in _wrapreduction
    return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
ValueError: zero-size array to reduction operation minimum which has no identity
MedSAM Screenshot 2024-01-23 14 26 17
rasakereh commented 10 months ago

Thank you for sharing the issue with us. Would you please follow these steps and send me a screenshot:

  1. Five buttons to the right of the drop-down menu click on the cube-like icon with tooltip text "Volumes".
  2. For Window/Level value select Manual Min/Max and the range of 0 to 255.

It will show how our plugin actually sees your image. I guess the error happens because there is not much separation between the segment you want to identify and the background. As a temporary fix you can try applying either of the preprocessing steps to increase the color contrasts. We will work on it to fix the issue and/or introduce more relevant preprocessing options.

Let me know if it fixed the problem please.

Thanks!

tejoman commented 10 months ago

For what its worth I had this same issue and it resolved after preprocessing my data to 0 to 255 intensity range as described by rasakereh.

neel-dey commented 10 months ago

On Linux and facing the same issue. Renormalizing to [0, 255] did not resolve this issue, see for example:

image

File "/home/neel/Desktop/Slicer-5.6.1-linux-amd64/lib/Python/lib/python3.9/site-packages/starlette/routing.py", line 782, in app
    await route.handle(scope, receive, send)
  File "/home/neel/Desktop/Slicer-5.6.1-linux-amd64/lib/Python/lib/python3.9/site-packages/starlette/routing.py", line 297, in handle
    await self.app(scope, receive, send)
  File "/home/neel/Desktop/Slicer-5.6.1-linux-amd64/lib/Python/lib/python3.9/site-packages/starlette/routing.py", line 77, in app
    await wrap_app_handling_exceptions(app, request)(scope, receive, send)
  File "/home/neel/Desktop/Slicer-5.6.1-linux-amd64/lib/Python/lib/python3.9/site-packages/starlette/_exception_handler.py", line 64, in wrapped_app
    raise exc
  File "/home/neel/Desktop/Slicer-5.6.1-linux-amd64/lib/Python/lib/python3.9/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
    await app(scope, receive, sender)
  File "/home/neel/Desktop/Slicer-5.6.1-linux-amd64/lib/Python/lib/python3.9/site-packages/starlette/routing.py", line 72, in app
    response = await func(request)
  File "/home/neel/Desktop/Slicer-5.6.1-linux-amd64/lib/Python/lib/python3.9/site-packages/fastapi/routing.py", line 299, in app
    raise e
  File "/home/neel/Desktop/Slicer-5.6.1-linux-amd64/lib/Python/lib/python3.9/site-packages/fastapi/routing.py", line 294, in app
    raw_response = await run_endpoint_function(
  File "/home/neel/Desktop/Slicer-5.6.1-linux-amd64/lib/Python/lib/python3.9/site-packages/fastapi/routing.py", line 193, in run_endpoint_function
    return await run_in_threadpool(dependant.call, **values)
  File "/home/neel/Desktop/Slicer-5.6.1-linux-amd64/lib/Python/lib/python3.9/site-packages/starlette/concurrency.py", line 40, in run_in_threadpool
    return await anyio.to_thread.run_sync(func, *args)
  File "/home/neel/Desktop/Slicer-5.6.1-linux-amd64/lib/Python/lib/python3.9/site-packages/anyio/to_thread.py", line 56, in run_sync
    return await get_async_backend().run_sync_in_worker_thread(
  File "/home/neel/Desktop/Slicer-5.6.1-linux-amd64/lib/Python/lib/python3.9/site-packages/anyio/_backends/_asyncio.py", line 2134, in run_sync_in_worker_thread
    return await future
  File "/home/neel/Desktop/Slicer-5.6.1-linux-amd64/lib/Python/lib/python3.9/site-packages/anyio/_backends/_asyncio.py", line 851, in run
    result = context.run(func, *args)
  File "/home/neel/Desktop/MedSAMSlicer-0.01/dependencies/server_essentials/server.py", line 316, in infer
    res[csidx], bbox_1024_prev = inf(bbox_1024_prev)
  File "/home/neel/Desktop/MedSAMSlicer-0.01/dependencies/server_essentials/server.py", line 313, in inf
    return mask.tolist(), [get_bbox1024(mask_t)]
  File "/home/neel/Desktop/MedSAMSlicer-0.01/dependencies/server_essentials/server.py", line 263, in get_bbox1024
    x_min, x_max = np.min(x_indices), np.max(x_indices)
  File "/home/neel/Desktop/Slicer-5.6.1-linux-amd64/lib/Python/lib/python3.9/site-packages/numpy/core/fromnumeric.py", line 2953, in min
    return _wrapreduction(a, np.minimum, 'min', axis, None, out,
  File "/home/neel/Desktop/Slicer-5.6.1-linux-amd64/lib/Python/lib/python3.9/site-packages/numpy/core/fromnumeric.py", line 88, in _wrapreduction
    return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
ValueError: zero-size array to reduction operation minimum which has no identity
rasakereh commented 9 months ago

A new release is ready. We tried to address this issue. Please remove pre-existing version and install the new one and let me know if it fixed your issue.

neel-dey commented 9 months ago

Thanks for the new release. There's now a different error when using the same image.

Traceback (most recent call last):
  File "/home/neel/Desktop/MedSAMSlicer-0.02/MedSAM/MedSAMLite/MedSAMLite.py", line 237, in <lambda>
    self.ui.pbSegment.connect('clicked(bool)', lambda: self.logic.applySegmentation())
  File "/home/neel/Desktop/MedSAMSlicer-0.02/MedSAM/MedSAMLite/MedSAMLite.py", line 634, in applySegmentation
    segmentation_mask = self.inferSegmentation(serverUrl)
  File "/home/neel/Desktop/MedSAMSlicer-0.02/MedSAM/MedSAMLite/MedSAMLite.py", line 608, in inferSegmentation
    seg_result[frame, :, :] = seg_data[str(frame)]
ValueError: could not broadcast input array from shape (150,146) into shape (146,150)

image

Looking at the trace, I'm guessing a transpose is missing somewhere?

Thanks for the help!

rasakereh commented 9 months ago

@neel-dey if there is no privacy concern, can you please share the image file with me? my email: reza.asakereh@uhn.ca

neel-dey commented 9 months ago

@rasakereh Oh sure, it's public data available from here

FYI, I just tried with a different (160, 160, 192) brain volume and was able to get an output whereas the image I linked to is (150, 146, 249) volume. Perhaps there's a divisibility by powers of two or resizing error happening somewhere?

rasakereh commented 9 months ago

Thanks @neel-dey . You are right, there was a faulty dimension swap in the server. It is now fixed in the new release. Also we implemented a better upgrade solution in the module so you dont have to do it manually each time. Hope it fixes the bug.

neel-dey commented 9 months ago

The interface does produce outputs now, thanks! I didn't create this issue so I can't close it, but this particular issue seems resolved from my side.

dzenanz commented 9 months ago

I am running into a different issue now:

sending setImage request...
Starting new HTTP connection (1): 127.0.0.1:5555
http://127.0.0.1:5555 "POST /setImage HTTP/1.1" 200 4
Response from setImage: null
Traceback (most recent call last):
  File "C:/Dev/Work/MedSAMSlicer/MedSAM/MedSAMLite/MedSAMLite.py", line 243, in <lambda>
    self.ui.pbSendImage.connect('clicked(bool)', lambda: self.logic.sendImage())
  File "C:/Dev/Work/MedSAMSlicer/MedSAM/MedSAMLite/MedSAMLite.py", line 642, in sendImage
    self.captureImage()
  File "C:/Dev/Work/MedSAMSlicer/MedSAM/MedSAMLite/MedSAMLite.py", line 631, in captureImage
    self.img_path = self.volume_node.GetStorageNode().GetFullNameFromFileName()
AttributeError: 'NoneType' object has no attribute 'GetFullNameFromFileName'

image

rasakereh commented 9 months ago

@dzenanz refer to issue #6 for this. You have to open an actual file (sth that exists on the disk) for your segmentation task

dzenanz commented 9 months ago

Close this issue, if you think it is fixed.