05-16-2016 09:02 AM
Use the Rescale tool to rescale the 12 bit data to 8 bit. ERDAS IMAGINE will interpret the 12 bit data as 16 bit.
ERDAS IMAGINE Raster tab > Resolution group > Radiometric menu > Rescale.
05-17-2016 12:59 AM - edited 05-17-2016 05:13 AM
But the original question was - "what is the best way" and for that I am not sure is there an asnwer for that. I personally like a lot for standard deviation based rescale but it could be that for some datasets traditional min-max is better. I guess suitable method depends on case - so when visual side is main target then standard deviation is good - when pixel values matter then some other more linear (like min-max) method is good.
In generally I would like to see more discussion in this forum about why some method was chosen and how good the results are rather than just finding correct buttons. Correct buttons (like this one) can often found on software help but finding out best practises is much harder. And for that sharing experiences matters much.
I really miss a strong lively discussion about Erdas Imagine usage and I hope this new forum will do that. Sofware help and support services are good for certain things but true user experiences are extremely valuable for other users. So that we all do not have to overcome same obstacles by our own.
06-24-2016 11:35 AM
That's an excellent point. The new Community forums are in their infancy and I'm sure we'll get back to the old level of lively debate at some stage, but it's going to take a little bit of time.
On the stretch issue, it's like you say - the question is a "how long is a piece of string?" debate. The answer is going to depend on a multitude of factors including the type of data you're stretching, whether you want a standardised stretch so multi-date results can be comparable, do you want to preserve a DN value for value-based NoData, do you want to preserve relative band weighting (preserve color), the application you're intending the results for, etc., etc.
The first thing to remember is that taking data with a dynamic range that's larger than 8-bit and "stretching" it to an 8-bit range is actually a compression, not a stretch. In other words it's a lossy compression technique intended to reduce the file size of your imagery (and perhaps to make it usable in applications which are unable to cater to greater bit depths). You are discarding a considerable amount of information by taking data with a 12-bit dynamic range down to 8-bit. As such you really have to assume that the goal is "visually appealing" data rather than data that can still be quantitatively analysed.
If the goal is file size reduction then the first question to ask is whether you really need to stretch to 8-bit? The traditional thinking is that data stored in a 16-bit integer is going to be twice the size of an 8-bit equivalent image. But if you are using Run Length Encoding (PackBits), or other lossless compression techniques, that may not be true. Data with a dynamic range of 11 or 12 bits may well only be 25 - 50% larger than an 8-bit equivalent. So before you jump into lossy stretching to 8-bit check your Preferences to see what compression techniques you are applying to IMG, TIFF, JP2, etc file creation. It may be that you simply need to optimise the storage format, rather than stretching down to 8-bit.
Similarly, if your goal is "visually appealing" with a smaller file size, you might want to consider converting the data to a lossy compressed format, but still stored in a 16-bit data type. Converting to ECW or JPEG 2000 may significantly reduce the file size while maintaining a dynamic range much closer to the original (albeit with changed DN values - but you're going to end up with changed DN values anyway if you're stretching to 8-bit).
In other words, consider your goals before jumping straight to an 8-bit stretch. It may not be necessary to do so.
But if you really do want to convert to an 8-bit data range, you've got lots of other options to consider.
A Min - Max style stretch is going to preserve information in the tails of the histogram. As such, you're going to be preserving the overall range of the original data much more effectively. This is important if you are interested in features that exist in those extremes of the histogram. Human construction is generally up at the top end of the brightness range, while water features are at the bottom end, and a myriad of information can be hidden in the shadows.
But, you preserve the extremes at the expense of over-compressing the majority of the data. Because you are linearly pulling in a data range of, say, 5 - 2040, to an output range of 0 - 255, the bulk of the original histogram in the middle gets squashed into a much smaller number of bins. In other words, you lose much more contrast in the majority of the image.
So, other parameters beside Min and Max can be used, or you could consider non-linear stretches (such as Gaussian). A regularly used alternative option for linear stretching are Standard Deviations (SD). By taking a range such as +/- 3 Standard Deviations around the mean and linearly stretching that range across the output 0 - 255 8-bit range you will retain more contrast for the majority of the image. However all DNs that were outside the SD range will be mapped to 0 or 255, i.e. you lose all contrast in the brightest and darkest areas of the original image.
A SD stretch also suffers from being equally distributed around the mean. So if your input histograms have significant skew you can disproportionately lose information in the bright or dark end of the data range. At it's most extreme you can even end up with one of the SD points being outside of the original input data range! Uncorrected this would mean that you are wasting (not using) some of the DN values in your already limited 0 - 255 8-bit output data range.
A very commonly used alternative is a Percentage-based linear stretch. For example, find the DN value corresponding to the histogram point where 2.5% of the darkest image (band) pixels are excluded and where 1% of the brightest pixels are excluded and stretch across that range. This has the advantage of not being adversely affected by skewed histograms and can, usually, help preserve relative color balance band to band.
However all these approaches are generally applied on a band-independent basis and so, to a lesser or greater degree, can cause "color" shifts in the output imagery. For example, in the input image, the "red" band might have a mean that's much higher than the mean of the "green" and the green is higher than the "blue". If you then apply a band-independent SD stretch, you will effectively normalise the means and thereby introduce a color shift in the data.
The solution to this is to apply band-dependant stretches, i.e. ones that apply corrections which takes into account the distribution of all bands, not each band individually. A simple approach is, after determining your initial stretch points (using SD, Min-Max, Percentage, etc) you then take the min of mins and max of maxs and use those stretch points on all bands. For example, you might have determined that the "red" band stretch points, based on input Min and Max histogram values, are 50 and 2000, the "green" are 25 and 1800 and the "blue" are 60 and 2010. Based on these band-independent stretch values, you might use band-dependant values of 25 to 2010 to stretch all three bands.
The advantage, as already mentioned, is to preserve relative histogram positioning (and thereby not introduce color shifts). The main disadvantage is that you may end up with unused DN values in your output 8-bit data range. In the above example, the Minimum input "red" value is 50 (and max is 2000), but we stretched based on a range of 25 to 2010, so in the output 8-bit image there may be no pixels with DN values of 0, 1, 2, or 3. But that's the cost of trying to preserve color. It'll happen less frequently if you derive your low and high points using Percentage or other techniques.
You also have to be careful how many bands you apply this technique to. It's great for display purposes where it's generally dealing with three bands only. The maximum I would use it with is four bands. More than that and the min of mins and max of maxs can start to become extreme with respect to any given individual band and thereby accentuate the problem described above.
Which bring us on the more modern approaches to stretching data. The Softcopy Image Processing Standard (SIPS) provides some interesting options, such as the ability to derive (band-dependant) Dark and Bright Points in an image histogram, as well as sensor-specific Tonal Transfer Curves (TTC). Many of these options are now available with the ERDAS IMAGINE 2016 Spatial Modeler.
So - that'll hopefully get the ball rolling on peoples experiences with different stretch techniques. How long's your piece of string?
06-27-2016 02:36 PM
I had a customer who wanted to take their 12 bit NTF imagery and convert it to a 8 bit JP2 format. Attached is the spatial model that was created. It may not answer the question what is the "best way", but thought I would share it.
This spatial model reads the multiband NTF imagery (or any file type you specify) and outputs a min-max stretched 3-band image into your JP2 format (or any other format that you specify). You can either specify as 7:7, 5:5, 3:3 for band 7, band 5 and band 3 or simply just enter/type “7,5,3” for the desired band inputs of bands 7, band 5 and band 3.
Hope this helps.
06-28-2016 01:03 PM
Here's another thought on "Best Practices" when stretching >8bit data to an 8-bit range:
What range should you actually stretch your "active" data across? Sounds obvious, right? You stretch it 0 to 255 to maximise usage of the 8-bit data range. But should you?
Consider Band 1 of my 16-bit Integer data set. The data ranges from a minimum of 282 to a maximum of 2047. Mean is 718 and SD is 208. Slight skew of the histogram to the left.
But this is an ortho image, so there are actually lots of pixels around the edges with a DN of 0, which has been used as the Value Based NoData for this dataset and so those pixels were ignored in the statistics calculation (or I could have specified for DN 0 to be ignored in the statistics calculation).
So let's consider a simple Min - Max linear data stretch. Take the range 282 to 2047 and map it across the 0 - 255 range such that 282 becomes 0 and 2047 becomes 255? Definitely not since that would take a lot of valid image pixels that were formerly DN value 282 and throw them in with the pool of NoData pixels. So in this instance I would have to be careful to map my data between 1 and 255, leaving all those NoData pixels unmodified.
What if I used a 2 SD stretch (or some other method to come up with a "low" DN value and a "high" DN value that are intended to be mapped linearly to the "full" output 8-bit range). For my data 2SD is 416. Around the Mean of 718 this means a low point of 302 and a high point of 1134 (approximately) as my range to stretch to 8-bit. Should I map 302 to the output value of 1? I would argue not since I have lots of input pixels which have DNs between 282 and 301 (as well as all those vale-based 0 NoData pixels). Depending on exactly how I implement my Stretch model those DNs are probably going to get thrown into the DN 0 / NoData hopper again. I have to be very careful that all pixels >= 282 and <= 302 are mapped to 1 and then the remainder up to 2047 are linearly distributed between 2 and 255.
Or there's also an argument that 0 / NoData should remain 0, pixels >= 282 and <302 are mapped to 1, and then 302 and upwards are mapped starting at an output value of 2.
Similar decisions need to be made at the top end of the input / output range as well, but it's generally not as critical as getting real image pixels at the bottom end accidentally thrown into the NoData hopper.
What do you think the best practice is?
06-29-2016 01:36 AM - edited 06-29-2016 01:52 AM
Good stuff Ian - just what I have been missing over the years on Erdas Imagine forums. In the world of raster each operation you do have always pros and cons. In vector GIS there is often an option to undo the trick you did for the data and return to original state but in the world of raster undo is not possible normally. If you change pixels to some other value there is no way back and you have to live with it.
So best practise in all cases depends on usecase and data you have. Always think before you do anything and as a backup keep raw data or processing steps stored somewhere if you afterwards notice that something was done in wrong way.
One constant challenge in this is Imagine help typically tells what to do but it does not typically tell anything about best practices or why you do something. So help we have in Imagine is pretty "single eyed" and expanding it would make users life easier. ESRI is here pretty good as they have screenshots or simple sketchs about what for example dissolve means. Improving Imagine help on that direction would be a great step. So from Imagine software help you can find pretty easily what to do but when going to question why to do software help is not that good source of information. To get answer to that why question sharing opinions and discussing here is very important. OK I agree that explaining simple vector operations as a sketch is much easier than explaining raster operations but my point is that Imagine help requires improvement. Software help is not just an obligatory thing to have but it can be a valuable source of information. For example having Imagine help on the web is a great step ahead. Nowdays it is so much easier to link help to someone else as you just can deliver simple link that works all over the internet. That is a good example for a great improvement step you have recently made for Erdas
12-15-2016 05:46 AM
To add to this discusison, I've created an article in the Spatial Recipes section discussing how you might handle NoData in data-stretch cases (and in general). Please see "Handling NoData in Spatial Modeler"