Hi FranÃ¯Â¿Â½ois,
that's an excellent question, and not a troll :-). Opencv is a
very powerful library, but it focuses primarily on computer vision
(feature detection and extraction, classification, ...), as opposed to
image processing in general (with other tasks such as denoising,
segmentation, ...).
The other big difference is that skimage builds on numpy
ndarrays, and uses the full power of the numpy API (including of course
the basic facilities for processing arrays as images that come with
numpy), as well as some of scipy functions (you could have added
scipy.ndimage to your list -- a few functions in skimage are wrappers
around scipy.ndimage, that exist for the sake of completeneness). One
important consequence is that algorithms working for 3-d or even n-d
images can be easily implemented in 3-d/n-d in skimage, whereas opencv is
restricted to 2-D images (as far as I know). Thanks to the use of numpy
arrays, the API of skimage is also quite pleasant for a numpy user, more
than the API of opencv.
A related difference is that skimage is written in python and
cython, whereas opencv is a C++ library. The two libraries attract a
different crowd of developers, and a Python/Cython toolkit based on numpy
arrays is easier to develop and maintain inside the Scientific Python
ecosystem.
I'm sure that other devs/users will have things to add to this
discussion!
Cheers,
Emmanuelle
On Thu, Dec 27, 2012 at 02:06:08PM -0800, FranÃ¯Â¿Â½ois wrote:
> Hi users and devs,
> It came to my knowledge that another python library (based on C++ and C
> codes) for image processing exists too : opencv
> I understand that numpy intregrates some basic features and we need some
> advanced features but I have the feeling that skimages is redoundant with
> opencv in some ways.
> What's the position of skimage about that? (Don't read this question as a
> troll but like a real question).
> I mean that similar features exist in both. Would not be possible to
> reuse/integrate opencv or merge? what's the reason for keeping them apart?
> My observation is there is 4 libraries to manipulate images:
> * PIL
> * numpy
> * skimages
> * opencv
> That's a lot.
> Cheers,

Hi,
FYI, I plan to work on the detection of ellipses quite soon. Stefan
indicated to me a reference which seems fairly simple to implement.
Cheers,
François.

Hi all,
Is there a way to get the pixels on the border of a labelled region in an
image using skimage? I've done edge detection, and then filled the
resulting shapes (after some edge linking), and would now like to be able
to get the pixels on the border of each of these shapes. I would have
thought that getting borders would be an option in regionprops, but it
doesn't seem to be.
Any ideas?
Cheers,
Robin

Dear Pythonistas,
We are porting the SIFT keypoints extraction algorithm (available from IPOL)
to GPU using PyOpenCL. For the moment, the keypoint location works and
shows a speed-up of 5 to 10x (without tuning so far, vs C++).
A lot of work is remaining, especially:
* limit the memory footprint (700MB/10Mpix image currently)
* calculate the descriptor for each descriptor
* keypoint matching and image alignment.
* best interleave of IO/CPU/GPU
but we managed to port the most trickiest part to OpenCL (without using
textures, which makes it running also on multi-core).
I would like to thank the people who published their algorithm on IPOL;
making unit testing possible.
Last but not least, the code is open source and should have a BSD
licence (even if there is a patent on the algorithm in the USA).
https://github.com/pierrepaleo/sift_pyocl
Cheers,
--
Jérôme Kieffer <google(a)terre-adelie.org>

