When using the function: D3DXSaveTextureToFile and passing in D3DXIFF_BMP to create a bmp I've noticed that the values seem to be estimated rather than given specifically.
Correct me if I'm wrong but a floating point texture can store any float in any given texel which would put it outside the range of a BMP which is stuck between rgb(255,255,255,255), so what it seems that the function is doing is simply taking the upper most and lowermost value of the texture and normalizing it between that range.
So my question is: Is it possible to grab the values exactly as they are in memory? including when the colours are outside of the spectruc of the computer monitor?
Don't use BMP. Use a format that supports the data type you want. For DX textures, it seems the D3DXIFF_PFM format is what you need. It's described like so:
Portable float map format. A raw
floating point image format, without
any compression. The file header
specifies image width, height,
monochrome or color, and machine word
order. Pixel data is stored as 32-bit
floating point values, with 3 values
per pixel for color, and one value per
pixel for monochrome.
Note that images will be large, though. A 256x256 texture in this format should weigh in at around 768 KB.
Updates: You should be able to use Image Magick's display command to view images in this format. Also HDRView supports the PFM format. A third choice might be fv.
Related
Let me explain.
My program takes an x-ray in a format of the x-ray detector ".his" which goes from 0 to 65535, and from those values it can tell you how much of a certain material is in each pixel "4 cm of aluminum" for example.
It does that for every pixel and you end up with a matrix that tells you how much of a given material is there, and you can visualize that matrix and see only fat tissue in an image without the bones blocking your view, it's very cool I know.
What I want to do now is to save that matrix as an image so that I can analyse and modify that image with programs like Image J, but I also want that if I see the pixel value I see the original value, I want to see "4" and know that pixel shows 4 cm of lungs or whatever material I'm working on.
Is that possible?, my professor seems to think that it is but he's not sure how to do it, and figure that out is my job anyway.
It should be possible since with Image J I can open the ".his" format and I can do just that, I can see the values from 0 to 65535, provided I say Image J that the image is 16 bit unsigned and other properties of that kind of files, but I wouldn't know how to do that for a Matlab variable.
Thanks a lot.
So if I understand correctly, you want to save an image that also contains arbitrary metadata on every pixel (in this case an integer).
If you use an image format like PNG you could encode that extra data into the alpha channel (which would be nearly imperceptible with a value like 4/255 away from fully opaque), but you'd have to be careful when editing the image that you don't change the alpha channel by mistake.
However, this is rather finnicky and would be cumbersome to implement in Matlab.
Instead I would suggest simply saving a standard image and a text file (or binary file) alongside it with the data you want.
I have a 16bit voxel data set from which I need to extract the integer values for each voxel. The data set can be downloaded from here, it is the 'Head Aneuyrism 16Bits' data set (You need to click on the blood vessels image to download the 16bit version). Its size is 512x512x512, but I don't know whether it is greyscale or color, nor if that matters. Looking at the image on the website I'd guess that it is color, but I am not sure whether the image should be taken literally.
A related question on SO is the following: How can I read in a RAW image in MATLAB?
and the following on mathworks: http://www.mathworks.com/matlabcentral/answers/63311-how-to-read-an-n-dimensioned-matrix-from-a-binary-file
Thanks to the information in the answers to these questions I managed to extract some information from the file with matlab as follows:
fileID=fopen('vertebra16.raw','r');
A=fread(fileID,512*512*512,'int16');
B=reshape(A,[512 512 512]);
I don't need to visualise the image, I only need to have the integer values for each voxel, but I am not sure whether I am reading the information in the correct way with my script.
The only way I found to try and check whether I have the correct voxel values is to visualise B using the following:
implay(B)
Now, with the code above, and then using implay(B) I get a black and white movie with a white disc in the center and black background and some black pixels moving in the disc (I tried to upload a frame of the movie, but it didn't work). Looking at the image on the website from which I downloaded the file, the movie frames I get seem quite different from that image, so I'd conclude that I do not have the correct voxel values.
Here are some questions related to my problem:
Do I need to know whether the image is in grey scale or color to read the voxel values correctly?
On the data set website there is only written that the data set is in 16bit format, so how do I know whether I am dealing with signed or unsigned integers?
In the SO question linked to above they use 'uint8=>uint8'. I could not find this in the matlab manual, so I wonder whether 'uint8=>uint8' is an obsolete matlab notation for 'uint8' or if it does something different. I suspect that it does something different since if I use 'int16=>int16' instead of 'int16' in my code above I get a completely black movie with implay.
It looks like you read the data correctly.
The problem when displaying it is the scale of the values. implay seems to assume the values to be in [0,1] and therefore clamps all values to be in that range, where are your data range is [0,3000].
Simply doing
B = B / max(B(:))
will rescale your data to [0,1] and looking at the data again with
implay(B)
shows you something much more sensible.
I am trying to convert an array of RGB values into an array of HSV values in Matlab. I am running the following code:
pic = imread('ColoradoMountains.jpg');
pic = rgb2hsv(pic);
imwrite(pic,'pic.jpg')
But the image that gets written has completely different colors. I've been trying to set the color map to hsv, but I'm not sure if that even makes sense. Nothing on the internet comes up with my keywords, can someone please point me in the right direction?
You can specify the colormap that imwrite is supposed to use. Try this:
imwrite(pic,colormap('HSV'),'pic.png');
Here's the documentation for imwrite: http://www.mathworks.com/help/matlab/ref/imwrite.html
In Matlab you have to distinguish between an indexed image and an 3-channel image. An indexed image is a n*m*1 image where each value of the [0,1] range is associated to a colour. This association is called colour map, which could be for example a unit circle in HSV or RGB. This can be written using imwrite with the map parameter, but this is not what you want.
What you obviously want is an HSV-encoded image, which means the three rgb-channels are converted to three hsv channels. This is (as far as I know) not possible. If you take a look into the documentation of imwrite, you can see how CMYK-Encoded images are written, this is done implicit passing a n*m*4 image. Is there any of the standard file formats which supports HSV? If so I'll take a closer look at this format.
I'm trying to develop a mobile application, and I'm wondering the easiest way to convert an image into a text file, and then be able to recreate it later in memory said text. The image(s) in question will contain no more than 16 or so colors, so it would work out fine.
Basically, brute-forcing this solution would require me saving each individual's pixel color data into a file. However, this would result in a HUGE file. I know there's a better way - like, if there's a huge portion of the image that consists of the same color, breaking up the area into smaller squares and rectangles and saving their coordinates and size to file.
Here's an example. The image is supposed to be just black/white. The big color boxes represent theoretical 'data points' in the outputted text file. These boxes would really state their origin, size, and what color they should be.
E.g., top box has an origin of 0,0, a size of 359,48, and it represents the color black.
Saved in a text file, the data would be 0,0,359,48,0.
What kind of algorithm would this be?
NOTE: The SDK that I am using cannot return a pixel's color from an X,Y coordinate. However, I can load external information into the program from a text file and manipulate it that way. This data that I need to export to a text file will be from a different utility that will have the capability to get a pixel's color from X,Y coordinates.
EDIT: Added a picture
EDIT2: Added constraints
Could you elaborate on why you want to save an image (or its parts) as plain text? Can't you use a binary representation instead? Also, if images typically have lots of contiguous runs of pixels of same color, you may want to use the so-called run-length encoding (RLE). Alternatively, one of Lempel-Ziv-something compression algorithms could be used (LZ77, LZ78, LZW).
Compress the image into a compressed format (e.g. JPEG, PNG, GIF, etc) and then save it as a .txt file or whatever. To recreate the image, just read in the file into your program using whatever library function suits your particular needs.
If it's necessary that the .txt file have some textual meaning, then you may be in some trouble.
In cs there is an algorithm like spatial index to recursivley subdivide a plane into 4 tiles. If the cell has the same size it looks like a quadtree. If want you to subdivide a plane into pattern (of colors) you can use this tiling idea to dynamically change the size of the cell. A good start to look at is a z-curve or a hilbert curve.
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