Subscribe to this thread
Home - General / All posts - CIR Imagery in M9
drtees45 post(s)
#01-Feb-19 17:32

At times, it is important for my work to use color infrared imagery (CIR) to detect possible wetlands. Four-band NAIP imagery provides an easy way to create CIR images. When dedicated CIR images are not readily available, I will turn to NAIP to create what I need. The conversion is relatively straight-forward in QGIS. The four bands are: Red - Band 1; Green - Band 2; Blue - Band 3; and Alpha - Band 4. Normal color imagery does not use Band 4 (Q3 NAIP (no adjustment).jpg and M9 NAIP (no adjustment).jpg). Creating CIR involves changing Red to Band 4; Green to Band 1, and Blue to Band 2. QGIS does not appear to have any settings for adjusting Alpha, but typically it is set to Band 2 (Q3 NAIP (CIR adjustment).jpg). The resulting image is generally identical to the color balance seen in dedicated CIR imagery.

M9 Syle setting names the Bands 0 through 3. Red is Band 2; Blue is Band 1; Green is Band 0; and Alpha is Band 3. Setting up a convention between USDA's Band identity with M9's suggests that M9 Band 0 is USDA Band 3; M9 Band 1 is USDA Band 2; M9 Band 2 is USDA Band 1; and M9 Band 3 is USDA Band 4. By this logic, creating the same CIR image in M9 should involve setting Red to Band 3; Green to Band 2, and Blue to Band 1. Based on other information available on the internet, it appears that Alpha should also be changed to Band 1. The result is illustrated in M9 NAIP (CIR adjustment).jpg. Adjusting the Alpha to any other Band will not produce the same image that QGIS creates. I am at a loss to understand why I cannot create the same CIR image in M9 as I can in QGIS (yes, I did try changing the ranges in M9 to match those in QGIS with no improvements in the final image). Am I missing something here?

I am running Manifold Build 9.0.168.8 and QGIS 3.02. I have 16 GB of RAM and an Nvidia Quatro K620 GPU.

Attachments:
M9 4-band NAIP (CIR adjustment).JPG
M9 4-band NAIP (no adjustment).JPG
Q3 4-band NAIP (CIR adjustment).JPG
Q3 4-band NAIP (no adjustment).JPG

Dimitri


5,249 post(s)
#01-Feb-19 18:19

It's hard to guess without a sample of the original data. Do you have a link to that? Do you have a link to a discussion of what NAIP is? Could be something as simple as getting BGR and RGB backward. :-)

Alpha is transparency. It could be I do not understand the original image data you are using, but if you have an RGBa image shot in visible light frequencies, there is no infra-red. Controlling the Red channel using information that is supposed to indicate pixel transparency does not add infrared frequency information. It might give a reddish look, the way false color using infrared frequencies is often set up to do, but that is not the same as sensing infra-red.

The intent, by the way, should not be to match to something Q does, it should be to match what is correct. What is the correct objective based on what you are doing, as a matter of science? Do you have examples of discussion from USDA or other sources that you are trying to match? To that end, the key questions are:

1. What is the original data you start with? What are the bands in that data, what are the data types of the numbers in those bands, and what are those bands supposed to represent? Visual frequencies? Other frequencies that have been sensed?

2. What is the result you want? You should be able to say clearly that if there are bands A, J, P, X in the source data those are to be remapped to output channels R, G, B, A in the image that is produced.

If you can answer the above two sets of questions, doing what you want in 9 will be easy and straightforward. If you can't answer them, then you can't know what to do with the controls 9 provides. Note that answering the above two sets of questions has nothing to do with Q. Saying, "this is what I do in Q" isn't really answering the questions.

drtees45 post(s)
#01-Feb-19 22:38

Four-band NAIP imagery can be downloaded for free from the USGS Earth Explorer website (earthexplorer.usgs.gov). I have attached a white paper on four-band imagery to this reply. The NAIP image I used in my example is likely too large to post to the forum.

Four-band NAIP is an image where Bands 1 through 3 correspond to red, green, and blue. The values associated with each band range from 0 to 255. Band 4 is near infrared and also ranges from 0 to 255. To create a CIR image, one need only assign Band 4 to red, Band 1 to green, and Band 2 to blue. This is essentially what I do in QGIS and the results are generally analogous to dedicated CIR imagery I have received from other sources.

When the bands in the NAIP are re-assigned, areas that could be wetlands tend to stand out. Red color now indicates a certain degree of plant growth vigor. Darker reds are slower-growing plants, Brownish looking areas could be where plants are stressed. Bare earth appears white or blue. Water appears black.

M9 identified the Bands as 0, 1, 2, and 3. Band 0 was associated with red, band 1 was associated wtih green, and band 2 was associated with blue. I made the assumption that band 3 might be the same as band 4 in the documentation.

Attachments:
fourband_infosheet_2012.pdf

Dimitri


5,249 post(s)
#03-Feb-19 15:55

Unfortunately, the USDA info sheet (the cited PDF) gets it wrong. That can lead to serious confusion. The info sheet says:

The user must have software which will recognize all four bands. The software will usually have some type of interface where the band assignments can be changed. If an image is created with the red (wavelength) band as band 1, green as band 2, blue as band 3, and near infrared as band 4, a natural color display on the computer screen would be set up with the red (display) channel as band 1 (red), green channel as band 2 (green), and blue channel as band 3 (blue).

Well, sure. The problem with the above is that NAIP does not provide four band imagery in the channel order described by USDA. USDA makes the common mistake of thinking "RGB" means literally the channel order, so the go into the song and dance about

If an image is created with the red (wavelength) band as band 1, green as band 2, blue as band 3, and near infrared as band 4,

But that's not how NAIP imagery is created. NAIP channel ordering is BGR. Red isn't the first channel in NAIP imagery, Red is the third channel. The first channel, Channel 0 in zero-based nomenclature, is Blue, the second channel, Channel 1, is Green, the third channel, Channel 2 is Red, and the last channel, Channel 3, is near-Infrared.

That is such misleading info from USDA that I've suggested an Example topic be added specifically showing how to create CIR from NAIP.

tjhb

8,516 post(s)
#04-Feb-19 05:42

Manifold decided to swallow the red pill on this, while everyone else has gone blue.

