Skip to content

Commit 1fc3fc8

Browse files
committed
Loading the untracked code.
1 parent 8e69739 commit 1fc3fc8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+8589
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.pyc

imgproc/README

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
2+
This repository contains set of simple (geo-)image processing tools.
3+
4+
The tools are primarily build on Python GDAL/OGR and Numpy modules.
5+
6+
I hope you'll find some of them usefull.
7+
8+
List of Files:
9+
10+
img_block.py shared python module (raster processing)
11+
extract_mask.py data/no-data mask extractor
12+
extract_mask2.py data/no-data mask extractor (2 no-data values)
13+
find_subset.py calculates offset and size of image
14+
subset containing the data and
15+
cropping out the no-data borders
16+
extract_subset.py extract image subset
17+
smooth_mask.py this tool applies Gaussian blur and
18+
thresholding to smooth mask borders
19+
extract_footprint.py extract footprint from raster image (mask)
20+
clip_to_mask.py sets masked pixels as no-data
21+
create_tiff.py creates empty tiff from a master (master
22+
defines pixel size and geocoding, type
23+
and band count is arbitrary) - possible use
24+
start image for gdal rasterization.
25+
extract_bit_mask.py Extract bit flag as 'byte' mask from
26+
a flag (multi-mask) image.
27+
28+
get_gdaladdo_levels.py propose 'gdaladdo' overview levels
29+
30+
get_histogram.py calculate image bands' histograms (linear of dB-scale)
31+
range_stretch.py image bands' ranges stretching (linear of dB-scale)
32+
33+
34+
img_geom.py shared python module (vector processing)
35+
mgrs.py shared utilities handling MGRS locations
36+
utm.py shared UTM utilities
37+
38+
eoxs_wkt_footprint.py extract footprint from a geo-referenceable
39+
DS (requires EOxServer/reftools)
40+
41+
geom_info.py print information about the input geometry
42+
geom_cut_to_mgrs_grid.py get list of MGR 100km squares covering the geometry
43+
geom_raster_extent.py get raster image extent as a rectange (polygon)
44+
geom_raster_outline.py get outline of raster feature as a (multi)polygon
45+
geom_rasterize.py rasterize geometry to an existing image
46+
geom_ctrans.py peform coordinate transformation of the input gemometry
47+
optionally including proper date-line wrapping
48+
geom_buffer.py bufffer geometry
49+
geom_simplify.py simplify geometry
50+
geom_segmentize.py segmentize geometry
51+
geom_union.py unite multiple geometries
52+
geom_insect.py intersect multiple geometries

