Can a hyperspectral image be stored in cv::mat? - opencv3.0

I know cv::mat container can store 3 channel images, but the data pointer of the container also could store multidimensional matrices. I was wondering if the different bands can be stored in the multidimensional matrix and keep the color channel for said bands (even though they'd be false colors beyond the visual range)

OpenCV Mat objects can be N-dimensional. As the docs for cv::Mat show, there are multiple constructors that specify the dimensions.
Furthermore, 2d matrices can have many more than three channels. The channels are encoded in the "type" of the matrix, so there exists a macro to create a type for many numbers of channels (up to CV_CN_MAX = 512) for the standard matrix datatypes, for e.g. uint8 (CV_U8C(n)) and fp64 (CV_64FC(n)). I believe the macros exist for each datatype, but you can check specifically on the same doc pages for all the macros defined up at the top.

Related

Who stores the image in zeros and ones

I wanted to know who stores the images/ videos or audios in zeros and ones. I know that an image is stored in form of zeros and ones by storing the color for each pixel in the form of zeros and ones, and similar things happen for other types of data. But my question is, for example, if I create an image using any Image creating application and store it in my computer, then what or who is storing the colors in binary form for each pixel?
There are two types of images
acquired from a device (camera, scanner), which measures the amount of light in the RGB channels for every pixel and converts it to a binary value; writing the values to memory is handled by the device driver.
synthetized, from a geometric model with surface and lighting characteristics by pure computation, and every pixel value is obtained "out of nothing"; this is done by a rendering program.
After the image has been written to RAM memory, it can be transferred to disk for long term storage.

How to convert uint8 to single? MATLAB

I have an array with 384x255 uint8 contains the features of an image, I want to train this image by using svmtrain. How to convert this array to 1-by-N single matrix so the number of rows will be equal to label.
I will explain my problem, I have extracted HOG features for ~500 images and saved results in a matrix.. easily, this matrix consist of 500 rows, each row has a HOG feature of one image.
BUT when I tried to extract LBP feature every thing is different. The matrix is about 384x255 uint8 for each image (I have ~500 images). I make reshape for this big matrix to be 500 rows, each raw has LBP features of an image but after classification them by SVM classifier, the results was terrible. So, does reshaping and converting from uint8 to single may change data and effect results?
Supposing that your array is stored in A:
B = reshape(single(A), 1, []);

How to change dynamic range of an RGB image?

I have 16-bit raw image (12 effective bits). I convert it to rgb and now I want to change the dynamic range. I created 2 map functions. You can see them visualized below. As you can see the first function maps values 0-500 to 0-100 and the second one maps the rest values to 101-255.
Now I want to apply the map-functions on the rgb image. What I'm doing is iterating through each pixel, find appropriate function for each channel and apply it on the channel. For example, the pixel is RGB=[100 2000 4000]. On R channel I'll apply the first function since 100 is in 0-500 range. But, on G and B channels I'll apply the second function since their values are in 501-4095.
But, in doing this way I'm actually changing the actual color of the pixel since I apply different functions on the channels of the pixel.
Can you suggest how to do it or at least give me a direction or show some articles?
What you're doing is a very straightforward imaging operation, frequently applied in image and video processing. Sometimes it's (imprecisely) called a lookup table (LUT), even though it's not always implemented via an actual lookup table. Examples of this are gamma adjustment or log encoding.
For instance, an example of this kind of encoding is sRGB, which is a gamma encoding from linear light. You can read about it here: http://en.wikipedia.org/wiki/SRGB. You'll see that it has a nonlinear adjustment.
The name LUT implies a good way of doing it. If you can make your image a uint8 or uint16 valued set, you can create a vector of desired output values for any input value. The lookup table has the same number of elements as the possible range of the variable type. If you were using a uint8, you'd have a lookup table of 256 values. Then the lookup is easy, you just use the image value as an index into your LUT to get the resulting value. That computational efficiency is why LUTS are so widely used.
In your case, since you're working in RGB space, it is acceptable to apply the curves in exactly the same way to each of the three color channels. RGB space is nice for that reason. However, for various reasons, sometimes different LUTs are implemented per-channel.
So if you had an image (we'll use one included in MATLAB and pretend it's 12 bit by scaling it):
someimage = uint16(imread('autumn.tif')).*16;
image(someimage.*16); % Need to multiply again to display 16 bit data scaled properly
For your LUT, you would implement this as:
lut = uint8([(0:500).*(1/5), (501:4095).*((255-101)/(4095-501)) + 79.5326]);
plot(lut); %Take a look at the lut
This makes the piecewise calculation you described in your question.
You could make a new image this way:
convertedimage = lut(double(someimage)+1);
image(convertedimage);
Note that because MATLAB indexes with doubles--one based--you need to cast properly and add one. This doesn't slow things down as much as you may think; MATLAB is made to do this. I've been using MATLAB for decades and this still looks odd to me.
This method lets you get fancy with the LUT creation (logs, exp, whatever) and it still runs very fast.
In your case, your LUT only needs 4096 elements since your input data is only 12 bits. You may want to be careful with the bounds, since it's possible a uint16 could have higher values. One clean way to bound this is to use the min and end functions:
convertedimage = lut(min(double(someimage)+1, end));
Now, this has implemented your function, but perhaps you want a slightly different function. For instance, a common function of this type is a simple gamma adjustment. A gamma of 2.2 means that the incoming image values are scaled by taking them to the 1/2.2 power (if scaled between 0 and 1). We can create such a LUT as follows:
lutgamma = uint8(256.*(((0:4095)./4095).^(1/2.2)));
plot(lutgamma);
Again, we apply the LUT with a simple indexing:
convertedimage = lutgamma(min(double(someimage)+1, end));
And we get the following image:
Using a smooth LUT will usually improve overall image quality. A piecewise linear LUT will tend to cause the resulting image to have odd discontinuities in the shaded regions.
These are so common in many imaging systems that LUTs have file formats. To see what I mean, look at this LUT generator from a major camera company. LUTs are a big deal, and it looks like you're on the right track.
I think you are referring to something that Photoshop calls "Enhance Monochromatic Contrast", which is described here - look at "Step 3: Try Out The Different Algorithms".
Basically, I think you find a single min from all the channels and a single max from across all 3 channels and apply the same scaling to all the channels, rather than doing each channel individually with its own min and max.
Alternatively, you can convert to Lab (Lightness plus a and b) mode and apply your function to the Lightness channel (without affecting the a and b channels which hold the colour information) then transform back to RGB, your colour unaffected.

Scan an image for certain colors, convert to an integer array

So I recently obtained an 8x8 bi-color LED array for my arduino kit, and I want to be able to read an image file for certain RGB values at certain coordinates, to create a 2d int array, with the ints corresponding to certain RGB values. for instance, since my array can display 3 different colors, i could define three different RGB values to read from the image in the code. then i'd have it read the image, make a 2d int array by the dimensions of the image, store ints 1-3 in the array where the corresponding RGB values were found.
i was going to try and find a C library for it but I think that arduino is a separate language, I'm not sure.
I did similar stuff for my Blinkenlight Experiments. Especially for the POV experiments. You might want to have a look at my Python code for converting images to Arduino Programms here: http://blog.blinkenlight.net/experiments/basic-effects/pov-generator/.
Another easy way to convert images to C code is to use "The Gimp". The Gimp supports "save as C source code" and "save as C header".
Just for completeness: Arduino is not a separate language. Arduino is C++ with some IDE preprocessing that tries to hide the fact that you actually code C++.

How is HDR data stored?

I am wondering what the data structure is behind storing images with HDR data. I understand how regular images (rgba) and cubemaps are stored. I doubt its as simple as storing multiple images at different exposures inside the same file.
You've probably moved on long ago, but I thought it worth posting references for anyone else who happened upon this question.
Here is an old reference for the Radiance .pic (now .hdr) file format. The useful info starts at the bottom of page 29.
http://radsite.lbl.gov/radiance/refer/filefmts.pdf
excerpt:
The basic idea is to store a 1-byte mantissa for each of three
primaries, and a common 1-byte exponent. The accuracy of these values
will be on the order of 1% (+/-1 in 200) over a dynamic range from
10^-38 to 10^38.
And here is a more recent reference for JPEG HDR format: http://www.anyhere.com/gward/papers/cic05.pdf
It's generally a matter of increasing the range of values (in an HSV sense) representable, so you can use e.g. RGB[A] where each element is a 16-bit int, 32-bit int, float, double etc. instead of a JPEG-type-quality 8-bit int. There's a trade-off between increasing the range represented, retaining fine gradations within that range, and whether some particular intensity levels are given priority via some non-linearity in the mapping (e.g. storing a log of the value).
The raw file from the camera normally stores the 12-14bit values from the Bayer mask - so effectively a greeyscale. These are sometimes compressed losslessly (in Canon or Nikon) or as 16bit values (Olympus). The header also contains the white balance and gain calibrations for the red,green,blue masked pixels so you can generate a color image.
Once you have a color image you can store it however you want, normally 16bit RGB is the easiest.
Here is some information on the Radiance file format, used for HDR images. It uses 32-bit floating-point numbers.
First, I am not sure if there is a public format for storing multiple images at different exposures inside cause the usage is rare. Those multiple images are used as one sort of HDR sources, but they are not HDR, they are just normal LDR (L for low) or SDR (S for standard?) images encoded like JPEG from digital cameras.
It is more common to store resulting in HDR format and the point is just like everyone mentioned, in floating point.
There are some HDR formats:
OpenEXR
TIF
Radiance
...
You can get more info from wiki

Resources