If treating BGR as if it were RGB is good enough for Photoshop, why is it not good enough for Manifold?

At worst, the ordinary approach is only one extra layer of indirection.

(And is it necessary only because Motorola v Intel? Regardless...)

Manifold has made a rod for its own back here. Explanation will be required in perpetuity.

Please refrain from blaming users. It was your choice to be literally right, about an issue that matters to not one single soul outside the company. You'll need to keep dealing with it.

Dimitri


5,249 post(s)
#04-Feb-19 08:12

Pleaserefrain from blaming users.

Nobody is blaming users. Referring inaccurately to the order of channels in data causes errors when people work with software that can rearrange channel to output assignments using multiband data, and it also causes errors in programming, SQL, and so on. Avoiding errors matters to everyone. Referring inaccurately to the order of channels in data also contributes to the mountain of totally wrong advice on Internet.

The USDA paper is a good example of that: it is simply wrong when it says that in NAIP four band data the first band is red, the second green and the third blue. Why does USDA make that error? Most likely because somebody looked at the "RGB" nickname and cluelessly assumed that the data channels in the data also appeared in R, G, B order.

That is an error, a blunder similar to ones made all the time when beginners hear "Latitude / Longitude" so they assume that the latitude number comes first in coordinate pairs.

There's nothing wrong with saying "Hey, it's OK to use the nickname 'RGB' to refer to images that use three color outputs. Just don't assume that the nickname literally specifies the data order, which might be RGBA, ARBG, BGR, ABGR, BGRA, etc." That's what Manifold does.

---

If you look at running text in the Manifold documentation, RGB images are simply called RGB images, just like they are everywhere. Nobody's pushing uphill against the accepted name. If you look at how Manifold works, it takes what somebody calls an "RGB" .tif and it correctly assigns the right channels to red, green and blue outputs, even though the actual data channel ordering is BGR. Works great. There's none of this "oh... you called it an RGB? Are you sure you don't mean BGR? well then I'll do it backwards..."

When you have a system that works with specific channel ordering in very many different formats and which allows users to specify which output will be driven by which channel, you cannot escape referring to the actual channel ordering. You can't just use the term "RGB" all the time, because the channel ordering is not always RGB. In fact, it's usually BGR. Referring to the actual channel ordering using a term like BGR is more compact than something like "channel ordering where data acquired in blue wavelengths is in the first band, data acquired....".

Photoshop and very many other consumer graphics editors don't need to get into any of that because they don't provide facilities to pick and choose and re-assign channels from manychannel formats into four outputs.

Photoshop users don't actually work with the specific data channels within a wide variety of different formats. Instead, once you import an image into Photoshop the "channels" are identified as Red, Green and Blue. That's because Photoshop decides how to assign data channels from the original file to R, G and B outputs and thereafter doesn't use any naming or channel ordering as it was in the original file. Instead, they refer only to the outputs by the color name. In Photoshop, every three band image is an "RGB" image because that is what Photoshop names the channels it uses.

Photoshop doesn't allow channel reassignments like Manifold does. There's none of this "first channel," "second channel," and so on stuff, assigned as you see fit to some desired color output. That's because Photoshop isn't either a GIS or a remote sensing image manipulation package. If you want to reassign channels to outputs, it is a much harder process in Photoshop than in Manifold.

Here is a video (watch it expanded to full screen, so you can read the small text in the video) that shows how it is done in Photoshop, using a four band NAIP .tif: https://vimeo.com/188925635

Like it or not, your multiband .tif image gets imported into what Photoshop forever more will call Red, Green, Blue, and Alpha channels. If you don't like what Photoshop did by default, you have only one recourse, a manual process that is shown in that video: you first must split your image into four grayscale images, each one of which is named with "Red," "Green," "Blue," or "Alpha" as part of the name by the splitting tool. You then use another tool to create a new RGB image that takes data for that image's Red, Blue, and Green "channels" from the various grayscale ones.

That can lead to a lot of confusion. For example, suppose the TIF you imported into Photoshop was one of the rare ones that actually uses RGB ordering for data channels and not BGR ordering. Photoshop will import it wrong, because the channel that Photoshop imports into what Photoshop calls the "Blue" channel will actually be Red data. You can fix that by splitting the image into "Red", "Blue" and "Green" grayscale images and then creating a new Photoshop RGB image where you take the "Blue" grayscale and put that into the image's "Red" channel.

Photoshop also misuses the name "Alpha" when dealing with four-band data like NAIP. "Alpha" universally means transparency, but not in Photoshop in the case of NAIP.

Fire up your copy of Photoshop and import into it a four band NAIP. By default, the Alpha channel is turned off in Photoshop's channels dialog. That's a strange thing to do, since usually Alpha is an important part of per-pixel transparency. But in this case, it's turned off.

You can see what happens in the video, where accidentally the commentator turns on the Alpha channel for a moment. What happens? The image goes red. If you try it yourself in Photoshop on your own desktop, you'll see that when Photoshop imports the data from the fourth NAIP channel it treats it as some sort of Red override. If you turn on just Blue and Alpha you get red colors. If the channel is what Photoshop calls it, Alpha, but it is treated as a color channel and not transparency, well that's just plain wrong. If you think it is OK that Photoshop takes a name like "Alpha" that universally is used to mean "transparency" and instead uses it as a Color output, well, I respectfully disagree. I think that's confusing, especially for beginners. If "Alpha" means transparency, use it for that.

The erroneous USDA PDF is not unique, by the way. It's amazing how much disinformation there is out there on the web. One reason I chose that video, for example, is because it was created by a University Geography Deparment and yet it provides bad info: He says to create an "infrared image" by using the fourth, Alpha Photoshop channel as the new Red channel, but to keep using the Green grayscale for the Green channel and the Blue grayscale for the Blue channel.

But that's wrong if you look at what the traditional Color Infrared (CIR) assignments are, where the near-Infrared channel drives the Red output, the Red channel drives the Green output, and the Green channel drives the Blue output.

Personally, I think the new topic on creating CIR from NAIP says it better: there are various assignments that can use the near-Infrared band in four band NAIP imagery to create a false color image, but the traditional assignment used to create what are called Color Infrared (CIR) images is the given one, which happens to match the result way back in the day when Kodak CIR film was used to photograph in the same bands.

