source: tags/release-1.2.2/src/Utils/zscale.cc

Last change on this file was 517, checked in by MatthewWhiting, 15 years ago

Templating the zscale function.

File size: 4.8 KB
Line 
1// -----------------------------------------------------------------------
2// zscale.cc: Get a suitable pixel value scaling for displaying a 2D
3//            image in greyscale.
4// -----------------------------------------------------------------------
5// Copyright (C) 2006, Matthew Whiting, ATNF
6//
7// This program is free software; you can redistribute it and/or modify it
8// under the terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 2 of the License, or (at your
10// option) any later version.
11//
12// Duchamp is distributed in the hope that it will be useful, but WITHOUT
13// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15// for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with Duchamp; if not, write to the Free Software Foundation,
19// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
20//
21// Correspondence concerning Duchamp may be directed to:
22//    Internet email: Matthew.Whiting [at] atnf.csiro.au
23//    Postal address: Dr. Matthew Whiting
24//                    Australia Telescope National Facility, CSIRO
25//                    PO Box 76
26//                    Epping NSW 1710
27//                    AUSTRALIA
28// -----------------------------------------------------------------------
29#include <iostream>
30#include <algorithm>
31#include <duchamp/Utils/utils.hh>
32const int nsample=1000;
33// const int width=300;
34const int width=150;
35const float contrast=0.25;
36
37template <class Type>
38void zscale(long imagesize, Type *image, Type &z1, Type &z2)
39{
40
41  float *smallarray = new float[nsample];
42  float *ct = new float[nsample];
43  long size=0;
44
45  float mean=0.,sd=0.;
46  for(int i=0;i<imagesize;i++) mean+=image[i];
47  mean /= float(imagesize);
48  for(int i=0;i<imagesize;i++) sd+=(image[i]-mean)*(image[i]-mean);
49  sd /= float(imagesize);
50 
51
52  if(imagesize>nsample){
53    int step = (imagesize / nsample) + 1;
54    for(int i=0;i<imagesize;i++){
55      if((i%step)==0){
56        smallarray[size] = image[i];
57        ct[size]=(float)size+1.;
58        size++;
59      }
60    }
61  }
62  else{
63    for(int i=0;i<imagesize;i++){
64      smallarray[i] = image[i];
65      ct[i] = float(i+1);
66    }
67    size=imagesize;
68  }
69
70  std::sort(smallarray,smallarray+size);
71 
72  /* fit a linear slope to the centre of the cumulative distribution */
73  long midpt = size/2;
74  long imin = midpt - width;
75  float slope,intercept,errSlope,errIntercept,r;
76  if(size<2*width)
77    linear_regression(size,ct,smallarray,0,size-1,slope,errSlope,
78                      intercept,errIntercept,r);
79  else linear_regression(size,ct,smallarray,imin,imin+2*width,slope,errSlope,
80                         intercept,errIntercept,r);
81
82  z1 = smallarray[midpt] + (slope/contrast)*(float)(1-midpt);
83  z2 = smallarray[midpt] + (slope/contrast)*(float)(nsample-midpt);
84
85  if(z1==z2){
86 
87    if(z1!=0) z2 = z1 * 1.05;
88    else z2 = z1+0.01;
89
90  }
91
92  delete [] smallarray;
93  delete [] ct;
94           
95}
96template void zscale<float>(long imagesize, float *image, float &z1, float &z2);
97template void zscale<double>(long imagesize, double *image, double &z1, double &z2);
98
99template <class Type>
100void zscale(long imagesize, Type *image, Type &z1, Type &z2, Type blankVal)
101{
102  float *newimage = new float[imagesize];
103  int newsize=0;
104  for(int i=0;i<imagesize;i++) if(image[i]!=blankVal) newimage[newsize++] = image[i];
105
106  float *smallarray = new float[nsample];
107  float *ct = new float[nsample];
108  long size=0;
109
110  float mean=0.,sd=0.;
111  for(int i=0;i<newsize;i++) mean+=newimage[i];
112  mean /= float(newsize);
113  for(int i=0;i<newsize;i++) sd+=(newimage[i]-mean)*(newimage[i]-mean);
114  sd /= float(newsize);
115 
116
117  if(newsize>nsample){
118    int step = (newsize / nsample) + 1;
119    for(int i=0;i<newsize;i++){
120      if((i%step)==0){
121        smallarray[size] = newimage[i];
122        ct[size]=(float)size+1.;
123        size++;
124      }
125    }
126  }
127  else{
128    for(int i=0;i<newsize;i++){
129      smallarray[i] = newimage[i];
130      ct[i] = float(i+1);
131    }
132    size=newsize;
133  }
134
135  std::sort(smallarray,smallarray+size);
136 
137  /* fit a linear slope to the centre of the cumulative distribution */
138  long midpt = size/2;
139  long imin = midpt - width;
140  float slope,intercept,errSlope,errIntercept,r;
141  if(size<2*width)
142    linear_regression(size,ct,smallarray,0,size-1,slope,errSlope,
143                      intercept,errIntercept,r);
144  else linear_regression(size,ct,smallarray,imin,imin+2*width,slope,errSlope,
145                    intercept,errIntercept,r);
146
147  z1 = smallarray[midpt] + (slope/contrast)*(float)(1-midpt);
148  z2 = smallarray[midpt] + (slope/contrast)*(float)(nsample-midpt);
149
150  if(z1==z2){
151 
152    if(z1!=0) z2 = z1 * 1.05;
153    else z2 = z1+0.01;
154
155  }
156
157  delete [] newimage;
158  delete [] smallarray;
159  delete [] ct;
160
161           
162}
163template void zscale<float>(long imagesize, float *image, float &z1, float &z2, float blankVal);
164template void zscale<double>(long imagesize, double *image, double &z1, double &z2, double blankVal);
165
166
Note: See TracBrowser for help on using the repository browser.