3

Can someone guide me for applying thresholding technique to input raster image using Python.

I intend to extract impervious surfaces from a high resolution raster such as roads, sideways and rooftops etc.

11
  • What type of imagery/data are you working with?
    – Aaron
    Commented Jul 2, 2015 at 12:28
  • I am working with Google Earth imagery having spatial resolution of 0.5m.
    – khajlk
    Commented Jul 2, 2015 at 12:36
  • Ok, so the imagery is not georeferenced (e.g. a screenshot in jpeg or png format)?
    – Aaron
    Commented Jul 2, 2015 at 12:37
  • 1
    Aaron, It ain't a screenshot. It is in TIFF format (raster image) and has been georeferenced.
    – khajlk
    Commented Jul 2, 2015 at 12:45
  • Please specify what you mean by "thresholding". Keeping data inbetween certain thresholds as masks? Have you produced any code so far which would clarify what you want?
    – Kersten
    Commented Jul 2, 2015 at 12:49

2 Answers 2

4

You can use the OpenCV package in Python for image thresholding. This example shows not only how to perform the binary image thresholding, but also the limitations of this method. Here, I use a 1m spatial resolution NAIP image that shows a dirt road surrounded by arid vegetation. You can see that the road is extracted but there is also a significant amount of exposed soil and other background noise that is also extracted. There are a variety of other thresholding methods available in OpenCV that you may want to investigate.


enter image description here


import cv2
import numpy as np
from matplotlib import pyplot as plt

# Read the geotiff as greyscale image
img = cv2.imread(r'C:\your\path\roads_naip.tif',0)

# Apply the binary threshold. The second parameter "150" can be adjusted here.
ret,thresh1 = cv2.threshold(img,150,255,cv2.THRESH_BINARY)

titles = ['Original Image','Binary']
images = [img, thresh1]

for i in xrange(2):
    plt.subplot(1,2,i+1),plt.imshow(images[i],'gray')
    plt.title(titles[i])
    plt.xticks([]),plt.yticks([])

plt.show()
4
  • This code works fine until inputting an image but on line ret,thresh1 = cv2.threshold(img,139,255,cv2.THRESH_BINARY) it returns an ASSERTION ERROR like this, error: (-215) m.dims >= 2 in function cv::Mat::Mat I have tried to change the value of second parameter several times but the problem persists.
    – khajlk
    Commented Jul 2, 2015 at 17:36
  • How are you running OpenCV? It is best to run cv2 via a distribution such as python(x,y).
    – Aaron
    Commented Jul 2, 2015 at 17:41
  • Also, are you using 8-bit unsigned integer format rasters?
    – Aaron
    Commented Jul 2, 2015 at 17:46
  • I am running OpenCV package in Enthought Python Distribution. Yes, the input TIFF RGB image is 8-bit unsigned integer raster having cell size (X,Y) = 0.5,0.5.
    – khajlk
    Commented Jul 2, 2015 at 18:30
0

Well, thank you so much @Aaron. The problem has solved. I have realized that the above code needs to be slightly modified for the case of Google Earth imagery regarding its conversion to grey-scale intensity image. Following is the output of my modified code. Impervious surfaces of building rooftops have been extracted. Nevertheless, the results can be much improved through the combination of different thresholding techniques of OpenCV package.

Applying image thresholding to Google Earth imagery

3
  • 2
    @JibranKhan - You should consider accepting Aaron's solution by clicking the green-faded tick on the left-hand side of his post to show that this question has been answered :)
    – Joseph
    Commented Jan 13, 2016 at 11:13
  • 1
    @Joseph: Done, though a bit late :) Thank you for guidance.
    – khajlk
    Commented Jan 13, 2016 at 13:49
  • Most welcome buddy! And don't worry about being late =)
    – Joseph
    Commented Jan 14, 2016 at 10:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.