tjhb

8,516 post(s)
#05-Feb-19 01:44

... By default, the Alpha channel is turned off in Photoshop's channels dialog. That's a strange thing to do, since usually Alpha is an important part of per-pixel transparency. But in this case, it's turned off.

You can see what happens in the video, where accidentally the commentator turns on the Alpha channel for a moment. What happens? The image goes red. If you try it yourself in Photoshop on your own desktop, you'll see that when Photoshop imports the data from the fourth NAIP channel it treats it as some sort of Red override. If you turn on just Blue and Alpha you get red colors. If the channel is what Photoshop calls it, Alpha, but it is treated as a color channel and not transparency, well that's just plain wrong. If you think it is OK that Photoshop takes a name like "Alpha" that universally is used to mean "transparency" and instead uses it as a Color output, well, ...

I think this is a misunderstanding.

If you click on the "eye" for a Photoshop alpha channel to make it visible, what you see is a rubylith overlay. The name and the colour derive from the days when masking was done by overlaying a physical sheet of coloured acetate on an image.

You can change the rubylith colour, its opacity/transparency, and whether it masks or shows, by double clicking on the right side of its channel bar.

If you single-click on any channel (not on the eye), then you see its mask in black and white, which is also shown in the main image. Then you can paint on it to adjust mask values.

Also: Ctrl-click on a mask to load its mask values as a (graduated) selection. Ctrl-Shift-click to add to the current selection. And so on.

BTW Photoshop can have many alpha channels (even hundreds), though when there is more than one they are usually not called alpha but by a specific name (double-click the name to rename a channel). They are directly interchangeable with selections and layer masks (and of course with RGB, CMYK, HSB or Lab channels). A place to store and manipulate data.

Dimitri


5,249 post(s)
#05-Feb-19 05:29

Interesting. Thanks for the info! I don't use Photoshop that much and Alpha channels less, so this is new to me. I agree their use of Alpha to store selections, for more than just alpha compositing, is a very powerful tool. But it is a dual system running in parallel to how they handle transparency in other cases.

What is interesting is that Photoshop imports an NAIP tiff with four channels differently than other tiffs with alpha, and it imports the NAIP tiff differently than other formats with alpha transparency.

Here's an interesting experiment: launch Manifold and import from the clipart collection the missile_PNG18a.png image (I've attached it below as well). This imports as an RGBa image with four channels, including an alpha transparency channel.

Import the same image into Photoshop and you get an image that retains transparency (as used in the Gaussian shadow), but it has only three channels, R,G,B, with means other than a Photoshop Alpha channel used to handle transparency. Import it into GIMP and the channels module shows an alpha channel, like Manifold.

Back in Manifold, export that image to TIFF, called missile.tiff. Now, re-import into Manifold. The tiff retains transparency and the resulting image is still an RGBa, with an alpha channel. Same with GIMP.

Import into Photoshop and you also get an image that retains transparency, but again as an RGB with transparency encoded not using a Photoshop Alpha channel.

What's puzzling to me is why Photoshop imports the TIFF format NAIP with an explicit Alpha channel but other four band TIFFS without an explicit Alpha. I'll pour through the docs today and see what's up with that. I suspect it has to do with whether a TIF tag declares an explicit alpha (Manifold's TIFF output declares an associated alpha, the NAIP TIFF does not). In that case it would make sense for Photoshop to bring it in as the generic layer they use for storing pixel data that can mean selections, or masks, or other stuff other than Red, Green, and Blue.

From a UI perspective, I don't like the dual system in Photoshop for encoding transparency and using the "alpha" name: sometimes it is an alpha channel meaning transparency and sometimes not.

I respectfully also point out that the error in my commentary on Alpha doesn't change the key point, that Photoshop maps data channels into what it names Red, Green and Blue channels without giving users access to the order of the channels within the original data, so there's no need for them to ever refer to what the order is in the data using combinations like ARGB, BGRA, BGR, RGB, etc.

Attachments:
missile_PNG18a.png

tjhb

8,516 post(s)
#01-Feb-19 22:48

The source is a four-channel image whose channels are RGB + IR (near infrared).

By default, Manifold interprets a four-channel image as RGB + Alpha (transparency), which is very reasonable since it is the most common encoding for four channels.

To digest RGB + IR, we need to change the defaults.

(a) To display just the RGB channels, ignoring IR, do this:

Note that this display mode is built in. Just click the Assign Channels button (the four squares above the channel list) and select the BGR preset:

(b) To display the image as standard CIR (mapping IR -> red, R -> green, G -> blue, and ignoring B), do this:

(It would possibly be good if CIR or BGR+IR could be added as a preset too.)

Attachments:
CIR.png
preset.png
RGB.png

tjhb

8,516 post(s)
#01-Feb-19 23:05

Editing timed out while I was adding preset.png inline. It goes here:

Note that this display mode is built in. Just click the Assign Channels button (the four squares above the channel list) and select the BGR preset:

tjhb

8,516 post(s)
#01-Feb-19 23:09

Why does Manifold use call the standard channel order "BGR" rather than "RGB"? Apparently because that is the way things are actually encoded. In standard RGB imagery, the blue channel is first, green is second, red is third.

Overly literal perhaps, and something to get used to, but correct.

Dimitri


5,249 post(s)
#02-Feb-19 06:02

Apparently because that is the way things are actually encoded.

Ah, no need for "apparently".... there's a topic explaining all that in the user manual :-) See the discussion titled "Channels and Outputs" near the end of the Style: Images topic.

I'd just like to point out that wasting time by going astray on such totally elementary matters is what happens when people fail to RTFM. Controls in the Style panel for images are very easy and efficient to use once you learn them. Poke at them without learning and it's a source of easily-avoided frustration.

For goodness sake, if anybody is going to fool around with this stuff, save time and avoid frustration by reading the Style: Images topic, and also take the time to review the many step-by-step, lavishly illustrated examples recommended in the See Also section of that topic.

By the way, if drtees provides a link to the image he used, I'd be happy to download it from the Earth Explorer site and do a video showing how quick and easy it is to use the Style panel controls to create a CIR version.

drtees45 post(s)
#04-Feb-19 17:28