Hello,
a while ago, I contributed to skimage an implementation of the
random walker segmentation algorithm (which has been improved and
extended by many others since then). This algorithm computes a multilabel
segmentation using seeds (already labeled pixels), by determining for an
unlabeled pixel the probability that a seed diffuses to the pixel (with
an anisotropic diffusion coefficient depending on the gradient between
neighboring pixels).
In the current implementation in skimage, the computation of the
probability map is done by inverting a large sparse linear system
(involving the Laplacian of the graph of pixels). Different methods can
be chosen to solve the linear system: a brute force inversion only
works for tiny images; a conjugate gradient method works well but is
quite slow. If the package pyamg is available, a multigrid method is used
to compute a preconditioner, which speeds up the algorithm -- but it
requires pyamg. Also, the memory cost of the algorithm is important
(linear, I think, though. I haven't yet taken the time to use a memory
profiler but I should).
Recently, a colleague brought to my attention that the linear
system was just a set of fixed-point equations, that could be solved
iteratively. Indeed, the solution verifies that the probability of a
pixel is the weighted sum (with weights on edges that are a decreasing
function of gradients) of the probabilities of its neighbors. I have
written a quick and dirty implementation (only for 2-D grayscale images
and for 2 labels) of this "local" version, available on
https://github.com/emmanuelle/scikits.image/blob/local_random_walker/skimag…
It turns out that this implementation is slower than the
conjugate gradient with multigrid acceleration (typically 2 to three
times slower), but it has several advantages. First, it can be as fast as
the "simple" conjugate gradient (without pyamg's muligrid acceleration),
which is the mode that most users will use (we don't expect users to
install pymag when they are just trying out algorithms). Second, its
memory cost is lower (for example, the weight of an edge is stored only
once, while it appears twice in the Laplacian matrix). Finally, because
the operations only involve neighboring pixels, it is possible that
further speed optimization can be done (using cython... or maybe a GPU
implementation, even if we're not that far yet with skimage).
So, should we replace the linear algebra implementation with this
simpler local and iterative implementation ? I'd be interested in knowing
about your opinion.
Cheers,
Emmanuelle

Hello all,
Based on the discussion here:
https://groups.google.com/forum/#!topic/pythonvision/AVrnueiKKYI
It seems like this label function should be faster than the scipy version.
However, I find it to be much slower:
from skimage import morphology
from scipy import ndarray as nd
k = np.zeros((4000,4000),dtype=int)
k[100,100] = 1
strel = np.ones((3,3))
%timeit morphology.label(k)
1 loops, best of 3: 1.46 s per loop
%timeit nd.label(k,strel)
1 loops, best of 3: 355 ms per loop
If you have any insight, I would be very grateful. I am using version 0.8.2
on the versions of python/numpy/cython, etc. included in the most recent
edition of Enthought/Canopy.
Thanks,
Evan Daugharthy

Great posts Chintak !! They cleared up a lot of the ambiguities I had about
ndarray's working at a lower level of abstraction.
Same goes for Stefan's clear 'The Numpy Array' paper. Thanks a lot.
Ankit Agrawal,
Communication and Signal Processing,
IIT Bombay.
On Wed, Jul 31, 2013 at 4:25 PM, Chintak Sheth <chintaksheth(a)gmail.com>wrote:
> Added the explanation and another example in einsum section. Hope that
> makes it more understandable. Thanks for pointing it out, Juan! :D
>
> @Stefan, sure I'll add it in a bit. I'm trying to get Python3 up and
> rolling as you had instructed.
>
> Chintak
>
> --
> You received this message because you are subscribed to the Google Groups
> "scikit-image" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to scikit-image+unsubscribe(a)googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>
>

Added the explanation and another example in einsum section. Hope that
makes it more understandable. Thanks for pointing it out, Juan! :D
@Stefan, sure I'll add it in a bit. I'm trying to get Python3 up and
rolling as you had instructed.
Chintak

@Marc: They are very different functions. ravel() gives you a view or a
copy of the array as a 1D array that happens to be contiguous.
ascontiguousarray will give you a view or a copy of the array *of the same
shape* as the original, but guaranteed to be contiguous. Let me try to
illustrate:
In [1]: x = np.arange(20, dtype=np.uint8).reshape((4,5))
In [2]: x
Out[2]:
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]], dtype=uint8)
In [3]: x.strides
Out[3]: (5, 1)
So I've made an array x that has 4 rows and 5 columns. Internally, the data
in x is stored as a contiguous block of memory of length 20 bytes. The
strides tell numpy that to get to the next row in the array, you need to
skip 5 bytes in the memory, but to get to the next column, you only need to
go to the next (+1) byte in memory. This is called C-contiguous.
Now, let's get a weird view of x:
In [4]: y = x.T[1::2]
I've taken the transpose of x (5 rows and 4 columns) and then taken the 1st
and 3rd rows of that. By default, numpy will use nice tricks with strides
to avoid a copy:
In [5]: y.strides
Out[5]: (2, 5)
In [6]: y
Out[6]:
array([[ 1, 6, 11, 16],
[ 3, 8, 13, 18]], dtype=uint8)
In [7]: y[1, 1] = 45
In [8]: x
Out[8]:
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 45, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]], dtype=uint8)
So, y is actually pointing to the same memory as x, but it uses different
strides to access its own rows and columns. Notice that changing an entry
in y changed the corresponding entry in x.
In [10]: np.ravel(y)
Out[10]: array([ 1, 6, 11, 16, 3, 45, 13, 18], dtype=uint8)
np.ravel gives you a "linearised" version of y, concatenating all the rows
together.
In [11]: z = np.ascontiguousarray(y)
In [12]: z
Out[12]:
array([[ 1, 6, 11, 16],
[ 3, 45, 13, 18]], dtype=uint8)
In [13]: z.strides
Out[13]: (4, 1)
np.ascontiguousarray gives you the same thing as y, except now it's a
separate contiguous block of memory: look at the strides. You can tell that
it's a copy because modifying z has no effect on x:
In [14]: z[0, 0] = 72
In [15]: x
Out[15]:
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 45, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]], dtype=uint8)
In [16]: z
Out[16]:
array([[72, 6, 11, 16],
[ 3, 45, 13, 18]], dtype=uint8)
But, if an array is already contiguous, np.ravel() avoids a copy and
returns a view into the same data. So:
In [19]: a = np.ravel(x)
In [20]: a[0] = 72
In [21]: x
Out[21]:
array([[72, 1, 2, 3, 4],
[ 5, 6, 7, 45, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]], dtype=uint8)
If you try to get a contiguous version of x, which is already contiguous,
you are actually getting x back:
In [22]: b = np.ascontiguousarray(x)
In [23]: b is x
Out[23]: True
In [25]: b[3, 4] = 0
In [26]: x
Out[26]:
array([[72, 1, 2, 3, 4],
[ 5, 6, 7, 45, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 0]], dtype=uint8)
Hope that clarifies a few things! It takes quite a bit of playing around
before you can get an intuition for what's a copy, what's a view, what's
contiguous, etc.
On Wed, Jul 31, 2013 at 6:15 PM, Ankit Agrawal <aaaagrawal(a)gmail.com> wrote:
> Hi Marc,
>
>
> On Wed, Jul 31, 2013 at 1:09 PM, Marc de Klerk <deklerkmc(a)gmail.com>wrote:
>
>> Hi guys,
>>
>> I've been using np.ravel(). This morning I tried to lookup the difference
>> between np.ravel() and np.ascontiguousarray(). Does anybody know?
>>
> I am not sure if this helps as I don't know your purpose for using
> np.ravel / np.ascontiguousarray. I got to know about the ndarray.flags
> method yesterday from Stefan while discussion on this PR<https://github.com/scikit-image/scikit-image/pull/668>
> .
>
> In [15]: a = np.arange(20).reshape((4,5))
>
> In [16]: a
> Out[16]:
> array([[ 0, 1, 2, 3, 4],
> [ 5, 6, 7, 8, 9],
> [10, 11, 12, 13, 14],
> [15, 16, 17, 18, 19]])
>
> In [17]: a.flags
> Out[17]:
> C_CONTIGUOUS : True
> F_CONTIGUOUS : False
> OWNDATA : False
> WRITEABLE : True
> ALIGNED : True
> UPDATEIFCOPY : False
>
> In [18]: b = np.ravel(a)
>
> In [20]: b
> Out[20]:
> array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
> 17, 18, 19])
>
> In [21]: b.flags
> Out[21]:
> C_CONTIGUOUS : True
> F_CONTIGUOUS : True
> OWNDATA : False
> WRITEABLE : True
> ALIGNED : True
> UPDATEIFCOPY : False
>
> Hope this helps!!
>
> Marc
>>
>> On Sunday, July 21, 2013 6:37:47 AM UTC+2, Chintak Sheth wrote:
>>
>>> Hi Ronnie,
>>>
>>> On Jul 21, 2013 10:00 AM, "Ronnie Ghose" <ronnie...(a)gmail.com> wrote:
>>> >
>>> > So in skimage/colors why does it matter if the array is contiguous? Is
>>> this for Cython operations later?
>>> >
>>>
>>> Yeah it is mainly for using memory views in Cython which is initialized
>>> as C contiguous.
>>> `cdef some_type[:. ::1] var_name`
>>>
>>> In thus case ::1 is for C contiguous.
>>>
>>> Chintak
>>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "scikit-image" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to scikit-image+unsubscribe(a)googlegroups.com.
>> For more options, visit https://groups.google.com/groups/opt_out.
>>
>>
>>
>
> --
> You received this message because you are subscribed to the Google Groups
> "scikit-image" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to scikit-image+unsubscribe(a)googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>
>