pmneila / morphsnakes Goto Github PK
View Code? Open in Web Editor NEWMorphological snakes for image segmentation and tracking
License: BSD 3-Clause "New" or "Revised" License
Morphological snakes for image segmentation and tracking
License: BSD 3-Clause "New" or "Revised" License
Hi,
I have got this error when dealing with 3d input data.
Traceback (most recent call last):
File "", line 4, in
iter_callback=visual_callback_3d)
File "/Users/renne/anaconda3/lib/python3.7/site-packages/morphsnakes.py", line 346, in morphological_chan_vese
iter_callback(u)
File "", line 37, in visual_callback_3d
fig.clf()
AttributeError: 'numpy.ndarray' object has no attribute 'clf'
Could you please help answer it?
Many thanks,
Renne
Hello,
When initiating a level set of multiple blobs using morphsnakes, is it possible to prevent them from merging?
Ciaran
Hi,
Thanks for your code. I have been trying to play around it a bit. In that process, I cropped the image. However, the algo doesn't seem to give correct output.
Original
Cropped:
Do you know what could be the issue?
PS: cropping the image like this
imgcolor = imread("testimages/seastar2.png")/255.0
imgcolor = imgcolor[50:250, 50:250]
I have tried it for some medical images which are a bit larger than standard computer vision images and then the processing takes significantly longer time and on the other hand, setting larger step may skip the boundary. Have you consider and you think that it could be easier extendable to run in on superpixels (which usually preserve the edges), similar as we did DOI: 10.1117/1.JEI.26.6.061611?
Thanks a lot for the very useful library!
I have faced an issue with the installation of morphsnakes
using pip
as described in the README file.
The issue is related to the dependencies of morphsnakes
: numpy
and scipy
are not automatically installed when running pip install morphsnakes
:
$ pip install morphsnakes
Collecting morphsnakes
Using cached morphsnakes-2.0.1-py3-none-any.whl (7.8 kB).
Installing collected packages: morphsnakes
Successfully installed morphsnakes-2.0.1
so that when I try to import morphsnakes
:
import morphsnakes
the following import error is raised:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/fnattino/Projects/Eratosthenes/Repos/morphsnakes/morphsnakes.py", line 56, in <module>
import numpy as np
ModuleNotFoundError: No module named 'numpy'
I would be happy to help fixing this in order to use this tool as a dependency in a project package I am working on, so if you don't mind I will open a PR to address the issue!
Hi, I saw that you are developing a branch with C++ support and refactoring the folder structure, I think
pylint
check (or enable travis or coverage.)mayavi
, which currently is not supported in Anaconda
with python-3.5
(which will be support in the next release of mayavi
), I think this dependency should be written in the Readme.mdHi. Congratulations on such an impressive method.
I am very new to coding (and only know a little Python) and relatively new to image processing.
Here is one of my results of running ACWE on an image:
I am trying to segment the ink -- the handwritten letters -- on images with text like this, and wondering three things:
How could I capture multiple letters (even allowing for connected-letters, like the "ic" above) as separate objects at the same time? Like in the image above, how could I capture "s" separately from "ci"?
Or imagine a word next to these letters (which there is in the original). How could I run morphsnakes to also do its work on those letters and words as well?
How would one isolate a donut-shaped object (like "ci" is, almost, in effect; or like a letter "o" or "d" would be)? I mean, how could I segment the ink without the inside as part of the result? Or even get the letter "s" to hug its borders better?
Lastly, how could I improve the precision of these results, so that tips aren't cropped (like the right side of the "i", top and bottom; or like the upper-right tip of the "s")?
(For one thing, I was wondering if donut-shapes hurt precision -- if the entire interior is being weighed against the exterior. That is, using my example image, a significant area of "not ink" in the donut hole of "ic" is being factored into results.)
Thank you for your consideration.
Hi,
How can I use a rectangle similar to you use at "europe.gif"?. I want to use the coordinates of a rectangle instead of a circle.
Thanks.
Thanks for your great work, I met a problem on this library.
I can't figure out how to make evolve_visual3d
work, could you please provide a demo on that.
def evolve_visual3d(msnake, levelset=None, num_iters=20):
"""
Visual evolution of a three-dimensional morphological snake.
Parameters
----------
msnake : MorphGAC or MorphACWE instance
The morphological snake solver.
levelset : array-like, optional
If given, the levelset of the solver is initialized to this. If not
given, the evolution will use the levelset already set in msnake.
num_iters : int, optional
The number of iterations.
"""
from enthought.mayavi import mlab
if levelset is not None:
msnake.levelset = levelset
fig = mlab.gcf()
mlab.clf()
src = mlab.pipeline.scalar_field(msnake.data)
mlab.pipeline.image_plane_widget(src, plane_orientation='x_axes', colormap='gray')
cnt = mlab.contour3d(msnake.levelset, contours=[0.5])
for i in xrange(num_iters):
msnake.step()
cnt.mlab_source.scalars = msnake.levelset
# Return the last levelset.
return msnake.levelset
I get morphsnake installation for my Docker image in the requirements.txt file. You can see it. The download is successful:
Successfully built morphsnakes
Installing collected packages: morphsnakes
Attempting uninstall: morphsnakes
Found existing installation: morphsnakes 0.0.9
Uninstalling morphsnakes-0.0.9:
Successfully uninstalled morphsnakes-0.0.9
Successfully installed morphsnakes-0.0.6
but i can't use the library. i'm trying with thos code to try the library:
try:
import morphsnakes
print("morphsnakes not yes intalled")
except ImportError:
print("morphsnakes cannot load please check your installed")
the output on the terminal: morphsnakes cannot load please check your installed
mean i get problem right from this library. can you help me? i mean i tried another way with save morpsnake.py file in my folder. but long time for make the outline of image when i just save the file and not the library. please corect me if my thinking is wrong.I will look forward to your reply
Can this code/algorithm be modified to work with open contours? E.g. a curve rather than a closed shape.
Hello!
First of all, very nice work! Thanks a lot for the implementation, and for the examples you prepared!
I was wondering if you would consider merging these algorithms (i.e. the full repo) into scikit-image
(scikit-image.org, https://github.com/scikit-image/scikit-image). It is one of the most popular libraries for image processing, and is fully written in Python/Cython.
If you find this proposal interesting, I'd be happy to assist you with the Pull Request.
In any case, thanks again, and keep up the great work! ;)
Hi, I want to calculate number of pixels in example_nodule()
's example. How can ı do ? Because I want to find area for selected zone.
Thank you.
@pmneila
hi!
i am trying this on my spyder but i am not getting the results instead i am getting the blank image.
Also tell me the steps to execute it smoothly.
I want get counters in images like BSDS, but Morphological Snakes often get a poor result.
besides the threshold, what affects Morphological Snakes stop condition?
and I want to use a semantic mask as my init counter, and edge detection result for Auxiliary judgment of iterative termination. how to use this for a better counter result?
Please release morphsnakes under a permissive open source license!
Hi, I want to use morphsnakes
as a tool for extracting the boundary of a CT/MRI scan of head.
I want to use the red line on the left figure as a function handler in python, denoted by fd
. For all pixels p = (x, y)
, it will be fd(p) = 0
on the boundary, fd(p) < 0
interior and fd(p) > 0
at the exterior. I do not know whether morphsnakes
support this feature (in both 2D and 3D!!), and is there any post processing techniques I need to achieve this goal ?
Can you please post an example of how to do this in python for an image where I know the start and end position?
Thanks.
========
Hi,
In general, no, it cannot be done. However, if your open curve has fixed end-points (i.e., you know where the curve starts and ends) then it might be possible to simulate this behavior using a closed contour that passes through the end-points and updating only the fragment of the contour between the end-points. Whether this will work or not depends on your particular problem.
Originally posted by @pmneila in #8 (comment)
I copied the examples code into a Jupyter Notebook and ran it. The exact code sitting in Jupyter (Python 3) is below:
import os
import logging
import time
import numpy as np
from imageio import imread
import matplotlib
from matplotlib import pyplot as plt
import morphsnakes as ms
# in case you are running on machine without display, e.g. server
if os.environ.get('DISPLAY', '') == '':
logging.warning('No display found. Using non-interactive Agg backend.')
matplotlib.use('Agg')
PATH_IMG_NODULE = 'morphsnakes-master/images/mama07ORI.bmp'
PATH_IMG_STARFISH = 'morphsnakes-master/images/seastar2.png'
PATH_IMG_LAKES = 'morphsnakes-master/images/lakes3.jpg'
PATH_IMG_CAMERA = 'morphsnakes-master/images/camera.png'
PATH_IMG_COINS = 'morphsnakes-master/images/coins.png'
PATH_ARRAY_CONFOCAL = 'morphsnakes-master/images/confocal.npy'
def visual_callback_2d(background, fig=None):
"""
Returns a callback than can be passed as the argument `iter_callback`
of `morphological_geodesic_active_contour` and
`morphological_chan_vese` for visualizing the evolution
of the levelsets. Only works for 2D images.
Parameters
----------
background : (M, N) array
Image to be plotted as the background of the visual evolution.
fig : matplotlib.figure.Figure
Figure where results will be drawn. If not given, a new figure
will be created.
Returns
-------
callback : Python function
A function that receives a levelset and updates the current plot
accordingly. This can be passed as the `iter_callback` argument of
`morphological_geodesic_active_contour` and
`morphological_chan_vese`.
"""
# Prepare the visual environment.
if fig is None:
fig = plt.figure()
fig.clf()
ax1 = fig.add_subplot(1, 2, 1)
ax1.imshow(background, cmap=plt.cm.gray)
ax2 = fig.add_subplot(1, 2, 2)
ax_u = ax2.imshow(np.zeros_like(background), vmin=0, vmax=1)
plt.pause(0.001)
def callback(levelset):
if ax1.collections:
del ax1.collections[0]
ax1.contour(levelset, [0.5], colors='r')
ax_u.set_data(levelset)
fig.canvas.draw()
plt.pause(0.001)
return callback
def visual_callback_3d(fig=None, plot_each=1):
"""
Returns a callback than can be passed as the argument `iter_callback`
of `morphological_geodesic_active_contour` and
`morphological_chan_vese` for visualizing the evolution
of the levelsets. Only works for 3D images.
Parameters
----------
fig : matplotlib.figure.Figure
Figure where results will be drawn. If not given, a new figure
will be created.
plot_each : positive integer
The plot will be updated once every `plot_each` calls to the callback
function.
Returns
-------
callback : Python function
A function that receives a levelset and updates the current plot
accordingly. This can be passed as the `iter_callback` argument of
`morphological_geodesic_active_contour` and
`morphological_chan_vese`.
"""
from mpl_toolkits.mplot3d import Axes3D
# PyMCubes package is required for `visual_callback_3d`
try:
import mcubes
except ImportError:
raise ImportError("PyMCubes is required for 3D `visual_callback_3d`")
# Prepare the visual environment.
if fig is None:
fig = plt.figure()
fig.clf()
ax = fig.add_subplot(111, projection='3d')
plt.pause(0.001)
counter = [-1]
def callback(levelset):
counter[0] += 1
if (counter[0] % plot_each) != 0:
return
if ax.collections:
del ax.collections[0]
coords, triangles = mcubes.marching_cubes(levelset, 0.5)
ax.plot_trisurf(coords[:, 0], coords[:, 1], coords[:, 2],
triangles=triangles)
plt.pause(0.1)
return callback
def rgb2gray(img):
"""Convert a RGB image to gray scale."""
return 0.2989 * img[..., 0] + 0.587 * img[..., 1] + 0.114 * img[..., 2]
def example_nodule():
logging.info('Running: example_nodule (MorphGAC)...')
# Load the image.
img = imread(PATH_IMG_NODULE)[..., 0] / 255.0
# g(I)
gimg = ms.inverse_gaussian_gradient(img, alpha=1000, sigma=5.48)
# Initialization of the level-set.
init_ls = ms.circle_level_set(img.shape, (100, 126), 20)
# Callback for visual plotting
callback = visual_callback_2d(img)
# MorphGAC.
ms.morphological_geodesic_active_contour(gimg, iterations=45,
init_level_set=init_ls,
smoothing=1, threshold=0.31,
balloon=1, iter_callback=callback)
def example_starfish():
logging.info('Running: example_starfish (MorphGAC)...')
# Load the image.
imgcolor = imread(PATH_IMG_STARFISH) / 255.0
img = rgb2gray(imgcolor)
# g(I)
gimg = ms.inverse_gaussian_gradient(img, alpha=1000, sigma=2)
# Initialization of the level-set.
init_ls = ms.circle_level_set(img.shape, (163, 137), 135)
# Callback for visual plotting
callback = visual_callback_2d(imgcolor)
# MorphGAC.
ms.morphological_geodesic_active_contour(gimg, iterations=100,
init_level_set=init_ls,
smoothing=2, threshold=0.3,
balloon=-1, iter_callback=callback)
def example_coins():
logging.info('Running: example_coins (MorphGAC)...')
# Load the image.
img = imread(PATH_IMG_COINS) / 255.0
# g(I)
gimg = ms.inverse_gaussian_gradient(img)
# Manual initialization of the level set
init_ls = np.zeros(img.shape, dtype=np.int8)
init_ls[10:-10, 10:-10] = 1
# Callback for visual plotting
callback = visual_callback_2d(img)
# MorphGAC.
ms.morphological_geodesic_active_contour(gimg, 230, init_ls,
smoothing=1, threshold=0.69,
balloon=-1, iter_callback=callback)
def example_lakes():
logging.info('Running: example_lakes (MorphACWE)...')
# Load the image.
imgcolor = imread(PATH_IMG_LAKES)/255.0
img = rgb2gray(imgcolor)
# MorphACWE does not need g(I)
# Initialization of the level-set.
init_ls = ms.circle_level_set(img.shape, (80, 170), 25)
# Callback for visual plotting
callback = visual_callback_2d(imgcolor)
# Morphological Chan-Vese (or ACWE)
ms.morphological_chan_vese(img, iterations=200,
init_level_set=init_ls,
smoothing=3, lambda1=1, lambda2=1,
iter_callback=callback)
def example_camera():
"""
Example with `morphological_chan_vese` with using the default
initialization of the level-set.
"""
logging.info('Running: example_camera (MorphACWE)...')
# Load the image.
img = imread(PATH_IMG_CAMERA)/255.0
# Callback for visual plotting
callback = visual_callback_2d(img)
# Morphological Chan-Vese (or ACWE)
ms.morphological_chan_vese(img, 35,
smoothing=3, lambda1=1, lambda2=1,
iter_callback=callback)
def example_confocal3d():
logging.info('Running: example_confocal3d (MorphACWE)...')
# Load the image.
img = np.load(PATH_ARRAY_CONFOCAL)
# Initialization of the level-set.
init_ls = ms.circle_level_set(img.shape, (30, 50, 80), 25)
# Callback for visual plotting
callback = visual_callback_3d(plot_each=20)
# Morphological Chan-Vese (or ACWE)
ms.morphological_chan_vese(img, iterations=150,
init_level_set=init_ls,
smoothing=1, lambda1=1, lambda2=2,
iter_callback=callback)
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG)
example_nodule()
example_starfish()
example_coins()
example_lakes()
example_camera()
# Uncomment the following line to see a 3D example
# This is skipped by default since mplot3d is VERY slow plotting 3d meshes
# example_confocal3d()
logging.info("Done.")
plt.show()
After running this (and yes, I put the images in the correct place) it produced the following error:
NameError Traceback (most recent call last)
<ipython-input-7-e6b7bfe1611c> in <module>()
263 if __name__ == '__main__':
264 logging.basicConfig(level=logging.DEBUG)
--> 265 example_nodule()
266 example_starfish()
267 example_coins()
<ipython-input-7-e6b7bfe1611c> in example_nodule()
153 init_level_set=init_ls,
154 smoothing=1, threshold=0.31,
--> 155 balloon=1, iter_callback=callback)
156
157
C:\ProgramData\Anaconda3\lib\site-packages\morphsnakes.py in morphological_geodesic_active_contour(gimage, iterations, init_level_set, smoothing, threshold, balloon, iter_callback)
468 u = np.int8(init_level_set > 0)
469
--> 470 iter_callback(u)
471
472 for _ in range(iterations):
<ipython-input-7-e6b7bfe1611c> in callback(levelset)
65 ax_u.set_data(levelset)
66 fig.canvas.draw()
---> 67 plt.pause(0.001)
68
69 return callback
C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\pyplot.py in pause(interval)
292 canvas.start_event_loop(interval)
293 else:
--> 294 time.sleep(interval)
295
296
NameError: name 'time' is not defined
So, of course, first I check C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\pyplot.py because:
--> 294 time.sleep(interval)
So, I discover that yes, the time module is in fact imported in this script. It makes no sense why this error is being thrown. And, it prevents me from testing any of the examples. What can I do to solve it?
I am working on your code a little bit. I am applying it for segmentation of rooftop area of buildings. So every time I had to change the centre level dataset is there any way to automate that part on the image?
Thanks for your code and help.
Hi,
I do not have much experience with python, could you please help me how can I save segmentation into nii binary file?
Thank you
Mark
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.