I did not provide a link to Earth Explorer for a few flimsy reasons. The first is that you need to set up an account on the USGS website in order to download anything. Providing a link would not immediately allow you to download anything. The second flimsy reason is that the USGS Bulk Download App system was disfunctional last week, likely due to the government shut down. Earth Explorer does allow for direct downloads of selected images. My experience has been that directly downloading the image can often result in a corrupted zip or tgz compressed file. Sometimes the only version of an image available for direct download is a "medium" resolution version, likely to speed up foreground transfers.

Dimitri's lengthy response above indicated to me that the designers of QGIS knew of the difference between the term "RGB" and the way the files are actually coded. I suspect that their assignment of band monikers reflects the difference and that my attempt to determine analog correlations between the band designations (as suggested by USDA) and M9's designations was doomed to failure from the start.

I followed the instructions provided by tjhb and got an image very similar to the one in the M9 manual. It is still not an accurate representation of CIR. The red color in the M9 CIR lacks the subtle intensity gradients that would make it useful for me. I have attached two more images: one created by QGIS and zoomed in and the second created by M9 using the manual's guidance and also zoomed in. It clearly shows that the intensity of the red color tends to wash out important visual information. The NAIP program may be incorrect in their description of the different color bands, but the argument is moot if using the correct nomenclature for the bands still fails to produce the desired image.

Attachments:
M9 4-band NAIP zoomed (CIR adjustment).JPG
Q3 4-band NAIP zoomed (CIR adjustment).JPG

Dimitri


5,249 post(s)
#04-Feb-19 18:47

Dimitri's lengthy response above indicated to me that the designers of QGIS knew of the difference between the term "RGB" and the way the files are actually coded.

Sure, but so does Manifold. Import what is casually described as an "RGB" image into Manifold and, like magic, the correct bands are indeed used for R, G and B. That's neither here nor there, which is why my discussion didn't mention Q. I discussed Manifold, and Photoshop.

Your initial problem assigning channels, I would guess, came from a) unfamiliarity with Manifold's controls and b) inaccurate advice from the USDA pdf. If you assign channels like the USDA says, it comes out wrong, because the USDA uses incorrect channel order for what is actually in NAIP four band imagery. See the discussion in the user manual topic on creating CIR from NAIP, and also in the video that was published today.

The red color in the M9 CIR lacks the subtle intensity gradients that would make it useful for me. I have attached two more images: one created by QGIS and zoomed in and the second created by M9 using the manual's guidance and also zoomed in.

Based on the images you provided (thanks!) the QGIS display apparently has each channel constrained to the specific range of values that occur in that channel. The Manifold display has each channel assigned to a range of values from 0 to 255. There are very good reasons for wanting to do it either way as a default. For example, if you always look at the 0 to 255 range you are using a standard normalization for every image. If every time you alter every channel to only the specific range of values that occur within that channel within that particular image, each image is normalized only to itself. Manifold uses the full range 0 to 255 as the default, while Q uses the range within that channel within that image as the default.

You can change the image in Manifold easily enough to use the range that occur within that channel within the image. To do that, you apply Full Range as discussed in the Style: Autocontrasttopic: select the channels, right click into any of the three 0 to 255 ranges, and choose Full Range from the context menu, then press update style.

Do that (I've just tried) and it changes, but not as much as it should. It is also puzzling that Manifold is showing the water bodies as bright red, high reflectance, while Q is showing them as black.

Just for the heck of it, I tried an experiment and created a data source for a four-band NAIP .tif using GDAL. GDAL Created two images, an RGB natural color image and then a separate grayscale image for "Band4", that is the infrared. Open that and it has black water, etc. I think what is going on is that the .tif importer is importing the four bands directly from the .tif and there is something different about the fourth band that the importer isn't handling correctly. All the band assignments are fine, but the initial import of the data is strange. There are many possibilities for the disparity, something to take a look at, but I suspect the encoding for the fourth band is different from the first three. It looks like encoding for the IR band is somehow inverted.

Hurray! Just tried it... if you extract band 4 as a channel, apply a transform expression of 255 - [Tile], you get exactly what GDAL gets. Well, that was easy...

I'll take a look at it tomorrow in more detail I bet that if I take the images imported into Manifold via GDAL, the image comes together identically as seen in Q (Q uses GDAL for rasters).

Dimitri


5,249 post(s)
#04-Feb-19 19:11

Aha, that was indeed it. Either the IR band is not coded the same as the others (inverted coding) or for some reason Manifold is inverting it when reading the TIF. If you take band four and apply 255 - [the tile value] to fill the tile, you get the correct result. Use that band in the image, apply full range and it comes out identical to the way you see it in Q. It's late now so I'll write up a note in case it is Manifold's bug, a suggestion that if it isn't Manifold auto-adapts, and if I have time the procedure for using the band as is.

Examples:

Attachments:
cir01.jpg
cir02.jpg

tjhb

8,516 post(s)
#04-Feb-19 19:31

Brilliant diagnosis Dimitri!

I was about to sit down and try to diagnose the radioactive ponds in drtees' imagery but you have solved it straight away.

I'll check local RGB-IR imagery again to make sure it is sane.

P.s an easyish way to check whether this is an encoding issue or a parsing bug would be to use SQL VectorValues() to shuffle the channels around.

drtees45 post(s)
#04-Feb-19 21:28

Thank you for figuring out what is going on. I would say that, in my defense, it is immaterial whether the NAIP is correctly naming the bands. Their recipe suggests using their "incorrect" names and altering which channels are associated with which bands in order to create the CIR. Q apes their incorrect nomenclature. I made a matrix table to determine in an unmodified NAIP image which bands, as identified in Q, are associated with which bands, as identified by M9. If the NAIP naming convention is wrong, then my matrix table would be equally wrong. This should not matter at all since the name of the band is immaterial to the information the band is portraying. I should still get the answer in the back of the book.

At this point, I must confess a profound lack of understanding of the process you used to get the images above. The M9 manual is still quite rough (difficult to find specific information), which makes the RTFM claim a bit harsh. Knowing the answer is in there is one thing; being able to find it is another. I have always found finding the required information in the M8 documentation to be straight-forward. To make a possibly unfair analogy, finding information in the M9 manual is like the pirate island from "Pirates of the Caribbean:" you can't find it unless you know where it is.

I could not see a way to "extract" Band 4, nor how to apply the transform-tile function as described. The examples in the manual do not match what I am seeing in M9. The expressions under Transform mean very little to me; my days of writing code are long past since Fortran is no longer a viable programming option. SQL is something I wish to learn when I have the time, which I do not at this moment. Did you extract band 4 in M9 or GDAL? How do you invert the tile values?

I realize that I sound as if I need considerable hand-holding. Perhaps I do. On the other hand, a tool as powerful as M9 also needs to be accessible to users who represent the least common denominator. At the moment, I am afraid I am it.

Mike Pelletier


1,558 post(s)
#04-Feb-19 22:17

Your not alone. The solution to this also needs to include the ability to apply whatever massaging is necessary to many other images since with hundreds of these type of images, doing it manually for each one is like shooting zombies :-)