imgproc/clip_to_mask.py

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
#!/usr/bin/env python
2+
#------------------------------------------------------------------------------
3+
#
4+
# This tool clips data to mask. Based on the mask value, the code
5+
# performs folloging pixel operations:
6+
# mask no-data value (0x00) -> sets pixel to a given no-data value
7+
# mask data value (0xFF) -> copies pixel from the original image
8+
#
9+
# This tool extracts subset of the image specified by the row/column
10+
# offset of the upper-left corenr and row/column size of extracted
11+
# block. The tool takes care about preserving the geo-metadata.
12+
#
13+
# Project: Image Processing Tools
14+
# Authors: Martin Paces <[email protected]>
15+
#
16+
#-------------------------------------------------------------------------------
17+
# Copyright (C) 2013 EOX IT Services GmbH
18+
#
19+
# Permission is hereby granted, free of charge, to any person obtaining a copy
20+
# of this software and associated documentation files (the "Software"), to deal
21+
# in the Software without restriction, including without limitation the rights
22+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
23+
# copies of the Software, and to permit persons to whom the Software is
24+
# furnished to do so, subject to the following conditions:
25+
#
26+
# The above copyright notice and this permission notice shall be included in all
27+
# copies of this Software or works derived from this Software.
28+
#
29+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
32+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
34+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
35+
# THE SOFTWARE.
36+
#-------------------------------------------------------------------------------
37+
38+
import sys
39+
import os.path
40+
import img_block as ib
41+
import img_util as iu
42+
import numpy as np
43+
44+
def clipToMask( bi , bm , mask_fg , nodata ) :
45+
46+
if bi.non_equal_2d( bm ) :
47+
raise RuntimeError( "Equal blocks' extents required!" )
48+
49+
# prepare list of no-data values
50+
if len( nodata ) == 1 :
51+
nodata = [ nodata[0] for i in xrange(bi.data.shape[2]) ]
52+
53+
fg = ( bm.data[:,:,0] == mask_fg )
54+
bg = ( bm.data[:,:,0] != mask_fg )
55+
56+
for i in xrange( bi.data.shape[2] ) :
57+
bi.data[:,:,i] = bg * nodata[i] + fg * bi.data[:,:,i]
58+
59+
#------------------------------------------------------------------------------
60+
61+
if __name__ == "__main__" :
62+
63+
# TODO: to improve CLI
64+
65+
EXENAME = os.path.basename( sys.argv[0] )
66+
67+
def error( message ) :
68+
print >>sys.stderr, "ERROR: %s: %s\n" %( EXENAME, message )
69+
70+
# block size
71+
bsx , bsy = 256, 256
72+
73+
# default format options
74+
75+
FOPTS = ib.FormatOptions()
76+
FOPTS["TILED"] = "YES"
77+
FOPTS["BLOCKXSIZE"] = "256"
78+
FOPTS["BLOCKYSIZE"] = "256"
79+
FOPTS["COMPRESS"] = "DEFLATE"
80+
81+
try:
82+
83+
INPUT = sys.argv[1]
84+
MASK = sys.argv[2]
85+
OUTPUT = sys.argv[3]
86+
NODATA = sys.argv[4].split(",")
87+
MASKBG = 0x00
88+
MASKFG = 0xFF
89+
90+
#anything else treated as a format option
91+
for opt in sys.argv[5:] :
92+
FOPTS.setOption( opt )
93+
94+
except IndexError :
95+
96+
error("Not enough input arguments!")
97+
sys.stderr.write("USAGE: %s <input image> <mask> <output TIF> <no data value or list>\n"%EXENAME)
98+
sys.stderr.write("EXAMPLE: %s input.tif mask.tif output.tif 255,255,255\n"%EXENAME)
99+
sys.stderr.write("EXAMPLE: %s input.tif mask.tif output.tif 0\n"%EXENAME)
100+
sys.exit(1)
101+
102+
# open input image
103+
imi = ib.ImgFileIn( INPUT )
104+
105+
# convert no-data values to the image's data type
106+
NODATA = map( np.dtype(imi.dtype).type, NODATA )
107+
108+
if len(NODATA) < imi.sz :
109+
NODATA=[ NODATA[0] for i in xrange(imi.sz) ]
110+
111+
# open input mask
112+
imm = ib.ImgFileIn( MASK )
113+
114+
# check mask properties
115+
116+
if imm.sz > 1 :
117+
error("Multiband mask not supported!")
118+
sys.exit(1)
119+
120+
if imm.dtype != 'uint8' :
121+
error("Unsupported mask data type '%s'!"%imi.dtype)
122+
sys.exit(1)
123+
124+
if not imm.equal_2d( imi ) :
125+
error("Input mask and image must have the same pixel"
126+
" size! image: (%d x %d) mask: (%d x %d)" %(
127+
imi.sy , imi.sx, imm.sy , imm.sx ) )
128+
sys.exit(1)
129+
130+
# creation parameters
131+
prm = {
132+
'path' : OUTPUT,
133+
'nrow' : imi.sy,
134+
'ncol' : imi.sx,
135+
'nband' : imi.sz,
136+
'dtype' : imi.dtype,
137+
'options' : FOPTS.getOptions(),
138+
'nodata' : NODATA,
139+
}
140+
141+
#print prm
142+
143+
# geocoding
144+
if imi.ds.GetProjection() :
145+
prm['proj'] = imi.ds.GetProjection()
146+
prm['geotrn'] = imi.ds.GetGeoTransform()
147+
elif imi.ds.GetGCPProjection() :
148+
prm['proj'] = imi.ds.GetGCPProjection()
149+
prm['gcps'] = imi.ds.GetGCPs()
150+
151+
# open output image
152+
imo = ib.createGeoTIFF( **prm )
153+
154+
#--------------------------------------------------------------------------
155+
156+
# initialize progress printer
157+
prg = iu.Progress( (1+(imi.sy-1)/bsy)*(1+(imi.sx-1)/bsx) )
158+
159+
print "Clipping image by a mask ..."
160+
161+
for ty in xrange( 1 + (imi.sy-1)/bsy ) :
162+
for tx in xrange( 1 + (imi.sx-1)/bsx ) :
163+
164+
# extent of the tile
165+
ex_ti = imi & ib.ImgExtent( (bsx,bsy,imi.sz) , (tx*bsx,ty*bsy,0) )
166+
ex_tm = imi & ib.ImgExtent( (bsx,bsy,1) , (tx*bsx,ty*bsy,0) )
167+
168+
# allocate input image block
169+
bi = ib.ImgBlock( imi.dtype , extent = ex_ti )
170+
171+
# allocate mask block
172+
bm = ib.ImgBlock( imm.dtype , extent = ex_tm )
173+
174+
# load image block
175+
imi.read( bi )
176+
177+
# load mask block
178+
imm.read( bm )
179+
180+
# clip image block to mask
181+
clipToMask( bi , bm , MASKFG , NODATA )
182+
183+
# save image block
184+
imo.write( bi )
185+
186+
# print progress
187+
sys.stdout.write(prg.istr(1)) ; sys.stdout.flush()
188+
189+
sys.stdout.write("\n") ; sys.stdout.flush()

