#Original Function Location: /themis/lib/dav_lib/public_library/latest/image_stretch.dvrc
/themis/lib/dav_lib/library/image_stretch.dvrc
Source Code for Function: "nstretch()" in "image_stretch.dvrc" (Public)
image_stretch_version=1.03
# dcs - taken from /u/gorelick/dcs.dv
# do_dcs - taken from /u/knowicki/dvrc/tools.dvrc
# do_rgb - taken from /u/knowicki/dvrc/tools.dvrc
# do_rdcs - written to keep in line with other "do_" tools
# do_hsv - written to keep in line with other "do_" tools
# sstretch_old - taken from /u/gorelick/.dvrc
# nstretch - taken from /u/gorelick/.dvrc
# stretch - taken from /u/knowicki/dvrc/stretch.dvrc
# cleandcs - wrapper for thm.cleandcs
# rdcs - taken from /u/cedwards/rstretch2.dvrc
# rsstretch - taken from /u/cedwards/rstretch2.dvrc
# rmnoise_pca - taken from /u/cedwards/christopher.dvrc
# rrmnoise_pca - taken from /u/cedwards/rstretch2.dvrc
# colorize - taken from /u/cedwards/colorize.dvrc
# get_color - taken from /u/cedwards/colorize.dvrc
# lstretch - Added by J. Bandfield 1/2008
define dcs(ignore,sample,variance) {
#c.edwards modified 6-24-10 to make the minimum stretched data value 1 and not 0
if ($ARGC != 1) {
printf("\ndcs()\n")
printf("performs a decorrelation stretch of data.\n")
printf("data will be centered around 127 with a sigma of +- 50.\n")
printf("requires either 1 or 3 bands of data to be stretched.\n\n")
printf("Syntax: dcs(input, [ignore], [sample], [variance])\n")
printf("example: pic=dcs(a, ignore=-32768, sample=b)\n")
printf("example: pic=dcs(cat(a[,,8],a[,,7],a[,,5],axis=z),ignore=0)\n")
printf(" 'input' can be any 1 or 3 band float/short/int array.\n")
printf(" 'ignore' is the null data value. Default = 0.\n")
printf(" 'sample' is an array of identical size to the input\n")
printf(" used to define the limits of the stretch.\n")
printf(" 'variance' is a number or set of 3 numbers defining\n")
printf(" the stretch per axis. (sigma) default = 50 \n\n")
printf("last updated Tue Jan 24 21:34:08 MST 2006\n")
printf("written by Noel Gorelick.\n")
return(null)
}
#
# this does a decorrelation stretch
# Data will be centered around 127, with a sigma of +/- 50.
#
# compute the symmetric covariance matrix and eigenvectors of it.
a = $1;
if (HasValue(sample)) {
if (HasValue(ignore)) {
c = covar(sample, axis=z, ignore=ignore);
#make the mask in this stupid way because of how ignores are handled
mask=byte(a[,,1]*0+1)
mask[where sum(a == ignore,axis=z)>=1 ]=0
} else {
c = covar(sample, axis=z);
mask=byte(a*0+1)
mask[where sum(a == 0,axis=z)>=1]=0
}
} else {
if (HasValue(ignore)) {
c = covar(a, axis=z, ignore=ignore);
mask=byte(a[,,1]*0+1)
mask[where sum(a == ignore,axis=z)>=1 ]=0
} else {
c = covar(a, axis=z);
mask=byte(a*0+1)
mask[where sum(a == 0,axis=z)>=1]=0
}
}
e = eigen(c);
# generate the scaling matrix with the scaling factors on the diagonal
# and compute the rotation matrix
if (HasValue(variance)) {
v = float(variance);
} else {
v = 50.0;
}
s = identity(dim(a)[3]) * v/sqrt(e[1]);
m = mxm(mxm(e[2:], s), translate(e[2:], x, y));
# We have to reshape the data to push it through mxm() because mxm is dumb.
# Force the input to be bip so we can use the forbidden resize() function.
d = dim(a);
a = bip(a);
resize(a, dim(a)[3], dim(a)[1]*dim(a)[2]);
# subtract the mean of each band, rotate and add back 127
if (HasValue(ignore)) {
avg = avg(a,y,ignore=ignore);
} else {
avg = avg(a,y);
}
a = a - avg;
a = mxm(a, m);
a = a + 127;
a = byte(bip(a));
# reshape the data back to its original size
resize(a, d[1], d[2], d[3]);
a[where mask==1 && a==0]=1
return(a);
}
define do_dcs(ignore,sample,variance) {
if($ARGC==0) {
printf("A nice shortcut to dcs THEMIS images with any three bands\n\n")
printf("Syntax: do_dcs(image,band1,band2,band3,ignore,sample,variance)\n")
printf(" 'ignore' null value of the data, default = -32768\n")
printf(" 'sample' a color sample array\n")
printf(" 'variance' specify color variance, default = 50\n")
printf("Examples:\n")
printf(" display(do_dcs(a,9,6,4))\n")
printf(" display(do_dcs(a,7,5,3,ignore=-32768))\n")
printf(" pic=do_dcs(data,variance=cat(80,50,50,axis=y))\n")
printf(" pic=do_dcs(data,ignore=0,sample=b)\n\n")
printf("if 3 bands aren't specified an 8-7-5 stretch is performed\n\n")
printf("last updated Tue Jan 24 21:34:08 MST 2006\n")
printf("written by Keith Nowicki\n")
return(null)
}
ignorev=-32768
var=cat(50,50,50,axis=y)
#$1 is the data
bands = dim($1)[3]
if(HasValue(variance)) var=variance
B1 = 8
B2 = 7
B3 = 5
if($ARGC == 4) {
B1 = $2
B2 = $3
B3 = $4
}
if(B1 > bands || B2 > bands || B3 > bands) {
printf("specified bands do not match data\n")
return(null)
}
printf("performing a %d-%d-%d stretch\n",B1,B2,B3)
if(HasValue(ignore)) ignorev=ignore
data=$1
if(HasValue(sample)==0) {
image=dcs(cat(data[,,B1],data[,,B2],data[,,B3],axis=z),ignore=ignorev,variance=var)
}
if(HasValue(sample)) {
image=dcs(cat(data[,,B1],data[,,B2],data[,,B3],axis=z),ignore=ignorev,sample=cat(sample[,,B1],sample[,,B2],sample[,,B3],axis=z),variance=var)
}
return(image)
}
define do_rgb(ignore,var) {
if($ARGC==0) {
printf("A nice shortcut to RGB images with any three bands\n\n")
printf("Syntax: do_rgb(image,band1,band2,band3,ignore,var)\n")
printf(" 'ignore' null value of the data, default = -32768\n")
printf(" 'var' variance value used in stretch algorithm, default = 40\n")
printf("Examples:\n")
printf(" display(do_rgb(a,9,6,4))\n")
printf(" display(do_rgb(a,7,5,3,ignore=-32768))\n")
printf("if 3 bands aren't specified an 1-2-3 stretch is performed\n")
printf("Calls sstretch() to do the stretching work\n\n")
printf("last updated Fri Oct 20 10:29:30 MST 2006\n")
printf("written by Keith Nowicki\n")
return(null)
}
ignorev=-32768;
bands = dim($1)[3]
B1 = 1;
B2 = 2;
B3 = 3;
variance = 40
if($ARGC == 4) {
B1 = $2
B2 = $3
B3 = $4
}
if(B1 > bands || B2 > bands || B3 > bands) {
printf("specified bands do not match data\n")
return(null)
}
if(HasValue(ignore)) ignorev=ignore;
if(HasValue(var)) variance=var;
data=$1;
data_pic = sstretch(data, var=variance, ignore=ignorev)
image=cat(data_pic[,,B1], data_pic[,,B2], data_pic[,,B3],axis=z);
return(image);
}
define do_rdcs(sample,ignore,variance,ysize,xsize,verbose) {
if($ARGC==0) {
printf("A nice shortcut to rdcs THEMIS images with any three bands\n\n")
printf("Syntax: do_rdcs(image,band1,band2,band3,ignore,sample,variance)\n")
printf(" 'ignore' null value of the data, default = -32768\n")
printf(" 'sample' a color sample array\n")
printf(" 'variance' specify color variance, default = 50\n")
printf("Examples:\n")
printf(" display(do_rdcs(a,9,6,4))\n")
printf(" display(do_rdcs(a,7,5,3,ignore=-32768))\n")
printf(" pic=do_rdcs(data,variance=cat(80,50,50,axis=y))\n")
printf(" pic=do_rdcs(data,ignore=0,sample=b)\n\n")
printf("if 3 bands aren't specified an 8-7-5 stretch is performed\n\n")
printf("last updated Fri Jun 16 10:39:32 MST 2006\n")
printf("written by Keith Nowicki\n")
return(null)
}
ignorev=-32768
var=cat(50,50,50,axis=y)
ys=1000
xs=4000
verb=0
#$1 is the data
bands = dim($1)[3]
if(HasValue(variance)) var=variance
if(HasValue(xsize)) xs=xsize
if(HasValue(ysize)) ys=ysize
if(HasValue(verbose)) verb=verbose
B1 = 8
B2 = 7
B3 = 5
if($ARGC == 4) {
B1 = $2
B2 = $3
B3 = $4
}
if(B1 > bands || B2 > bands || B3 > bands) {
printf("specified bands do not match data\n")
return(null)
}
printf("performing a %d-%d-%d stretch\n",B1,B2,B3)
if(HasValue(ignore)) ignorev=ignore
data=$1
if(HasValue(sample)==0) {
image=rdcs(cat(data[,,B1],data[,,B2],data[,,B3],axis=z),ignore=ignorev,variance=var,ysize=ys,xsize=xs)
}
if(HasValue(sample)) {
image=rdcs(cat(data[,,B1],data[,,B2],data[,,B3],axis=z),ignore=ignorev,sample=cat(sample[,,B1],sample[,,B2],sample[,,B3],axis=z),variance=var,ysize=ys,xsize=xs)
}
return(image)
}
define do_hsv(ignore,colorize) {
if($ARGC<2) {
printf("Perform an HSV overlay using a color and greyscale image pair\n")
printf("$1 = color image or numeric data to use as Hue and Saturation color\n")
printf("\tNote: if the data is not byte and 3 bands you must choose colorize > 0\n")
printf("$2 = black and white replacement image for Value\n")
printf("colorize = perform the colorize option on $1, same colors as in colorize() (Default is 0)\n")
printf("ignore = ignore value for the colorize option (Default is -32768)\n")
printf("\n")
printf("c.edwards 9/21/10\n")
return(null)
}
if(HasValue(colorize)==0) {
colorize=0
}
if(HasValue(ignore)==0) {
ignore=-32768
}
color=$1
bw=$2
if(dim(color)[3]==1 && colorize==0) {
printf("\bThe input color image is not 3 bands\n")
printf("Please select a colorize option or input a 3 band image\n\n")
return(null)
}
if(sum(dim(color)[:2]==dim(bw)[:2])!=2) {
printf("\n$1 and $2 do not have the same X and Y dimensions\n")
printf("Please make sure input data are of the same size\n\b")
return(null)
}
if(dim(color)[3]==1 && colorize!=0) {
color=colorize(color,ignore=ignore,colors=colorize)
}
if(type(color) != "byte") {
printf("\nSupply $1 as a byte array or a numeric array with colorize set to > 0\n\n")
return(null)
}
if(type(bw) != "byte") {
printf("\nSupply $2 as a byte array\n\n")
return(null)
}
color=rgb2hsv(byte(color))
color[,,3]=bw/255.
color=byte(hsv2rgb(color,maxval=255))
return(color)
}
define sstretch_old(variance,ignore) {
if($ARGC==0) {
printf("sstretch_old - sigma stretch the data\n\n")
printf("Syntax: sstretch_old(image,ignore)\n")
printf(" 'ignore' null value of the data, default = -32768\n")
printf("Examples:\n")
printf(" display(sstretch_old(a))\n")
printf(" pic=(sstretch_old(a,ignore=0))\n")
printf("last updated Tue Jan 24 21:34:08 MST 2006\n")
printf("written by Noel Gorelick\n")
return(null)
}
if (HasValue(ignore) == 0) ignore=-32768;
if (HasValue(variance) == 0) {
variance = 40;
}
if (type($1) == "STRUCT") {
b = avg(($1).data, ignore=ignore, both=1);
c = (($1).data - float(b.avg))*(variance/float(b.stddev))+127;
} else {
b = avg($1, ignore=ignore, both=1);
c = ($1 - float(b.avg))*(variance/float(b.stddev))+127;
}
return(byte(c));
}
define nstretch() {
if($ARGC==0) {
printf("nstretch - normalize stretch the data\n\n")
printf("Syntax: nstretch(image)\n")
printf("Examples:\n")
printf(" display(nstretch(a))\n")
printf(" pic=(nstretch(a)\n")
printf("last updated Tue Jan 24 21:34:08 MST 2006\n")
printf("written by Noel Gorelick\n")
return(null)
}
a = $1
b = moment(a)
c = (((a - b[1]) / (b[2]-b[1])) * 255)
return(byte(c))
}
define stretch(out_low, out_high, full, kluge, ignore,region) {
if ($ARGC == 0) {
printf ("\nImage stretch routine\n\n")
printf ("usage: stretch(array, 'stretch_type', param1, [param2], [out_low = i], [out_high = i], [full=1])\n\n")
printf (" where\n")
printf (" stretch_type = auto\n")
printf (" param1 = auto_end_val\n")
printf (" stretch_type = linear\n")
printf (" param1 = z_min\n")
printf (" param2 = z_max\n")
printf (" stretch_type = sigma\n")
printf (" param1 = # of sigmas away from mean
printf (" stretch_type = minmax\n")
printf (" stretch_type = table\n")
printf (" param1 = table mapping of input values to output values\n")
printf (" [,out_low] is low dn in output image (default = 20)\n")
printf (" [,out_high] is high dn in output image (default = 250)\n")
printf (" [,full=1] returns image, along with min and max input values used in stretch in structure\n\n")
printf (" example: out = stretch(in, 'sigma', 3) \n")
printf (" out = stretch(in, 'auto', .01, out_low=10) \n")
printf (" out = stretch(in, 'sigma', 3 out_low=10, full=1) \n")
printf (" out = stretch(in, 'minmax') \n")
printf (" out = stretch(in, 'table', table)\n\n")
printf ("last updated Tue Jan 24 21:34:08 MST 2006\n")
printf ("written by Phil Christensen\n")
return(null)
}
# p. christensen 2/6/00
# k. nowicki 01/17/06
input = $1;
b = byte(input*0.);
size = dim(input);
x1 = 1;
x2 = size[1];
y1 = 1;
y2 = size[2];
if(HasValue(region)) {
x1 = region[1];
x2 = region[2];
y1 = region[3];
y2 = region[4];
printf("statistics region = %d %d %d %d\n", x1, x2, y1, y2);
}
# set low and high values in output image for cosmetic purpose
low_out = 10;
high_out = 250;
if ($2 == "minmax") {
if(HasValue(ignore)) {
m = moment(input, ignore=0);
} else {
m = moment(input);
}
b = (((input - m[1]) / (m[2]-m[1])) * 255);
printf("stretching %.1e to 0 %.1e to 255\n", m[1], m[2]);
return(byte(b));
}
if ($2 == "auto") {
# do this one the "dumb" way - loop on bands
nbands = dim(input)[3];
low_dn_array = create(1,1,dim(input)[3],format=float);
high_dn_array = create(1,1,dim(input)[3],format=float);
for (iband = 1 ; iband <= nbands ; iband+=1) {
# set values less than 0 to 0
# tmp = input[,,iband]
# tmp[where(input[,,iband]<=0.)] = 0.
# a = histogram(input[,,iband], steps=2560, compress=1)
# changed to include region - prc - 10/30/02
a = histogram(input[x1:x2, y1:y2, iband], steps=2560, compress=1);
len = dim(a)[2];
# zero out 0 and 255 values - i.e. remove peaks at start and end
a[2,1] = 0;
a[2,len] = 0;
if(HasValue(kluge)) {
printf(" doing the kluge\n");
# zero out 20 points at high and low ends of histogram before to auto ends
a[2,1:100] = 0;
a[2,len-100:len] = 0;
}
total = sum(a[2,]);
auto_end = $3;
end = total * $3;
if(HasValue(out_low)) {
low_out = out_low;
}
if(HasValue(out_high)) {
high_out = out_high;
}
# this code is for historical reasons - param_map uses this form
if ($ARGC >= 4) {
low_out = $4;
high_out = $5;
}
low_dn = low_out;
high_dn = high_out;
# find auto-end point on low end of histogram
cum = 0;
for (i = 1 ; i <= len ; i+=1) {
cum = cum + a[2,i, 1];
if (cum > end) {
# found point at low DN limit
low_dn = a[1,i, 1];
break;
}
}
# find auto-end point on high end of histogram
cum = 0;
for (i = 1 ; i <= len ; i+=1) {
counter = len+1-i;
# counter = 255-i
cum = cum + a[2,counter, 1];
if (cum > end) {
# found point at high DN limit
high_dn = a[1,counter, 1];
break;
}
}
printf("doing auto_end stretch: plane = %d auto_ends = %.4e low input value = %.2e high input value = %.2e low output dn = %d high output dn = %d\n",iband, auto_end, low_dn, high_dn, low_out, high_out);
slope = float(high_out - low_out) / (high_dn - low_dn);
printf ("slope = %.2f\n",slope);
b[,,iband] = (input[,,iband] - low_dn) * slope + low_out;
low_dn_array[,,iband] = low_dn;
high_dn_array[,,iband] = high_dn;
}
}
if ($2 == "sigma") {
printf("doing sigma stretch\n")
if(HasValue(ignore)) {
# changed to use region - prc - 10/30/02
tmp = avg(input[x1:x2, y1:y2], axis=xy, both=1, ignore=0);
} else {
tmp = avg(input[x1:x2, y1:y2], axis=xy, both=1);
}
ave = tmp.avg;
stddev = tmp.stddev;
if ($ARGC >= 4) {
low_out = $4;
high_out = $5;
}
low_dn = ave - (stddev * $3);
high_dn = ave + (stddev * $3);
slope = float(high_out - low_out) / (high_dn - low_dn);
b = (input - low_dn) * slope + low_out;
# printf("linear stretch: iband = %d low_dn = %.2f high_dn = %.2f slope = %.2f\n",iband, low_dn, high_dn, slope)
}
if ($2 == "linear") {
printf("doing linear stretch\n");
low_dn = $3;
high_dn = $4;
if(HasValue(out_low)) {
low_out = out_low;
}
if(HasValue(out_high)) {
high_out = out_high;
}
slope = float(high_out - low_out) / (high_dn - low_dn);
b = (input - low_dn) * slope + low_out;
printf("linear stretch: low_out = %d high_out = %d low_dn = %.2f high_dn = %.2f slope = %.2f\n", low_out, high_out, low_dn, high_dn, slope);
}
if ($2 == "table") {
printf("doing table mapping stretch\n");
table = $3;
tdimx = dim(table)[1];
tdimy = dim(table)[2];
if(tdimy <= 1 || tdimx != 2) {
printf("\nThe table must a 2xNx1 array, where N must be larger than 1\n");
printf("column 1 is the input value, column 2 is the output value\n");
return(NULL);
}
b = input*0.0;
#loop through the mapping sets and perform linear stretches
for(i=1;i
low_in = float(table[1,i]);
high_in = float(table[1,i+1]);
low_out = float(table[2,i]);
high_out = float(table[2,i+1]);
slope = float(high_out - low_out) / (high_in - low_in);
b[where (input >= low_in && input < high_in)] = (input - low_in) * slope + low_out;
}
}
if(HasValue(full)) {
# return array and min, max values
struc = struct();
struc.out = b;
if($2 == "auto") {
struc.min = low_dn_array;
struc.max = high_dn_array;
} else {
struc.min = low_dn;
struc.max = high_dn;
}
return(struc);
} else {
return(byte(b));
}
}
define cleandcs(opt) {
if($ARGC==0) {
printf("cleandcs() - removes unwanted saturated pixels in dcs images\n")
printf("Syntax: cleandcs(image,opt)\n")
printf(" 'image' a byte color picture resulting from a dcs operation\n")
printf(" 'opt' option for level of cleaning. Default = 2\n")
printf(" opt=1 removes all pixels with 255 in one band and 0 in others\n")
printf(" opt=2 removes all pixels with 255 in two bands and 0 in other\n\n")
printf("last updated Tue Jan 24 21:34:08 MST 2006\n")
printf("written by Keith Nowicki\n")
return(null)
}
op = 2
img = $1
if(HasValue(opt)) op = int(opt)
if(op == 1) img[where max(img,axis=z) == 255 && max(img,axis=z,ignore=255) == 0] = 0
if(op == 2) img[where min(img,axis=z) == 0 && min(img,axis=z,ignore=0) == 255] = 0
return(img)
}
define rdcs(data,sample,ignore,variance,ysize,xsize,verbose) {
#c.edwards modified 6-24-10 to make the minimum stretched data value 1 and not 0
if($ARGC==0 && HasValue(data)==0) {
printf("\nCompute a Running DCS Stretch\n")
printf("Calls dcs() as stretching function\n\n")
printf("$1=data (3-band or 1-band)\n")
printf("data=data option for more efficient memory usage\n")
printf("ignore=value to ignore (Default=-32768)\n")
printf("ysize=size of the chunks to stretch in y (Default=1000)\n")
printf("xsize=size of the chunks to stretch in x (Default=4000)\n")
printf("NOTE: both xsize and ysize must be even integers\n")
printf("variance=variance of the stretch (Default=50)\n")
printf("sample=sample image\n\n")
printf("NOTE: can also be used to change variance of each band\n")
printf("variance=cat(50,20,40,axis=y)\n\n")
printf("verbose = turn on print statements\n\n")
printf("c.edwards 3/7/06\n\n")
return(null)
}
#initialize input
if(HasValue(data)==0) data=$1
xs=4000
ys=1000
ign=-32768
var=50.0
verb=0
ydiff=xdiff=0
dim=dim(data)
if(HasValue(verbose)) verb=1
if(HasValue(ysize)) ys=int(ysize)
if(HasValue(xsize)) xs=int(xsize)
if(HasValue(ignore)) ign=ignore
if(HasValue(variance)) var=variance
if(ys%2 == 1) ys-=1
if(xs%2 == 1) xs-=1
#create output pic, ramps and indices
pic=byte(data*0)
mask=byte(data[,,1]*0+1)
mask[where sum(data == ignore,axis=z)>=1]=0
yrange=xrange=clone(0,2,1,1)
yramp=create(1,int(ys/2),1,start=0,step=(1/(ys/2.)),format=float)
xramp=create(int(xs/2),1,1,start=0,step=(1/(xs/2.)),format=float)
#set maximum loop values
maxx=dim[1]-int(xs/2)
maxy=dim[2]-int(ys/2)
if(dim[1]
if(dim[2]
#loop through x to get x-direction
for(i=1;i<=maxx;i+=int(xs/2)) {
xrange[1]=i;xrange[2]=i+xs-1
if(xrange[2]>=dim[1]) {
xdiff=xrange[2]-dim[1]
xrange[2]=dim[1]
}
tmppic=byte(clone(0,xrange[2]-i+1,dim[2],dim[3]))
#loop through y to get y-direction
for(j=1;j<=maxy;j+=int(ys/2)) {
yrange[1]=j;yrange[2]=j+ys-1
if(yrange[2]>=dim[2]) {
ydiff=yrange[2]-dim[2]
yrange[2]=dim[2]
}
if(verb==1) printf("x=%i:%i y=%i:%i\n",xrange[1],xrange[2],yrange[1],yrange[2])
#stretch the data
if(HasValue(sample)) {
tmp=dcs(data[xrange[1]:xrange[2],yrange[1]:yrange[2],],ignore=ign,variance=var,sample=sample[xrange[1]:xrange[2],yrange[1]:yrange[2],])
}else{
tmp=dcs(data[xrange[1]:xrange[2],yrange[1]:yrange[2],],ignore=ign,variance=var)
}
#if its the first y-chunk then insert else ramp it into the y-column
if(j==1) tmppic[,yrange[1]:yrange[2],]=tmp
if((j!=1 && ydiff>int(ys/2))) break;
if(j!=1) {
tmppic[,yrange[1]:yrange[2]-int(ys/2)+ydiff]=tmppic[,yrange[1]:yrange[2]-int(ys/2)+ydiff]*(1-yramp)
tmp[,:int(ys/2),]=tmp[,:int(ys/2),]*yramp
tmppic[,yrange[1]:yrange[2],]=tmppic[,yrange[1]:yrange[2],]+tmp
}
ydiff=0
}
#if its the first x-chunk then insert else ramp it into the full picutre
if(i==1) pic[xrange[1]:xrange[2],]=tmppic
if((i!=1 && xdiff>int(xs/2))) return(bip(byte(pic)))
if(i!=1) {
pic[xrange[1]:xrange[2]-int(xs/2)+xdiff,]=pic[xrange[1]:xrange[2]-int(xs/2)+xdiff,]*(1-xramp)
tmppic[:int(xs/2),]=tmppic[:int(xs/2),]*xramp
pic[xrange[1]:xrange[2],]=pic[xrange[1]:xrange[2],]+tmppic
}
}
pic[where mask==1 && pic==0]=1
return(bip(byte(pic)))
}
define rsstretch(data,ignore,variance,ysize,xsize,verbose) {
if($ARGC==0 && HasValue(data)==0) {
printf("\nCompute a Running SStretch\n")
printf("Calls sstretch() as stretching function\n\n")
printf("$1=data\n")
printf("data=data option for more efficient memory usage\n")
printf("ignore=value to ignore (Default=-32768)\n")
printf("ysize=size of the chunks to stretch in y (Default=1000)\n")
printf("xsize=size of the chunks to stretch in x (Default=4000)\n")
printf("NOTE: both xsize and ysize must be even integers\n")
printf("variance=variance of the stretch (Default=40)\n\n")
printf("verbose = turn on print statements\n\n")
printf("c.edwards 3/7/06\n\n")
return(null)
}
#initialize input
if(HasValue(data)==0) data=$1
xs=4000
ys=1000
ign=-32768
var=40
verb=0
ydiff=xdiff=0
dim=dim(data)
if(HasValue(verbose)) verb=1
if(HasValue(ysize)) ys=int(ysize)
if(HasValue(xsize)) xs=int(xsize)
if(HasValue(ignore)) ign=ignore
if(HasValue(variance)) var=variance
if(ys%2 == 1) ys-=1
if(xs%2 == 1) xs-=1
#create output pic, ramps and indices
pic=byte(data)
pic[]=0
yrange=xrange=clone(0,2,1,1)
yramp=create(1,int(ys/2),1,start=0,step=(1/(ys/2.)),format=float)
xramp=create(int(xs/2),1,1,start=0,step=(1/(xs/2.)),format=float)
#set maximum loop values
maxx=dim[1]-int(xs/2)
maxy=dim[2]-int(ys/2)
if(dim[1]
if(dim[2]
#loop through x to get x-direction
for(i=1;i<=maxx;i+=int(xs/2)) {
xrange[1]=i;xrange[2]=i+xs-1
if(xrange[2]>=dim[1]) {
xdiff=xrange[2]-dim[1]
xrange[2]=dim[1]
}
tmppic=byte(clone(byte(0),xrange[2]-i+1,dim[2],dim[3]))
#loop through y to get y-direction
for(j=1;j<=maxy;j+=int(ys/2)) {
yrange[1]=j;yrange[2]=j+ys-1
if(yrange[2]>=dim[2]) {
ydiff=yrange[2]-dim[2]
yrange[2]=dim[2]
}
if(verb==1) printf("x=%i:%i y=%i:%i\n",xrange[1],xrange[2],yrange[1],yrange[2])
#stretch the data
tmp=sstretch(data[xrange[1]:xrange[2],yrange[1]:yrange[2],],ignore=ign,variance=var)
#if its the first y-chunk then insert else ramp it into the y-column
if(j==1) tmppic[,yrange[1]:yrange[2],]=tmp
if((j!=1 && ydiff>int(ys/2))) break;
if(j!=1) {
tmppic[,yrange[1]:yrange[2]-int(ys/2)+ydiff]=tmppic[,yrange[1]:yrange[2]-int(ys/2)+ydiff]*(1-yramp)
tmp[,:int(ys/2),]=tmp[,:int(ys/2),]*yramp
tmppic[,yrange[1]:yrange[2],]=tmppic[,yrange[1]:yrange[2],]+tmp
}
ydiff=0
}
#if its the first x-chunk then insert else ramp it into the full picutre
if(i==1) pic[xrange[1]:xrange[2],]=tmppic
if((i!=1 && xdiff>int(xs/2))) {
pic[where data!=ign && pic==0]=1
return(bip(byte(pic)))
}
if(i!=1) {
pic[xrange[1]:xrange[2]-int(xs/2)+xdiff,]=pic[xrange[1]:xrange[2]-int(xs/2)+xdiff,]*(1-xramp)
tmppic[:int(xs/2),]=tmppic[:int(xs/2),]*xramp
pic[xrange[1]:xrange[2],]=pic[xrange[1]:xrange[2],]+tmppic
}
}
pic[where data!=ign && pic==0]=1
return(bip(byte(pic)))
}
define rmnoise_pca(null,filt,noise_sample,debug,b10,mult) {
if($ARGC==0) {
printf("\nRemove image noise with cse.rmnoise() and other methods\n\n")
printf("This script uses cse.rmnoise() and eigen vectors\n")
printf("to help clean the data. Compared to\n")
printf("cse.rmnoise() more color information is retained\n\n")
printf("$1 = 10 band THEMIS IR data (will accept less bands but specify b10 location)\n")
printf("null = null value of the image (Default is -32768)\n")
printf("filt = the filter length for cse.rmnoise() (Default is 7)\n")
printf("b10 = the loacation of band 10 set to 0 if no band 10 exists\n\n")
printf("mult = multiplier (Default=10000, best for radiance data)\n")
printf("noise_sample = the sample area for eigen2 to determine vectors\n")
printf("This is found automatically but to use this to submit \n")
printf("an alternate sample of the noise returned from thm.white_noise_remove2()\n")
printf("This should be fewer than 4000 total points or eigen2 may fail\n")
printf("The number of points is related to the time required to process\n")
printf("\nNOTE: This WILL CHANGE the data and should only be used for\n")
printf("\"pretty pictures\". Band 10 will be smoothed by convolution\n")
printf("\nc.edwards 3/7/06\n\n")
return(null)
}
verbose=0
data=$1
mul=10000
if(HasValue(mult)) mul=mult
# get arguement and data properties
filter=7
if(HasValue(filt)) {
filter=filt
}
nullval=-32768
if(HasValue(null)) {
nullval=null
}
x=dim(data)[1]
y=dim(data)[2]
z=dim(data)[3]
band10=z
if(HasValue(b10)) band10=b10
if(band10==0) band10=z+1
#no user defined sample
if(HasValue(noise_sample)==0) {
#determine sample size for x and y
count=1
xsample=x
while(xsample>10) {
xsample=x/count
count+=1
}
xsamplen=count
count=1
ysample=y
while(ysample>40) {
ysample=y/count
count+=1
}
ysamplen=count
}
#run rmnoise on the data
clean=thm.white_noise_remove2(data,ignore=nullval,filt=filter,b10=band10)
#separate the old noise array
noise=data-clean
#sample the data
if(HasValue(noise_sample)==0) {
noise_mult_sample=noise[::xsamplen,::ysamplen,1:band10-1]*float(mul)
}
#user specified sample
if(HasValue(noise_sample)) {
noise_mult_sample=noise_sample
}
#run eigen2 on the sample data
printf("\nDetermining Eigen Vectors\n")
e_struct=eigen2(noise_mult_sample,band10-2)
#run jpca on data and eigen_struct to apply vectors to data
printf("Calculating Principal Components\n")
noise_pca=pca2(noise[,,:band10-1]*10000,e_struct)
#set the first principal component equal to zero
noise_pca[,,1]=noise_pca[,,1]*0
#reconstruct the noise (error message of division by zero normal)
noise_recon=pca2_recon(noise_pca,e_struct,band10-2)
noise_recon=noise_recon/float(mul)
noise_pca=0
#add the correction back
new_clean=clean
clean=0
new_clean[,,:band10-1]=new_clean[,,:band10-1]+(noise[,,:band10-1]-noise_recon)
noise=noise_recon=0
#take care of color shift caused by rmnoise
color_shift=avg(data-new_clean,axis=xy,ignore=nullval)
new_clean[,,:band10-1]=new_clean[,,:band10-1]+color_shift[,,:band10-1]
verbose=3
#if there is debug option selected then return extra info
if(HasValue(debug)) {
out={}
out.new_clean=float(new_clean)
out.eigen_struct=e_struct
out.color_shift=color_shift
return(out)
} else {
return(float(new_clean))
}
}
define rrmnoise_pca(data,ignore,ysize,xsize,verbose,b10,mult) {
if($ARGC==0 && HasValue(data)==0) {
printf("\nCompute a Running rmnoise_pca\n")
printf("$1=data\n")
printf("data=data option for more efficient memory usage\n")
printf("ignore=value to ignore (Default=-32768)\n")
printf("ysize=size of the chunks (Default=1000)\n")
printf("xsize=size of the chunks (Default=1000)\n")
printf("b10=band 10 location (Default=10, 0=no band 10)\n")
printf("mult=multiplier value (Default=10000, good for radiance data)\n")
printf("CAUTION: SLOWER THAN HELL!!!\n")
printf("verbose = turn on print statements\n\n")
printf("c.edwards 3/7/06\n\n")
return(null)
}
#initialize input
if(HasValue(data)==0) data=$1
xs=1000
ys=1000
ign=-32768
var=40
verb=0
ydiff=xdiff=0
mul=10000
dim=dim(data)
band10=dim[3]
if(HasValue(verbose)) verb=1
if(HasValue(ysize)) ys=int(ysize)
if(HasValue(xsize)) xs=int(xsize)
if(HasValue(ignore)) ign=ignore
if(HasValue(variance)) var=variance
if(HasValue(b10)) band10=b10
if(HasValue(mult)) mul=mult
if(ys%2 == 1) ys-=1
if(xs%2 == 1) xs-=1
#create output pic, ramps and indices
pic=float(data*0)
bmask=byte(pic*0)
bmask[where data!=ign]=1
yrange=xrange=clone(0,2,1,1)
yramp=create(1,int(ys/2),1,start=0,step=(1/(ys/2.)),format=float)
xramp=create(int(xs/2),1,1,start=0,step=(1/(xs/2.)),format=float)
#set maximum loop values
maxx=dim[1]-int(xs/2)
maxy=dim[2]-int(ys/2)
if(dim[1]
if(dim[2]
#loop through x to get x-direction
for(i=1;i<=maxx;i+=int(xs/2)) {
xrange[1]=i;xrange[2]=i+xs-1
if(xrange[2]>=dim[1]) {
xdiff=xrange[2]-dim[1]
xrange[2]=dim[1]
}
tmppic=float(clone(0,xrange[2]-i+1,dim[2],dim[3]))
#loop through y to get y-direction
for(j=1;j<=maxy;j+=int(ys/2)) {
yrange[1]=j;yrange[2]=j+ys-1
if(yrange[2]>=dim[2]) {
ydiff=yrange[2]-dim[2]
yrange[2]=dim[2]
}
if(verb==1) printf("x=%i:%i y=%i:%i\n",xrange[1],xrange[2],yrange[1],yrange[2])
#stretch the data
tmp=rmnoise_pca(data[xrange[1]:xrange[2],yrange[1]:yrange[2],],null=ign,mult=mul,b10=band10)
#if its the first y-chunk then insert else ramp it into the y-column
if(j==1) tmppic[,yrange[1]:yrange[2],]=tmp
if((j!=1 && ydiff>int(ys/2))) break;
if(j!=1) {
tmppic[,yrange[1]:yrange[2]-int(ys/2)+ydiff]=tmppic[,yrange[1]:yrange[2]-int(ys/2)+ydiff]*(1-yramp)
tmp[,:int(ys/2),]=tmp[,:int(ys/2),]*yramp
tmppic[,yrange[1]:yrange[2],]=tmppic[,yrange[1]:yrange[2],]+tmp
}
ydiff=0
}
#if its the first x-chunk then insert else ramp it into the full picutre
if(i==1) pic[xrange[1]:xrange[2],]=tmppic
if((i!=1 && xdiff>int(xs/2))) {
pic[where bmask==0]=ign
return(float(pic))
}
if(i!=1) {
pic[xrange[1]:xrange[2]-int(xs/2)+xdiff,]=pic[xrange[1]:xrange[2]-int(xs/2)+xdiff,]*(1-xramp)
tmppic[:int(xs/2),]=tmppic[:int(xs/2),]*xramp
pic[xrange[1]:xrange[2],]=pic[xrange[1]:xrange[2],]+tmppic
}
}
pic[where bmask==0]=ign
return(float(pic))
}
define colorize(colors,values,type,ignore) {
#Added $DV_EX support
#Added $DV_SCRIPT_FILES support - 5-13-08
#added color_tables directory to $DV_SCRIPT_FILES
if($ARGC==0) {
printf("Colorize any numeric array\n\n")
printf("$1 = numeric array to be colorized\n")
printf("ignore = ignore value of the data\n")
printf("type = rgb or hsv colorization (Default = \"rgb\")\n")
printf("colors = number of colors to use 1 = 6 colors, 2 = 7 colors\n")
printf(" 3 = xv color scale, 4 = tes colormap, 5 = tes daily colormap (Default = 1)\n")
printf("values = values of the data for each color (Assigned linearly by default)\n")
printf("\nn.gorelick\n")
printf("Modified by c.edwards Aug 15, 2006\n")
return(null)
}
in = $1
if (HasValue(ignore) == 0) {
ignore = -32768
}
color=1
if(HasValue(colors)) color=colors; colors=0
if(color==1) {
colors = {}
colors += { get_color("Magenta")}
colors += { get_color("Blue")}
colors += { get_color("Lime")}
colors += { get_color("Yellow")}
colors += { get_color("Orange")}
colors += { get_color("Red") }
}
if (color==2) {
colors = {}
colors += { get_color("Magenta")}
colors += { get_color("Blue")}
colors += { get_color("Cyan")}
colors += { get_color("Lime")}
colors += { get_color("Yellow")}
colors += { get_color("Orange")}
colors += { get_color("Red") }
}
if(color==3) {
scalebar=read($DV_SCRIPT_FILES+"/color_tables/xvscalebar.ppm")
colors={}
for(i=1;i<=dim(scalebar)[1];i+=1) {
colors+={scalebar[i,1]}
}
values=create(dim(scalebar)[1],1,1,bsq,int,0,1)
}
if(color==4) {
scalebar=read($DV_SCRIPT_FILES+"/color_tables/colormap.ppm")
colors={}
for(i=1;i<=dim(scalebar)[1];i+=1) {
colors+={scalebar[i,1]}
}
values=create(dim(scalebar)[1],1,1,bsq,int,0,1)
}
if(color==5) {
scalebar=read($DV_SCRIPT_FILES+"/color_tables/colormap_daily.ppm")
colors={}
for(i=1;i<=dim(scalebar)[1];i+=1) {
colors+={scalebar[i,1]}
}
values=create(dim(scalebar)[1],1,1,bsq,int,0,1)
}
if (HasValue(values) == 0) {
values = create(length(colors),1,1)/float(length(colors)-1)
maxval = max(in,ignore=ignore)
minval = min(in,ignore=ignore)
values = values * (maxval-minval) + minval
for (i = 1 ; i <= length(colors) ; i+=1) {
printf("%3.3d,%3.3d,%3.3d = %f\n", colors[i][,,1], colors[i][,,2], colors[i][,,3], values[i]);
}
}
if (HasValue(type) == 0) type = "rgb"
c = colors[1]
for (i = 2 ; i <= length(colors) ; i+=1) {
c = cat(c, colors[i], x)
}
if (type == "hsv") c = rgb2hsv(c,maxval=255)
rgb = clone(float(in)*0, 1, 1, 3)
rgb[,,1] = interp(c[,,1], values, in)
rgb[,,2] = interp(c[,,2], values, in)
rgb[,,3] = interp(c[,,3], values, in)
rgb[where in < values[1]] = c[1]
rgb[where in > values[length(values)]] = c[length(colors)]
rgb[where in==ignore] = 0
if (type == "hsv") rgb = hsv2rgb(rgb, maxval=255)
rgb = bip(byte(rgb))
return(rgb)
}
define get_color(display) {
colors = {"AliceBlue", 240//248//255, \
"AntiqueWhite", 250//235//215, \
"Aqua", 0//255//255, \
"Aquamarine", 127//255//212, \
"Azure", 240//255//255, \
"Beige", 245//245//220, \
"Bisque", 255//228//196, \
"Black", 0//0//0, \
"BlanchedAlmond", 255//235//205, \
"Blue", 0//0//255, \
"BlueViolet", 138//43//226, \
"Brown", 165//42//42, \
"Burlywood", 222//184//135, \
"CadetBlue", 95//158//160, \
"Chartreuse", 127//255//0, \
"Chocolate", 210//105//30, \
"Coral", 255//127//80, \
"CornflowerBlue", 100//149//237, \
"Cornsilk", 255//248//220, \
"Cyan", 0//255//255, \
"DarkBlue", 0//0//139, \
"DarkCyan", 0//139//139, \
"DarkGoldenrod", 184//134//11, \
"DarkGray", 169//169//169, \
"DarkGreen", 0//100//0, \
"DarkKhaki", 189//183//107, \
"DarkMagenta", 139//0//139, \
"DarkOliveGreen", 85//107//47, \
"DarkOrange", 255//140//0, \
"DarkOrchid", 153//50//204, \
"DarkRed", 139//0//0, \
"DarkSalmon", 233//150//122, \
"DarkSeaGreen", 143//188//143, \
"DarkSlateBlue", 72//61//139, \
"DarkSlateGray", 47//79//79, \
"DarkTurquoise", 0//206//209, \
"DarkViolet", 148//0//211, \
"DeepPink", 255//20//147, \
"DeepSkyBlue", 0//191//255, \
"DimGray", 105//105//105, \
"DodgerBlue", 30//144//255, \
"Firebrick", 178//34//34, \
"FloralWhite", 255//250//240, \
"ForestGreen", 34//139//34, \
"Fuschia", 255//0//255, \
"Gainsboro", 220//220//220, \
"GhostWhite", 255//250//250, \
"Gold", 255//215//0, \
"Goldenrod", 218//165//32, \
"Gray", 128//128//128, \
"Green", 0//128//0, \
"GreenYellow", 173//255//47, \
"Honeydew", 240//255//240, \
"HotPink", 255//105//180, \
"Ivory", 255//255//240, \
"Khaki", 240//230//140, \
"Lavender", 230//230//250, \
"LavenderBlush", 255//240//245, \
"LawnGreen", 124//252//0, \
"LemonChiffon", 255//250//205, \
"LightBlue", 173//216//230, \
"LightCoral", 240//128//128, \
"LightCyan", 224//255//255, \
"LightGoldenrod", 238//221//130, \
"LightGoldenrodYellow", 250//250//210, \
"LightGray", 211//211//211, \
"LightGreen", 144//238//144, \
"LightPink", 255//182//193, \
"LightSalmon", 255//160//122, \
"LightSeaGreen", 32//178//170, \
"LightSkyBlue", 135//206//250, \
"LightSlateBlue", 132//112//255, \
"LightSlateGray", 119//136//153, \
"LightSteelBlue", 176//196//222, \
"LightYellow", 255//255//224, \
"Lime", 0//255//0, \
"LimeGreen", 50//205//50, \
"Linen", 250//240//230, \
"Magenta", 255//0//255, \
"Maroon", 128//0//0, \
"MediumAquamarine", 102//205//170, \
"MediumBlue", 0//0//205, \
"MediumOrchid", 186//85//211, \
"MediumPurple", 147//112//219, \
"MediumSeaGreen", 60//179//113, \
"MediumSlateBlue", 123//104//238, \
"MediumSpringGreen", 0//250//154, \
"MediumTurquoise", 72//209//204, \
"MediumVioletRed", 199//21//133, \
"MidnightBlue", 25//25//112, \
"MintCream", 245//255//250, \
"MistyRose", 255//228//225, \
"Moccasin", 255//228//181, \
"NavajoWhite", 255//222//173 }
colors+={"Navy", 0//0//128}
colors+={"OldLace", 253//245//230, \
"Olive", 128//128//0, \
"OliveDrab", 107//142//35, \
"Orange", 255//128//0, \
"OrangeRed", 255//69//0, \
"Orchid", 218//112//214, \
"PaleGoldenrod", 238//232//170, \
"PaleGreen", 152//251//152, \
"PaleTurquoise", 175//238//238, \
"PaleVioletRed", 219//112//147, \
"PapayaWhip", 255//239//213, \
"PeachPuff", 255//218//185, \
"Peru", 205//133//63, \
"Pink", 255//192//203, \
"Plum", 221//160//221, \
"PowderBlue", 176//224//230, \
"Purple", 128//0//128, \
"Red", 255//0//0, \
"RosyBrown", 188//143//143, \
"RoyalBlue", 65//105//225, \
"SaddleBrown", 139//69//19, \
"Salmon", 250//128//114, \
"SandyBrown", 244//164//96, \
"SeaGreen", 46//139//87, \
"Seashell", 255//245//238, \
"Sienna", 160//82//45, \
"Silver", 192//192//192, \
"SkyBlue", 135//206//235, \
"SlateBlue", 106//90//205, \
"SlateGray", 112//128//144, \
"Snow", 255//250//250, \
"SpringGreen", 0//255//127, \
"SteelBlue", 70//130//180, \
"Tan", 210//180//140, \
"Teal", 0//128//128, \
"Thistle", 216//191//216, \
"Tomato", 255//99//71, \
"Turquoise", 64//224//208, \
"Violet", 238//130//238, \
"VioletRed", 208//32//144, \
"Wheat", 245//222//179, \
"White", 255//255//255, \
"WhiteSmoke", 245//245//245, \
"Yellow", 255//255//0, \
"YellowGreen", 154//205//50}
if ($ARGC == 0) {
printf("\nGets the rgb color values from a color name\n")
printf("The colors included are many (if not all) of the standard web colors\n\n")
printf("n.gorelick\n")
printf("Modified by c.edwards Aug 15, 2006\n\n")
printf("Color options are shown below\n\n")
for (i = 1 ; i < length(colors) ; i+=2) {
printf("%s\n", colors[i]);
}
} else {
for (i = 1 ; i < length(colors) ; i+=2) {
if (colors[i] == $1) {
if(HasValue(display)) {
display(bip(byte(clone(translate(colors[i+1],x,z),100,100))))
}
return(translate(colors[i+1],x,z))
}
}
printf("Color not found: %s\n", $1)
return(null)
}
}
define lstretch(ignore,in_low,in_high,out_low,out_high) {
if ($ARGC == 0) {
printf("Do a linear stretch for a single band image.\n")
printf(" \n")
printf("$1 = input image\n")
printf("in_low = in data low value\n")
printf("in_high = in data high value\n")
printf("out_low = out data low value\n")
printf("out_high = out data high value\n")
printf("All ins and outs are optional. Output is byte.\n")
printf("ignore = ignore value (default is -32768)\n")
printf(" \n")
printf(" \n")
return(0)
}
data=$1
# Make sure we only have a 1 band image
data=data[,,1]
if (HasValue(ignore) == 0) {
ignorev=-32768
} else {
ignorev=ignore
}
if (HasValue(in_low) == 0) {
in_lowv=min(data, ignore=ignorev)
} else {
in_lowv=float(in_low)
}
if (HasValue(in_high) == 0) {
in_highv=max(data, ignore=ignorev)
} else {
in_highv=float(in_high)
}
if (HasValue(out_low) == 0) {
out_lowv=float(0)
} else {
out_lowv=float(out_low)
}
if (HasValue(out_high) == 0) {
out_highv=float(255)
} else {
out_highv=float(out_high)
}
slope=float((out_highv-out_lowv))/float((in_highv-in_lowv))
intercept=out_lowv-in_lowv*slope
out=slope*data+intercept
out[where data!=ignorev && out<=out_lowv]=out_lowv
out[where (data==ignorev)]=0
return(byte(out))
}