tjhb

8,516 post(s)
#04-Feb-19 22:47

There is more going on here. I don't want to speak prematurely but I am getting some very surprising results. More soon.

Dimitri


5,249 post(s)
#05-Feb-19 06:07

At this point, I must confess a profound lack of understanding of the process you used to get the images above.

Well, sure, since I didn't post the procedure I used. :-) Hence my comment:

It's late now so I'll write up a note in case it is Manifold's bug, a suggestion that if it isn't Manifold auto-adapts, and if I have time the procedure for using the band as is.

There's something strange going on that requires manual intervention. That you can do manual intervention like I did is a good thing, but better to have such things happen automatically.

It's fairly unusual for any GIS project to isolate something like this and do whatever is necessary to adjust in a day or two, but that's something we can reasonably expect from Manifold. I'll try to find the time later today to post the procedure and the expression I used, as it shows a simple approach to such things that may be useful in other settings. Also, that way people who are in a hurry can use it right now.

Dimitri


5,249 post(s)
#05-Feb-19 06:38

it is immaterial whether the NAIP is correctly naming the bands. Their recipe suggests using their "incorrect" names and altering which channels are associated with which bands in order to create the CIR.

No, that's missing the point. There are seveal related notions here. One is the order in which the bands for various wavelengths are encoded in the data. Another is what you choose to call those data bands. A third notion is how you choose to assign those data bands to some particular display output.

The absolutely essential thing you must know, non-negotiable, is the order in which bands are encoded in the data. It doesn't matter what you choose to call those bands. You can call them Tom, Dick and Harry, but if you say "the order of the bands in the data is Dick, Tom, Harry" when in reality the order is "Harry, Dick, Tom" what you said is wrong. It is not a mistake in the names you chose, it is a mistake in the order in which you said they come.

You can refer to the data channels as Channel 1, 2, 3 and 4, or, if you intend to use the data in programming, SQL or other technical settings, you'll use the more technical, zero-based order names of Channel 0, 1, 2 and 3.

Great. So what does that ordering mean? If NAIP says Channel 0 was imaged in Red wavelengths when in reality it was imaged in Blue wavelengths, that's a mistake.

The USDA paper gets sloppy in that respect. Instead of using names like Channel 1 or Channel 2, they refer to channels by color name. That's OK, just like using Tom, Dick and Harry, so long as you tell the truth when you say the order in which they come.

The USDA paper doesn't tell the truth. Instead, they explicitly say that Red comes first, next Green and last Blue. That's simply wrong, and that error cascades through when they then use that wrong ordering to describe the CIR arrangement.

That same error, by the way, is repeated in the .txt metadata that accompanies the NAIP .tif, where it explicitly says: "32-bit pixels, 4 band color(RGBIR) values 0 - 255" Nope. That's not the order in the data. They should have written "32-bit pixels, 4 band color(BGRIR) values 0 - 255".

Now, lucky for us, Manifold does exactly what QGIS does: it reads the TIF, assumes the ordering is BGRa, and assigns channels that way. If you just import the image into Manifold and then do the procedure shown in the manual or the video, it all works effortlessly, and you can do CIR straight away.

I made a matrix table to determine in an unmodified NAIP image which bands, as identified in Q, are associated with which bands, as identified by M9.

This seems to be the wrong approach. It's much simpler than that. If you have an image with four bands, each pixel has four chunks of information in it, the "bands", and those come in the same order for each pixel. You know that one of the chunks has a value sensed in Red wavelengths, one has a value sensed in Green wavelengths, one in Blue wavelengths, and one in IR wavelengths. If you want to rearrange those chunks based on which comes first and which comes next, etc., you have to know what the chunks are that you are rearranging and the order in which they appear in the data.

As it so happen, Manifold imports NAIP tifs with the chunks (channels) assigned to the display output that is the right one to use for the wavelengths in which they were sensed. Manifold does that for the same reason everybody else does that: if you have no specific reason to think otherwise, guessing that the chunks come in Blue, Green, Red order is way more likely correct than guessing they come in some other order. So, Manifold guesses BGR and it turns out in the case of NAIP that's the right guess.

That the NAIP and USDA documentation wrongly tells you they are in different order doesn't matter to how Manifold imports the data, since Manifold isn't reading through all that documentation. It just imports the TIF and applies what is the usual case with almost all TIFs. If anyone is worried after reading the USDA documentation that maybe Manifold got it wrong, it's easy to see in a second from the Style panel what is the correct arrangement, try the ordering NAIP/USDA document and see it is wrong, and then go back to the correct arrangement that Manifold gets by default.

It's generally not a big deal if you don't know what the correct order for channels is in a given data set (people do all sorts of unusual arrangements) because it takes just a click and a menu pick to set up whatever channel arrangement you want. You can try different arrangements and when you get a natural color image - grass being green and not blue, for example - it's pretty obvious that's the right one.

The way to feel confidence and to use the controls to find out when documentation on a particular data set is telling you a fib is to read the basic Style topics, the background topics they recommend, and then to work through the various examples. When examples refer to specific topics, read those That will give you a feeling of ease and confidence with the basic controls.

To alter things, the next level is to work with transforms, which give you more capabilities. After that you can learn to work with the various SQL functions, like the ones I used in the Expressions I built. But that's more advanced stuff which will seem incomprehensible without feeling comfortable in the basics.

