Modulenotfounderror: No Module Named 'Pydip', Although It's Installed

ImportError after successful pip installation

TL;DR: There are often multiple versions of python interpreters and pip versions present. Using python -m pip install <library-name> instead of pip install <library-name> will ensure that the library gets installed into the default python interpreter.

Please also note: From my personal experience I would advice against using sudo pip install to install packages into system's default python interpreter. This can lead to a various messy issues.
Whenever you are tempted to call pip with sudo, please check first if a virtualenv is not a better option for you.


Most modern systems ship multiple python interpreters. Each interpreter maintains its own set of installed packages. When installing new packages, it is important to understand into which interpreter those packages are actually installed.

On unix systems the shell can be used to understand what exactly is happening.

Typing which -a python shows all interpreters that in your PATH. The first line corresponds to the interpreter that is used when you run python from the command line.

/private/tmp/py32/bin/python
/usr/local/bin/python
/usr/bin/python

Each pip version belongs to exactly one interpreter. which -a pip shows all pip versions. Again the first line is what will be called when you type pip in your shell.

/usr/local/bin/pip
/usr/bin/python

Note that in this case python belongs to the interpreter installed in /private/tmp/py32/, but pip installs into the interpreter /usr/local/bin. After a successful install of a library, you will not be able to import it in your default python interpreter.

So how do you import the installed library?

Your first option is to start the desired interpreter with its full path. So if you type /usr/local/bin/python, you will be able to import the library.

The second - often preferred - option is to specifically invoke the right version of pip. To do so, you can use python -m pip install <library-name> instead of pip install <library-name>. This will call the pip version that belongs to your default python interpreter.

How to detect light spots in image?

In short, you'll get a very poor estimate of size using your method. The edges of the blurred regions, no matter what threshold you pick, do not correspond to the edges of the inselbergs you want to measure.
Instead, I suggest you follow the recipe below. I'm using DIPlib in Python for this (disclaimer: I'm an author). The Python bindings are a thin layer on the C++ library, it's fairly simple to translate the Python code below to C++ (it's just easier for me to develop it interactively in Python). Install with pip install diplib.

I downloaded the original height data from the link you provided (rather than the declivity). DIPlib can directly read floating-point valued TIFF files, so there is no need for any special conversion. I cropped a region similar to the one used by OP for this demo, but there is no reason to not apply the method to the whole tile.

import diplib as dip

height = dip.ImageRead('17S42_ZN.tif')
height.SetPixelSize(0.000278, 'rad') # not really radian, but we don't have degrees
height = height[3049:3684, 2895:3513];

The code also sets the pixel size according to data in the TIFF file (using units of radian, because DIPlib doesn't do degrees).

image height

Next, I apply the top-hat filter with a specific diameter (25 pixels). This isolates all peaks with a diameter of 25 pixels or less. Adjust this size according to what you think the maximum width an inselberg should be.

local_height = dip.Tophat(height, 25)

In effect, the result is a local height, the height above some baseline determined by the size of the filter.

image local_height

Next, I apply a hysteresis threshold (double threshold). This yields a binary image, thresholded at 100m above the baseline, where the terrain goes above 200m above that baseline. That is, I decided that an inselberg should be at least 200m above the baseline, but cut each of them off at 100m. At this height we'll be measuring the size (area). Again, adjust the thresholds as you see fit.

inselbergs = dip.HysteresisThreshold(local_height, 100, 200)

image inselbergs

Now all that is left is measuring the regions we found:

labels = dip.Label(inselbergs)
result = dip.MeasurementTool.Measure(labels, features=['Size', 'Center'])
print(result)

This outputs:

   |       Size |                  Center | 
-- | ---------- | ----------------------- |
| | dim0 | dim1 |
| (rad²) | (rad) | (rad) |
-- | ---------- | ---------- | ---------- |
1 | 1.863e-05 | 0.1514 | 0.01798 |
2 | 4.220e-05 | 0.1376 | 0.02080 |
3 | 6.214e-05 | 0.09849 | 0.04429 |
4 | 6.492e-06 | 0.1282 | 0.04710 |
5 | 3.022e-05 | 0.1354 | 0.04925 |
6 | 4.274e-05 | 0.1510 | 0.05420 |
7 | 2.218e-05 | 0.1228 | 0.05802 |
8 | 1.932e-05 | 0.1420 | 0.05689 |
9 | 7.690e-05 | 0.1493 | 0.06960 |
10 | 3.285e-05 | 0.1120 | 0.07089 |
11 | 5.248e-05 | 0.1389 | 0.07851 |
12 | 4.637e-05 | 0.1096 | 0.09016 |
13 | 3.787e-05 | 0.07146 | 0.1012 |
14 | 2.133e-05 | 0.09046 | 0.09908 |
15 | 3.895e-05 | 0.08553 | 0.1064 |
16 | 3.308e-05 | 0.09972 | 0.1143 |
17 | 3.277e-05 | 0.05312 | 0.1174 |
18 | 2.581e-05 | 0.07298 | 0.1167 |
19 | 1.955e-05 | 0.04038 | 0.1304 |
20 | 4.846e-05 | 0.03657 | 0.1448 |

(Remember, where it says 'rad' it is really degrees.) An area in square degrees is a bit weird, but you can convert this to square meters since you know the location on the globe. It might in fact be easier to translate the pixel sizes to meters before the computations.

The values given here for 'Center' are with respect to the top-left pixel, if we hadn't cropped the tile to begin with, we could have added the coordinates for the tile (as can be obtained from the corresponding tag in the TIFF file): (-42.0, -17.0).


In C++ the code should look like this:

#include <diplib/simple_file_io.h>
#include <diplib/morphology.h>
#include <diplib/segmentation.h>
#include <diplib/regions.h>
#include <diplib/measurement.h>

//...

dip::Image height = dip::ImageRead("17S42_ZN.tif");
height.SetPixelSize(0.000278 * dip::Units::Radian());
height = height.At(dip::Range(3049, 3684), dip::Range(2895, 3513));

dip::Image local_height = dip::Tophat(height, 25);

dip::Image inselbergs = dip::HysteresisThreshold(local_height, 100, 200);

dip::Image labels = dip::Label(inselbergs);
dip::MeasurementTool measurementTool;
dip::Measurement result = measurementTool.Measure(labels, {}, {"Size", "Center"});
std::cout << result;


Related Topics



Leave a reply



Submit