My platform is Windows. I didn't expect reading indexed palette image to be this difficult in C++. In case you are not familiar with it, it's single channel image but expresses its pixel color with 256 indexed colors called palette.
I was using OpenCV but its imread just converts the file to a 3 channel image so I have no way to save it back to indexed palette image or compare it with another indexed palette image.
I tried to use Bitmap but for some reason, it does not read correct pixel values.
So right now, I am looking for a light library or code to read pixels from indexed palette file.
Using OpenCV to read or write a image from real cameras will lose and change the image information, so I prefer to use gdi+, which is more powerful in dealing with image format problems to solve your problem.
As comments on the question shows, I decided to have two methods, OpenCV for non-indexed-palette images and Bitmap (GDI+) for indexed palette images. Now everything is working perfect.
Related
I'm using WIC (Windows Imaging Component) to decode image files and get access to the pixel data. I'm trying to figure out the pixel order (i.e., bottom-up or top-down).
I use IWICImagingFactory::CreateDecoderFromFileName to create the decoder from which I grab the (first) frame (IWICBitmapFrameDecode). With the frame, I use GetPixelFormat and GetSize to compute a buffer size, and finally I use CopyPixels to get the decoded pixel data into my buffer.
This works fine with a variety of JPEG files, giving me pixel rows in top-down sequence, and the pixels are in BGRX order (GUID_WICPixelFormat32bppBGR).
When I try with GIF files, however, the pixel rows come in bottom-up sequence. The reported pixel format is RGBA (GUID_WICPixelFormat32bppRGBA), but the ground truth shows the channel order is BGRA (with the blue in the low byte of each 32-bit pixel, just like JPEG).
My primary question: Is there a way for me to query the top-down/bottom-up orientation of the pixel data?
I found a similar question that asked about rotation when using JPEG sources, and the answer was to query the EXIF data to know whether the image was rotated. But EXIF isn't used with GIF. So I'm wondering whether I'm supposed to assume that pixels are always bottom-up, except for ones that do have an EXIF orientation that says otherwise. Update 6/25/2020 Nope, the JPEG orientation is neutral and the GIF has no orientation information, yet MS Paint and other programs can open the files in the correct orientation.
My secondary question: What's up with the incorrect channel order (RGB/BGR) from the GIF decoder?
Not only that, the WIC documentation says that the GIF decoder should return indexes into a color table (GUID_WICPixelFormat8bppIndexed) rather than actual pixel values. Is it possible some software on my machine installed its own buggy GIF decoder that supersedes the one that comes with Windows 10?
To query photo orientation for formats that support it you should use System.Photo.Orientation photo metadata policy (or one of file format specific metadata query paths) using IWICMetadataQueryReader interface.
As for GetPixelFormat() reporting "incorrect" pixel format, it is right there in the Remarks section:
The pixel format returned by this method is not necessarily the pixel format the image is stored as. The codec may perform a format conversion from the storage pixel format to an output pixel format.
Native byte order of image bitmaps under Windows is BGRA, so that is what you are getting from the decoder. If you want image in a different format you need to use IWICImagingFactory::CreateFormatConverter() to create a format converter and convert the image data before copying.
Finally, GIF doesn't have orientation metadata because it is always encoded from top to bottom. Most likely reason you are getting a vertically inverted image is because you are reading it directly from the decoder -- try calling CopyPixels() on the converter instead.
I would like to read DICOM images in C++ and manipulate them using opencv.
I managed to read a dicom image using DCMTK however, I am unsure how to convert it to an opencv Mat.
The following is what I have so far:
DicomImage DCM_image("test.dcm");
cv::Mat image(int(DCM_image.getWidth()), int(DCM_image.getHeight()), CV_8U, (uchar*)DCM_image.getOutputData(8));
which results in the following:
In a DICOM viewer, it looks as follows:
After normalising, the grayed image appears as follows:
Any help would be greatly appreciated.
The main problem I can see now is the difference of pixel value ranges (depths).
AFAIK, DICOM can have a rather big depth (16 bit), and you are trying to fit in into CV_8U, which is only 8 bit. You can get DicomImage instance's depth using DicomImage::getDepth(), and then create a cv::Mat with appropriate depth to hold your image data.
You may also need to normalize the data to maximally utilize you available range, so that the display with cv::imshow() would look as expected.
So:
Do DicomImage::getDepth() on your DCM_image
Create a cv::Mat with sufficient depth to hold your data
Scale, if necessary
Before calling DicomImage::getOutputData() on a monochrome DICOM image, you should make sure that you've selected an appropriate VOI transformation (e.g. Window Center & Width). This could be done by DicomImage::setMinMaxWindow(), DicomImage::setWindow() etc. See documentation of the DicomImage class.
Please note, however, that DicomImage::getOutputData() always returns rendered pixel data, i.e. not the original Pixel Data that is stored in the DICOM dataset.
U need to read the data type in DICOM image encoding an convert that to opencv type Mat. The opencv docs provides the entire information on their Mat header.
I would like to write CPP code that is able to take in a PNG file, scan through its pixels and identify where the transparent pixels are.
I tried doing this with CIMG, but it didn't work out as CIMG only supports the RGB channels. Even after installing image magick, the 4th channel is not giving me the right values.
Anyone can suggest a library I could use?
I have extracted the depth map of 2 images and stored them as .tif file
now I would like to use openGL to join these two images depending on their depth
so I want to read the depth for each image from the .tif file and then use that depth to draw the pixel with the higher depth
to make it more clear the depth map are two images like this
link
so say I have the pervious image and I want to join it with this image
link
my question is how to read this depth from the .tif file
Ok, I'll have a go ;-)
I see the images are just grayscale, so if the "depth" information is just the intensity of the pixel, "joining" them may be just a matter of adding the pixels. This is generally referred to as "blending", but I don't know what else you could mean.
So, you need to;
Read the 2 images into memory
For each pixel (assuming both images the same size):
read the intensity from image A[row,col]
read the intensity from image B[row,col]
write max(A[row,col],B[row,col]) to C[row,col]
Save image C - this is your new "joined" image.
Now OpenGL doesn't have any built-in support for loading/saving images, so you'll need to find a 3rd party library, like FreeImage or similar.
So, that's a lot of work. I wonder if you really want an OpenGL solution or are just assuming OpenGL would be good for graphics work. If the algorithm above is really what you want, you could do it in something like C# in a matter of minutes. It has built-in support for loading (some formats) of image file, and accessing pixels using the Bitmap class. And since your created this images yourself, you may not be bound the the TIFF format.
I'm building a program to convert an image file (whatever file type would be easiest) to G-Code for use on a rep-rap with a pen plotter attachment.
I'm wondering if i wanted to process the image pixel by pixel and check things like pixel color, how could I do this with C++?
I would really like to know how I can process a bitmap image, pixel by pixel, to check the color of the pixel.
The best way is to use a library, like for example Magick++.
When you load an image, you can access it's pixels data with Blob
You will probably want to use an existing library that has been tested.
But for fun/practice/etc, this would be a good exercise and wouldn't be impossible to do. The Bitmap Format is (relatively) simple compared with other image formats. The Wikipedia page has some tons of info, including some C++ code. It looks like once you've gotten past the header information, you get to a pixel array that shouldn't be difficult to parse.
Good luck.
Most image formats consist of a header and the actual raw image data. A bimpap image is no different. If you don't want to use one of the existing libraries, or if you are not allowed to, you should read about bitmap format :
http://en.wikipedia.org/wiki/BMP_file_format
Once you understand this you could create appropriate structs/classes to store the information you want from the header such as x,y size, bpp etc. And also have a pointer to the raw image data. You could then simpy iterate through every pixel and do whatever you want with it :)
Once you decipher the image file, I suggest you place the pixels into a matrix, for the first pass. (Future revisions can use other methods to access the pixels).
You can apply transformations to the pixels by using matrix multiplication. You can also access the pixels individually by using array indexing.
Search the web and SO for "introduction to graphics c++".