imgproc/count_mask_pixels.py

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
#!/usr/bin/env python
2+
#------------------------------------------------------------------------------
3+
#
4+
# Extract pixel count.
5+
#
6+
# Project: Image Processing Tools
7+
# Authors: Martin Paces <[email protected]>
8+
#
9+
#-------------------------------------------------------------------------------
10+
# Copyright (C) 2013 EOX IT Services GmbH
11+
#
12+
# Permission is hereby granted, free of charge, to any person obtaining a copy
13+
# of this software and associated documentation files (the "Software"), to deal
14+
# in the Software without restriction, including without limitation the rights
15+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16+
# copies of the Software, and to permit persons to whom the Software is
17+
# furnished to do so, subject to the following conditions:
18+
#
19+
# The above copyright notice and this permission notice shall be included in all
20+
# copies of this Software or works derived from this Software.
21+
#
22+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28+
# THE SOFTWARE.
29+
#-------------------------------------------------------------------------------
30+
31+
import sys
32+
import os.path
33+
import img_block as ib
34+
import numpy as np
35+
import math as m
36+
from osgeo import ogr ; ogr.UseExceptions()
37+
from osgeo import osr ; ogr.UseExceptions()
38+
from osgeo import gdal ; gdal.UseExceptions()
39+
40+
#------------------------------------------------------------------------------
41+
42+
#------------------------------------------------------------------------------
43+
# pixel counters
44+
45+
def countPixelsEQL( bi, value ):
46+
return np.sum( bi.data[:,:,0] == value )
47+
48+
def countPixelsAND( bi, value ):
49+
return np.sum( ( bi.data[:,:,0] & value ) != 0 )
50+
51+
#------------------------------------------------------------------------------
52+
53+
if __name__ == "__main__" :
54+
55+
# TODO: to improve CLI
56+
57+
EXENAME = os.path.basename( sys.argv[0] )
58+
59+
DEBUG=False
60+
OPERATOR="EQL"
61+
OPERATORS=("EQL","AND","ALL")
62+
63+
try:
64+
65+
INPUT = sys.argv[1]
66+
VALUE = int( sys.argv[2] )
67+
NP = 2
68+
if len(sys.argv) > NP :
69+
for arg in sys.argv[NP:] :
70+
if ( arg in OPERATORS ) : OPERATOR = arg # match operator
71+
elif ( arg == "DEBUG" ) : DEBUG = True # dump debuging output
72+
73+
except IndexError :
74+
75+
sys.stderr.write("\nCount pixels.\n\n")
76+
sys.stderr.write("Not enough input arguments!\n")
77+
sys.stderr.write("USAGE: %s <input image> <data-value> [AND|EQL*] [DEBUG]\n"%EXENAME)
78+
sys.exit(1)
79+
80+
#--------------------------------------------------------------------------
81+
82+
# open input image
83+
imi = ib.ImgFileIn( INPUT )
84+
85+
# check input image
86+
87+
if imi.sz > 1 :
88+
sys.stderr.write( "ERROR: %s: Multiband images not supported!" \
89+
"\n"%(EXENAME) )
90+
sys.exit(1)
91+
92+
if imi.dtype not in ('uint8','int8','uint16','int16','uint32','int32') :
93+
sys.stderr.write( "ERROR: %s: Unsupported image data type '%s'!" \
94+
"\n"%(EXENAME,imi.dtype) )
95+
sys.exit(1)
96+
97+
#--------------------------------------------------------------------------
98+
99+
if DEBUG:
100+
print >>sys.stderr, "OPERATOR:" , OPERATOR
101+
print >>sys.stderr, "VALUE: " , VALUE
102+
103+
if OPERATOR == "EQL" :
104+
countPixels = countPixelsEQL
105+
elif OPERATOR == "AND" :
106+
countPixels = countPixelsAND
107+
elif OPERATOR == "ALL" :
108+
print ( imi.sx * imi.sy )
109+
sys.exit(0)
110+
else:
111+
sys.stderr.write( "ERROR: %s: Unsupported operator! OPERATOR='%s'!" \
112+
"\n"%(EXENAME,OPERATOR) )
113+
sys.exit(1)
114+
115+
#--------------------------------------------------------------------------
116+
bsx , bsy = 256,256
117+
118+
count = 0
119+
120+
for ty in xrange( 1 + (imi.sy-1)/bsy ) :
121+
for tx in xrange( 1 + (imi.sx-1)/bsx ) :
122+
123+
if DEBUG:
124+
sys.stderr.write("#")
125+
sys.stderr.flush()
126+
127+
# extent of the tile
128+
ex_t = imi & ib.ImgExtent( (bsx,bsy,imi.sz) , (tx*bsx,ty*bsy,0) )
129+
130+
# allocate input image block
131+
bi = ib.ImgBlock( imi.dtype , extent = ex_t )
132+
133+
# load image block
134+
imi.read( bi )
135+
136+
# count pixels
137+
count += countPixels( bi, VALUE )
138+
139+
# save image block
140+
#imo.write( bo )
141+
142+
if DEBUG:
143+
sys.stderr.write("\n")
144+
sys.stderr.flush()
145+
146+
print count

0 commit comments

Comments
 (0)