<jupyter_start><jupyter_text>Spatial filtering using ENVI 5.5  Aims  After completing this practical, you should be able to answer the questions: Which type of filter should I use for a given filtering application? What impact will the size and shape of the filter have on the output? You should have some understanding of the process (and issues) of spatial filtering of EO data using ENVI.   Data The datasets you need for this practical are available from (skip this step if you've already downloaded them for the [Image Display](ImageDisplay.ipynb) practical):* [ETM-190600](https://www.dropbox.com/s/a6q9k52arscz7tm/ETM-190600?dl=0)* [ETM-190600.HDR](https://www.dropbox.com/s/rnclhr1jtu1c0x4/ETM-190600.HDR?dl=0)* [TM-280589](https://www.dropbox.com/s/4aubve362tkqdnh/TM-280589?dl=0)* [TM-280589.HDR](https://www.dropbox.com/s/1bh5423bf0ka7u7/TM-280589.HDR?dl=0)You should download these data and put them in a directory (folder) that you will remember!The data you will be using are:* six wavebands of a Landsat TM image over Greater London, imaged on May 28th 1989. The data were obtained from the GLCF which maintains a large database of (freely available) Landsat and other imagery. The data are at an original pixel spacing of 28.5 m, but have been resampled to a 25 m grid here. The data are in a Transverse Mercator projection with OSGB 1936 datum. * six wavebands (nominally the same wavelengths) of a Landsat ETM image with 25 m spatial resolution, covering the same spatial extent. These data were obtained on June 19th 2000. The data were obtained from Landmap which contains a database available to Universities and other users through an Athens login (done via the institution you are at). The wavebands are:|1|2|3|4|5|6|| --- | --- | --- | --- | --- | --- || blue | green | red | nir | swir1 | swir 2 ||450-520 nm|520-600 nm| 630-690 nm|760-900 nm|1550-1750 nm|2080-2350 nm|The extent of the imagery is (Lat/Lon): $$    51^o 43'   9.23'' North, 0^o 36' 18.37'' West $$to$$    51^o 16' 29.32'' North,  0^o 27' 24.60'' East$$   Introduction ***In this section, we load the image data we wish to explore***. The purpose of this practical is for you to build on practical 1 and learn about the process of spatial (convolution) filtering. Note that convolution is a mathematical operation involving the modification of one function by another to produce a third (output) function. In spatial fitering this implies the operation of a filter (one function) on an input image (another function) to produce a filtered image (the output).The session will be normally requiring at least two hours of effort. You may not complete all tasks in detail during the live session, so once you get the hang of how to use the tools, move on to the next section and return later to think more about the remote sensing. There is a good material for this in text books (e.g. Jensen, Curran etc.) and some of this is online e.g. much of the Jensen material. First, obtain and then load the `TM` and `ETM` images of London that we used in a previous practical. **View the ETM image as a FCC.**![fcc1](images/fcc1.png)  Convolution filtering ***In this section, we use various tools for image convolution***.A description of the various options for convolution and morphology are as [envi help pages](http://www.exelisvis.com/docs/ConvolutionMorphologyFilters.html). You should have a quick read over this if you are not familiar with the types of filter we will be using.These operations are available via the `Toolbox` menu:![toolbox2](images/toolbox2.png)![conv](images/conv.png)***Apply a high pass filter (the one shown above) to the dataset***Now Display this and the original dataset using `Views->Two Vertical Views` with the convolution result in the left.You should then `Views->Link Views` to 'geo-link' the two views (creating a new link, clicking on the left view as the 'anchor' and then the right as the 'reference'), so that moving around or zooming in one view is performed the same for both views. Make sure to move around the views to match each other before linking them (one simple way is to 'Zoom to full extent' for both views). ![link](images/link-view.png)***Make sure you make notes of what you have done and how you have done it so you can recall this later.***Now, find an interesting part of the image, for example Richmond Park, and try to understand how the filter is operating over the features you see.You might find it easiest to use a greyscale image for this rather than false or real colour.![richmond1](images/richmond1.png) You may find it useful to examine horizontal or vertical profiles of the original satellite data:![profiles](images/profiles.png)You may need to zoom in to the image to see the detail of the transect, but what you should be interested in examining is the relationship between features in the original dataset and the high-pass dataset.For instance, looking at the NIR band, for a transect going over Richmond Park we see higher DN over the park than surrounding (urban) areas (**why?**) in the original data. In the corresponding high pass filtered dataset (below), we see variation in the filtered result around zero, with some 'larger' features (spikes).Consider carefully the numerical values in the convolution kernel:| _ | _ |_ || --- | --- | --- || -1 | -1 | -1 || -1 | 8 | -1 || -1 | -1 | -1 |***What does it indicate when there is a positive (or negative) spike in the filtered transect?******Why is there a number 8 in the centre of the filter?******what does the filter produce if the image data are constant? ('flat')******what does the filter produce if the image data show a step change? (see e.g. resevoirs)***![transdd](images/transdd.png)![profile3](images/profile3.png)  Convolution  To think some more about this, it can be instructive to consider filtering in one dimension (rather than the two dimensions of an image). To aid this, we can consider some prototype 'shapes' and look at how ther respond under the filtering operation.Typical example would be step and ramp features.<jupyter_code>%matplotlib inline
run python/proto.py<jupyter_output><empty_output><jupyter_text>Two basic operations we can perform are looking at the *local average* (e.g. mean) or *local difference* with a convolution operator.For a local mean over extent 3, we would use| _ | _ |_ || --- | --- | --- || 0.333 | 0.333 | 0.333 |***What do the numbers add up to? why is that so******what would a filter of extent 7 look like?***We would expect the local mean to provide some 'smoothing' of the function:<jupyter_code>run python/protoLow.py<jupyter_output>filter [0.14285714285714285, 0.14285714285714285, 0.14285714285714285, 0.14285714285714285, 0.14285714285714285, 0.14285714285714285, 0.14285714285714285]<jupyter_text>We can see that this is the case in the illustration (filter width 7) the impact (of smoothing) on the 'clean' signals is mostly negligible (which is an effect we would want), and for the noisy datasets, the noise is reduced.We can also note some 'edge effects' (e.g. the step at x = 100): **why do these occur?*****does the extent of the edge effects depend on the extent of the filter? If so, why******what might be done to mitigate such effects?***A local mean (low pass) filter then, such as that shown above reduces the high frequency components of the signal and retains the low frequency components (so we can 'get rid of' (reduce)) random noise in the signal. A local mean is effectively a local *integration* of the signal.The 'opposite' of this is differentiation, i.e. the difference between one pixel value and the next.The simplest filter for this is:| _ | _ || --- | --- | | 1 | -1 | which we can call a first order difference filter.***what do the values in the filter add up to in this case?******why is this so?***The impact of this is illustrated below.<jupyter_code>run python/protoHi1.py<jupyter_output>filter [1.0, -1.0]<jupyter_text>***Think through *why* it has the impact that we see.******Of what use might such a filter be?*** If we convolve the first order differential filter:| _ | _ || --- | --- | | 1 | -1 | we get a *second order differential filter*| _ | _ |_ || --- | --- | --- || 1 | -2 | 1|Whereas the first filter represents the 'rate of change' (e.g. slope) of the signal, the second order filter gives the rate of change of the rate of change (rate of change of slope).***what do the values in the filter add up to in this case?******why is this so?***To illustrate this:<jupyter_code>filt = [1.0,-1.0]
print (np.convolve(filt,filt))
run python/protoHi2.py<jupyter_output>filter [1.0, -2.0, 1.0]<jupyter_text>At first sight, this might look quite similar to the result of the first order differential.However, if we look more closely:<jupyter_code>run python/protoHi2zoom.py<jupyter_output>filter [1.0, -2.0, 1.0]<jupyter_text>we see e.g. that the 'edge' of the step edge is mapped to a 'zero crossing' in this case, rather than a local maximum as was the case for the first order filter.The peak of the ramp shows a small negative value in the second order differential data: ***why is this so?******What would the result look like if we were to replace the step and ramp functions by one minus step and one minus ramp?***  As a final example, let us consider what happens if we *smooth* (low pass) and then *differentiate* (high pass):<jupyter_code># show the result of convolving one filter with another filter
filt1 = [1.0,-1.0]
w = 3
filt2 = [1./w]*w
print ('differential',str(['%4.2f'%i for i in filt1]).replace("'",''))
print ('smoother    ',str(['%4.2f'%i for i in filt2]).replace("'",''))
conv = np.convolve(filt1,filt2,'full')
print ('combined    ',str(['%4.2f'%i for i in conv]).replace("'",''))<jupyter_output>differential [1.00, -1.00]
smoother     [0.33, 0.33, 0.33]
combined     [0.33, 0.00, 0.00, -0.33]<jupyter_text>Applying two filters to an image/signal has the same effect as convolving the two filters together and then applying this.We see that convolving a filter of extent 2 with one of extent 3 gives a new filter of extent 4. ***Why is this so?***To demonstrate, in the plots below, we first convolve the step and ramp with `filter 1` (***what type of filter is this?***) (blue line), then convolve this with `filter 2` (***what type of filter is this?***) (green line). Applying the combined filter to the data, we get the dashed red line (which is the same as the green line).<jupyter_code>run python/protoHiLow.py<jupyter_output>filter 1:         [1.00, -2.00, 1.00]
filter 2:         [0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14]
combined filter:  [0.14, -0.14, 0.00, 0.00, 0.00, 0.00, 0.00, -0.14, 0.14]<jupyter_text>Thinking through these graphs should re-inforrce what you have learned about spatial convolution in the lectures. You should be able to describe what the impact of different forms of filter on such prototype functions would be. You should then be able to translate this knowledge back to examining the image data.***Go back to the `envi` session and examine the impact of first and second order differential and smoothing filters on the image data******Relate what you see (e.g. in looking in detail at transects) to the impacts on the prototype shapes******Of what use might all of this be?***  4. Extras (optional) If you run these notes as an iPython notebook, then this shows an interactive tool to see the impact of filtering. **Additionally, if you open our pratical notebooks (you may have noticed the xxx.ipynb file extension) with Jupyter, it also allows you to make changes to the notes, and further down the line, to modify or even write your own code (e.g. for the coursework)!**1) If you don't have [iPython Jupyter](https://ipython.org/) installed on your PC, please use Anaconda on UCL Desktop.`Apps -> Anaconda3 (64bit) -> Anaconda Navigator`Ignore requests to update.2) Download the practical notes from here [https://github.com/UCL-EO/GEOG0027/](https://github.com/UCL-EO/GEOG0027/), using the green botton say `Code`, under which you'll find `Download zip`. Then extract the .zip file.2) Launch a Jupyter Notebook (Top right). This will appear as a webpage. Use the file navigator to find the extracted notes. ![Canopy](images/AnacondaNav.png)3) Find this file `SpatialFiltering.ipynb`, and open. It will display it in a web browser.4) If needed, delete the zip file(s) to free up space. From here, you can use the following interactive tool to explore the trade-offs you need to consider when filtering: e.g. a wider smoothing filter will suppress a higher level of noise (i.e. do more smoothing) than a narrow filter. However, with a wider filter, you are likely to suffer from greater 'edge effects'.<jupyter_code>run python/interact.py<jupyter_output>-1 (498,) (500,) (499,)
{'fraction_non_alphanumeric': 0.09554040285288816, 'fraction_numerical': 0.03950152833294145, 'mean_word_length': 4.425170068027211, 'pattern_counts': {'":': 0, '<': 26, '<?xml version=': 0, '>': 30, 'https://': 7, 'lorem ipsum': 0, 'www.': 5, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '155624', 'license': 'CC0-1.0', 'n_tokens_mistral': 3954, 'n_tokens_neox': 3578, 'n_words': 1855, 'path': 'docs/SpatialFiltering.ipynb', 'repo_name': 'UCL-EO/GEOG0027', 'size': '12759'}