drtees45 post(s)
#05-Feb-19 20:08

I believe you may have misinterpreted what I was saying. My reasoning stemmed from logic rather than an empirical knowledge of how the information is coded. QGIS opens a 4-band image and presents it on the screen. M9 opens the same image and presents it on the screen. Both images appear exactly the same. Q designates the "Red" as "Band 1." M9 designates the "Red" as "Channel 2." Regardless of how wrong USDA is on their naming convention, Band 1 in Q must be analogous to Channel 2 in M9 (i.e, if A=X and B=X, then A=B), otherwise both images would not appear the same on the screen.

You have an encyclopedic knowledge of GIS, file formats, and the intricacies of Manifold. I appreciate your knowledge and descriptions, even if your posts and responses are very long! Please understand that I do refer to the Manual, I read the examples, I play with the controls as you suggest. The end result was I got exactly the same type of image presented in the manual for creating CIR images from four band NAIP that prompted my query to the forum. It would have been much more helpful to me if the responses dwelt briefly on the errors in the USDA documention and, by the way, it appears that the coding for infrared channel appears to be inverted and here is a brief example of how to fix it in the interim.

I apologise if my posts are sounding a bit defensive, which they probably are.

Dimitri


5,249 post(s)
#06-Feb-19 08:25

Q designates the "Red" as "Band 1." M9 designates the "Red" as "Channel 2." Regardless of how wrong USDA is on their naming convention, Band 1 in Q must be analogous to Channel 2 in M9

Sigh... that's the wrong way to approach it. It's not a naming thing, it is a connection thing: which pipe feeds what output.

Manifold isn't designating Red as Channel 2. "Red" is the name of the Red LED in your computer monitor, one of the three LEDs (the other two being a Green LED and a Blue LED) that make up a pixel. See the discussion / illustration in the Images and Channels option.

The question is which data channel in the image is used to tell the Red LED how bright it should be, that is which pipe from which gushes a stream of numbers should be plugged into the Red LED. It's not a naming thing, it is like a telephone switchboard in the old days, where if John wants to talk to Dave, the operator plugs a wire between John and Dave. She's not renaming John to "Dave", she's just connecting the two of them so they can talk. If John wants to talk to Dave and the operator connects John to Eric, that's a mistake. There's nothing wrong with any of their names, it's just the pipe connection was made incorrectly.

USDA is not wrong in their naming convention. They're wrong in what they say is the order of the channels. That leads to incorrect pipe connections between perfectly OK names.

Let's say Dave is the Controller of a company, Jane is a bookkeeper in charge of seeing which payments have cleared, and Joe is a programmer who just wants to know what time a bank is open.

Let's say their bank has a VIP department, a Payments department and a Retail department. Each has their own telephone line.

Suppose our switchboard has a set of jacks for the bank on the right hand side of the switchboard. They are labeled so the first jack is the VIP line, the second jack is the Payments line and the third is the Retail line. What they're called doesn't matter (could be "Big shots", "worker bees", and "consumers"), it is what the department does that matters.

Jane may call the bank twice a day, so when she talks to the switchboard she might just say "give me the second line, please".

Suppose one day the cleaning lady accidentally scrubs off the labels on the switchboard. A new operator comes in and doesn't know which of the jacks are for retail, payments or VIP. The operator asks around and one of the other operators says, "Oh, no problem. Retail is the first jack, Payments is the second jack and VIP is the third jack." The operator sticks up some "Retail", "Payments," and "VIP" labels next to each jack. The problem is, because of bad info only the one labeled Payments is correct.

Dave calls and says "put me through to VIP, please" so the operator looks at the labels, sees VIP next to the third jack, and connects Dave to the third jack. Whoops. Dave spends the next 5 minutes on hold listening to dumb music. He's just been connected to the retail channel.

Joe calls and says "give me Retail banking please" and the operator plugs him into the first jack. Also wrong, since that's the VIP channel. Joe is really pleased with the service! It's the first time he's called a bank and they treated him like a big shot.

Jane calls and says "give me the second line, please". That's correct. If she asked for "Payments" that also would have been correct, a lucky accident.

The point of the above is that the naming convention is perfectly OK. It's just been wrongly applied, in the wrong order. What USDA did is similar, when they tell you to use the "first" band to drive the Red LED when really it should be driving the Blue LED.

For things like the order in which data bands appear in the data, what counts is the order and not how you name them, so long as you choose names which unambiguously make it clear what the order is.

So, you could use names like "First," "Second," "Third," "Fourth", or you could use "Un," "Deux," "Trois," "Quatre" or you could use names like "Channel 0," "Channel 1," "Channel 2", "Channel 3" if you like zero-based counting, or even names like "Band 1," "Band 2", "Band 3" and "Band 4".

But it would be really unwise to use names like "Eric," "Jane," "Luis,"and "Rita" because then people would not know which name means what order position. Using names like "Red," "Blue," "Green," and "IR" for positions is also asking for trouble, because there is nothing about a name like "Blue" which says whether you mean the first thing, the second thing, the third thing or the fourth thing.

For that reason, when people talk about data channels, where the order matters to tell what you're getting, they usually use numbers like 1, 2, 3, and 4, or, if they prefer zero-based counting, 0, 1, 2, and 3.

tjhb

8,516 post(s)
#04-Feb-19 23:02

Either the IR band is not coded the same as the others (inverted coding) or for some reason Manifold is inverting it when reading the TIF.

It seems to be the latter--though only for 8 bit per channel images.

For 8 bit per channel images, Manifold systematically inverts the fourth channel (channel 3).

This does not make sense, even when channel 3 is Alpha, since Alpha encodes opacity (visibility), not transparency. A value of 0 ("black") means completely transparent, while the maximum value for the data type ("white") means completely visible (opaque).

