1
votes

I need to segment out anomalies in a greyscale image. In a certain place in my algorithm, I compute a matrix that contains the known pixel intensities that I need to set to zero. How would I do this?

For example:
The computed pixel intensities: (array([ 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151]),)

The picture is of size (480,640) :
Printed it gives:
[[ 86 90 97 ..., 142 152 157]
[ 85 89 97 ..., 145 154 158]
[ 83 87 95 ..., 154 158 159]
...,
[130 134 139 ..., 156 154 154]
[130 134 140 ..., 154 153 152]
[130 134 141 ..., 154 153 152]]

I realize that for each pixel I could go through the intensity matrix. This would, however, be too expensive. NumPy experts I need your help!

2
The pixel intensities that I want to set to zero are computed on the flow and can be different.Talha

2 Answers

1
votes

To set to zero all pixels in an image array which have values from 91 to 151, inclusive, use:

import numpy as np
newimage = np.where(np.logical_and(91<=oldimage, oldimage<=151), 0, oldimage)

To set to zero all pixels in an image array whose values belong to some array vct, use:

newimage = np.where(np.in1d(oldimage, vct).reshape(oldimage.shape), 0, oldimage)

Example

Suppose we have an oldimage like this:

In [12]: oldimage
Out[12]: 
array([[0, 1, 2],
       [3, 4, 5]])

And we have a list of numbers called vct:

In [13]: vct
Out[13]: array([3, 5])

Let's set to zero all pixels in oldimage that are also in vct:

In [14]: newimage = np.where(np.in1d(oldimage, vct).reshape(oldimage.shape), 0, oldimage)

In [15]: newimage
Out[15]: 
array([[0, 1, 2],
       [0, 4, 0]])
3
votes

Simply

oI[ (oI >93) & (oI < 152)  ] = 0

should do I think...

According to your question, you want to have specific non-contiguous numbers in an array. That is best handled by a map-reduce algorithm. Let us say you want the following numbers to be set to 0:

numList = np.array([2, 15, 100, 56])

Then you can set a mask like so, and reduce them to a single mask:

mask     = (oI == 2)|(oI == 15)|(oI == 100)|(oI == 56)
oI[mask] = 0

This is clearly not a good solution for a big list of numbers. So you can do ...

mask = reduce( lambda m, n: m|n ,[ oI == i for i in numList]) 
oI[mask] = 0

If it is contiguous, like between a and b, then you just use the earlier approach ...

mask = (oI > a) & (oI < b)

Of course you can combine the masks in any set of contiguous and non contiguous sets of numbers. Just | them.

Hope this helps ...