I recently had a need to upsample weather radar images from the National Weather Service. Here's the URL of the source data:
http://radar.weather.gov/GIS.html
The source images are only about 500x500 pixels and each pixel is about 1 mile across. If used in GIS these images look trashy when zoomed into an area of interest. Most people don't notice this because they're used to seeing these images in a small window on a WEB page that doesn't allow zooming at all. I thought of a cheat - upsample the image before displaying in the map. This method DOES NOT add new information to the resulting image file, but does make the pixel dimensions smaller and thus "prettier" to the user when zoomed in.
The code below is a stand alone command line tool that will upsample an image by some factor then modify the world file to account for the new pixel dimensions. It works pretty good for my purposes!#Using the Python Image Library
#usage: image_resample.py imagefile worldfile factor x_coord y_coord units
#usage example: image_resample.py image1.gif image1.gfw 4 3409583.234 208204.45 feet
import Image
import sys
if "help" in sys.argv or len(sys.argv) == 1:
print"""
This command utility will upsample a Geo-image by some factor.
It presumes the input coordinate system is Lat/Lon NAD83.
useage: Image_Resampler.exe imagefile worldfile factor x_coord y_coord units
example: Image_Resampler.exe image1.gif image1.gfw 4 3409583.234 208204.45 feet
factor - integer
units - feet, meters, or dd (this is all case sensitive!)
"""
raw_input("Press enter to exit...")
sys.exit()
imagefile = sys.argv[1]
worldfile = sys.argv[2]
factor = int(sys.argv[3])
x_coord = float(sys.argv[4])
y_coord = float(sys.argv[5])
units = sys.argv[6]
#some constants
pie = 3.14159265
rad_m = 6371000.0
rad_ft = 22902231.0
#psyco helps to speed the entire application up - this is optional
import psyco
psyco.full()
# Do the image resizing
#######################################
# open an image file (.bmp,.jpg,.png,.gif)
# covert to RGB so the bicubic interpolation upsample actually does something
im1 = Image.open(imagefile).convert("RGB")
#figure out the original pixel dimensions
pixels = im1.size
old_width = pixels[0]
old_height = pixels[1]
# adjust width and height based on the factor
new_width = old_width * factor
new_height = old_height * factor
# use the BICUBIC filter - good quality. Other filters such as NEAREST
# and BILINEAR may be faster.
output = im1.resize((new_width, new_height), Image.BICUBIC)
output.save(imagefile)
#Deal with the world file
#####################################
# Check to see if this is even necessary
if worldfile == "NO":
sys.exit()
# Read the world file
in_file = open(worldfile,'r')
# Turn the stings into floats
world_file_list = map(float,in_file.readlines())
in_file.close()
# Reopen the world file for writing to
out_file = open(worldfile,'w')
# Compute the new pixel dimensions
if units == "feet":
x_dim = world_file_list[0]/factor*pie/180*rad_ft
y_dim = world_file_list[3]/factor*pie/180*rad_ft
elif units == "meters":
x_dim = world_file_list[0]/factor*pie/180*rad_m
y_dim = world_file_list[3]/factor*pie/180*rad_m
elif units == "dd":
x_dim = world_file_list[0]/factor
y_dim = world_file_list[3]/factor
#rebuild the world file list with the new values
world_file_list[0]= x_dim
world_file_list[3]= y_dim
world_file_list[4]= x_coord
world_file_list[5]= y_coord
#turn the floats to strings and write to the world file
for item in world_file_list:
out_file.write(str(item)+'\n')
out_file.close()