(Are there schemes where this is not the case? I don't know.)

When channel 3 is not Alpha, but data--as we declare it to be if we map channel 3 to R, G or B--then it makes even less sense to invert it. No more than it would make sense to invert any of the other channels.

For 16 bit per channel and 32 bit per channel images, Manifold does not invert the fourth channel, which is correct.


Check the attached test project RGBA 1024.mxb.

There are three simple test images, identical except for the data type--at least, they look identical to Photoshop, where they were created. The only difference is in changing the data type using Image > Mode before Save As.

Each image is 1024x1024px, has four channels, and is divided in four quadrants. In each quadrant, three channels have value 0 ("black"), while one channel is fully "white" (i.e. has the maximum value for the data type), in this order:

R G

B A

All images in the prioject initially have standard RGB mapping, i.e. the BGR preset: R channel 2, G channel 1, B channel 0, A=0.

The first thing to notice is that in the 16-bit image, channels 0 and 1 are switched:

B G

R A

I can't think of a good reason for this. That may be a separate issue (or I may be wrong). Putting this to one side...

If we now apply standard CIR mapping to each image--R channel 3, G channel 2, B channel 1, A=0--we get very different results for the 8-bit image, compared with the 16- and 32-bit images. For the 8-bit image, channel 3 is inverted.

Let's make it more simple. If we map channel 3 to any of R, G or B, and all other channels to 0--

--then channel 3 displays correctly for the 16- and 32-bit images...

but is inverted for the 8-bit image...


At first sight this looks like one bug, possibly two.

The same results do apply to real images, not just an artificial test image. I will post more about that soon.

Attachments:
Channel 3 only 16 or 32.png
Channel 3 only 8.png
Channel 3 only.png
Photoshop channels.png
RGBA 1024.mxb

Dimitri


5,249 post(s)
#05-Feb-19 06:12

(Are there schemes where this is not the case? I don't know.)

I don't know for sure either, but I'd bet there are cases like that. To me this smells of some automatic accommodation for some files somewhere, that works perfectly and makes it easy to use those files at the cost of breaking something else. I have zero data for that, just a guess based on intuition.

Dimitri


5,249 post(s)
#05-Feb-19 11:46

This does not make sense, even when channel 3 is Alpha, since Alpha encodes opacity (visibility), not transparency. A value of 0 ("black") means completely transparent, while the maximum value for the data type ("white") means completely visible (opaque).

The above is a good observation that merits discussion. For the sake of this discussion, let's stipulate we call a system where 0 is opaque and 255 fully transparent "alpha transparency" and a system where 0 is fully transparent and the max value for the data type is opaque "alpha opacity."

Back at the dawn of time different formats and different systems used either alpha transparency or alpha opacity. But already people were starting to call it "alpha transparency" whether it was transparency or opacity. Manifold had to pick one of the two ways of doing it, and Manifold picked alpha transparency.

There were three reasons for doing so:

First, people kept referring to it as "transparency" and were making the assumption that less of it meant more opacity, and that more of it meant more transparency. In other words, they believed that a value of 0 should be fully opaque. That was true of both inexpert users and often for expert users as well.

Second, Manifold had means to convert an RGB image into an RGBa image, adding an alpha channel. So what should that value in the alpha channel be for the starting condition? If there is "no" alpha, that logically means zero of something.

Third, starting with a baseline of zero is the same normal for every data type. If you use alpha transparency the baseline for "same results" between RGB and RGBa if you make no alpha modification is simply zero in the alpha channel, always, regardless of data type. In contrast, if you use alpha opacity, the baseline you start with for "no difference" varies by whatever is the data type. That's a different number for each of many variations counting float32, float64, plus 8, 16, 32 and 64 bit variations of integers.

Manifold dataports now automatically convert for whether a format uses alpha transparency or alpha opacity. If the format uses alpha opacity, the numbers are inverted for use within Manifold as alpha transparency. So in the case of fourth channels intended to be used as alpha all that happens correctly on import or export [I'll discuss NAIP below.]

Those are all good reasons to choose alpha transparency as a baseline, but over time alpha opacity has become far more popular. So these days people may casually use the term "alpha transparency" but more often than not the system they are using will code numbers as alpha opacity.

The choice of alpha transparency or alpha opacity is one of those cases where you must choose something, so you do, and then after that either trends go your way or they don't. When they don't, you decide how to deal with that. You either make adjustments that allow the choice you made to keep functioning, or you drop what you chose and switch to follow the trend.

About NAIP: that's an example of good intentions leading to you-know-where. The issue arises from how TIFF files store alpha. TIFF format files don't store alpha as one of four equivalent channels. Instead, TIFF files store three channels in BGR order, but alpha is stored in TIFF as an extra clump of data using what's called an "extra sample" tag. That extra sample tag is supposed be in one of three states, 0 for unspecified data, 1 for associated alpha and 2 for unassociated alpha.

Manifold exports images with transparency to TIFF by writing the alpha to an extra sample and setting the tag to 1. However, when Manifold reads TIFFs it always assumes the extra tag to be alpha and inverts it. It does that because very many TIFF images do not set the extra sample tag or wrongly set it to 0 even when the extra sample is intended to be alpha. That allows Manifold to read alpha transparency in most TIFF files which have been coded incorrectly but which users just want to open anyway.

NAIP is a case where a convenience to deal with an incorrect, but fairly frequently found, error causes trouble with correct data. It is somewhat analogous to how backwards lat/lon is so common that Manifold will by default assume coords are in XY order even when the data announces an EPSG code that requires them to be in YX.

NAIP does it correctly, writing 0 to the extra sample tag. The simple solution is to adjust the dataport so Manifold honors whatever the extra sample tag says. If it says 0 than bring the data in as non-inverted alpha. If it has no tag or says 1 or 2, do the inversion to use it as alpha. I've suggested that change be made immediately.

That will break imports on TIFF files that have alpha data but which fail to set the extra sample tag, but in this case it seems more important to honor somebody who is doing it right (NAIP) than to continue a convenience for cases where a particular file is doing it wrong. When the file is doing it wrong, it's easy enough to rescue the data with the expression I published.

NAIP fourth channel data isn't alpha, so it really doesn't matter what the Manifold system is for alpha transparency or alpha opacity or how that gets converted on the fly to some other system. It just matters that the dataport sees the tag and doesn't treat NAIP as part of the alpha system.

A different issue is whether it makes sense to continue Manifold's use of alpha transparency within the Style pane or to make changes to reflect increasing standardization on alpha opacity. I personally think it would be better to bite the bullet and simply switch to using alpha opacity.

That would involve making a relatively simple change but one that appears in many places. It would also require a one-time conversion, inverting alpha values, of all "old style" .map files. That's not fun, but it would be cleaner, I think, than a collection of more trickier adjustments to stick with the legacy way it is now.

Dimitri


5,249 post(s)
#05-Feb-19 14:07

Or, an even better idea, just use whatever is in the data and set a property for whether that data uses alpha transparency/opacity...

tjhb

8,516 post(s)
#05-Feb-19 14:41

Much food for thought here, and some things I didn't know, and if I ever did know, had forgotten. A quick comment just for now.

My string intuition is that Manifold should be as agnostic as it can possibly be about what the data contains and what it means. That includes making it easy for me to say, from one moment to the next, channel x is elevation, channel x is now landcover, channel x, y and z are vector components and channel t is time, channel x is now alpha (of either kind), now aspect from north, now it is just plain red.

This kind of semantic fluidity or substitution is not going to arise every day, certainly not in that sort of sequence (that would be mad), but the possibility of it is deeply important, and making it a straightforward seems like an excellent design principle.

Much of it is already in place. The style panel is designed expressly to be agnostic about data--but currently, with some (I think) unnecessary assumptions and constraints regarding alpha.

Another quick comment (an addition): bit depth should never determine (or constrain) data semantics. Currently it partly does.

Dimitri


5,249 post(s)
#05-Feb-19 18:36

My string intuition is that Manifold should be as agnostic as it can possibly be about what the data contains and what it means. That includes making it easy for me to say, from one moment to the next, channel x is elevation, channel x is now landcover, channel x, y and z are vector components and channel t is time, channel x is now alpha (of either kind), now aspect from north, now it is just plain red.

Great minds think alike! That's where it's headed, which we'll see when we get to the big raster cycle. But first we need to close out some more GPU items, layer groups, etc., that's on deck

Mike Pelletier


1,558 post(s)
#05-Feb-19 17:30

Don't have much to add other than to say I really like adding this and whatever controls are needed to give the control Tim speaks of below. Since we are usually not dealing with one image file, It would be nice to either have the importer be able to apply the needed settings during import or somehow let the style dialogue apply to many similar image components.

This is a very interesting topic and very glad you are pushing it forward. Hopefully we will soon be able to adjust projection for linked images as well. Without that I cannot use all the nice ecw images I've created over the years. Yes I can import them but for some reason my largest (47 GB) one seems to bomb on import (program has stopped working message appears). Could be some sort of time out thing on my end.

Dimitri


5,249 post(s)
#05-Feb-19 18:34

Hopefully we will soon be able to adjust projection for linked images as well.

Why not show them in a map window, and set the map window to the projection you want?

for some reason my largest (47 GB) one seems to bomb on import (program has stopped working message appears)

That's worth reporting. It's likely the ECW driver, which is not Manifold code, but Manifold has two ECW drivers to choose from and it could be the other vendor's driver won't bomb.

Mike Pelletier


1,558 post(s)
#05-Feb-19 20:05

Why not show them in a map window, and set the map window to the projection you want?

Because then all my other layers have to reproject to this incorrect projection. It works but a definite compromise.

I'll report the ecw issue. Thanks.

Dimitri


5,249 post(s)
#05-Feb-19 08:05

OK. Here is the procedure. You can do it in one step, as follows:

1. Import the NAIP .tif image.

2. Open it.

3. Launch the Transform panel. It opens with Tile being the target field.

4. Click on the Expression tab.

5. Enter the following expression:

TileChannelsConcat(TileChannel([Tile], 0), 

TileChannelsConcat(TileChannel([Tile], 1), 

TileChannelsConcat(TileChannel([Tile], 2), 

CASTV((255 - TileChannel([Tile], 3)) AS UINT8))))

6. Press Update Field. Done. Channel 3 is now inverted.

If you want to see this in action with a Preview, start by opening the NAIP .tif image and use the Style pane to assign channels 3, 2, 1 to R, G, B, with A set to a Value of 0.

That shows the too-bright CIR effect. You can then switch to the Transform panel, and in the Expression tab enter the expression above. The moment you enter it, you'll see a preview that shows the image using the desired CIR effect. Press Update Field and it is applied.

Unpacking what the expression does...

When I started looking at the channels I wanted to experiment with each channel individually, but in the context of the entire image. So, this is what I did:

1. Open the Tiles table for the image and launch Edit - Schema.

2. Add four new fields to the table, all of them of type tile, and naming them Tile0, Tile1, Tile2, and Tile3.

3. Back in the table launch the Transform dialog and then for each of the Tilex channels in turn, extract just that channel's tile using the TileChannel function in the Expression tab.

For example, if in the Transform panel you set the target field to Tile2, in the Expression tab enter

TileChannel([Tile], 2)

That fills the Tile2 field with a tile that is 128x128 uint8 that is Channel 2 in the [Tile] field. It's one of the channels in the 128x128 uint8x4 tile from which the image is displayed.

4. You now have four additional columns of tiles, where each of the columns is one of the channels. You can play around with them. For example, suppose you want to invert the values in the Tile3 column. In the Transform panel you make the target field Tile3 and then in the Expression tab enter the expression

CASTV((255-[Tile3]) AS UINT8)

The CASTV is required because the output of computation is a FLOAT64 and you want all the types to stay UINT8 for when you reassemble the channels back into one uint8x4 tile.

5. After playing around with individual channels, and seeing what those experiments do, when you are happy with what you've done, you can use the TileChannelsConcat function to reassemble the channels back into the [Tile] field, as described in this topic.

I used the process above to figure out what was going on. Once I knew, I could pack together all the necessary functions into a single expression, doing the channel extractions and concatenations together in one go. That's what the expression does.

You could, of course, imagine an extension to Transform dialogs that allow expressions to operate only on a single channel within a multi-channel tile. Such things are always a balance between adding very large numbers of transforms and dialogs or just using SQL expressions to do anything not canned within an existing transform.

So... apply the above expression and in a second... no more radioactive ponds! :-)

drtees45 post(s)
#07-Feb-19 19:49

I tried this and it worked. I did make one guess when creating the new fields in the schema as you suggested. I assumed that the new fields should be UINT8 instead of the default boolean. Regardless, I now have the image I was after.

Manifold User Community Use Agreement Copyright (C) 2007-2017 Manifold Software Limited. All rights reserved.