In past I have used OpenCv for processing 32 bit .bmp files, and have got successful results. How do I make use of Opencv functions to process 12bit raw data?
My processing will be mostly operations like finding the some of 1000 pixels and so on.
EDIT
The file that I am getting is .bin file. And the Pixels in Image are placed like this(the file has all the content like this, coz I am taking a picture of white paper):
(FF)(0F)(FF)(0F)(FF)(0F)(FF)(0F)(FF)(0F)(FF)(0F)(FF)(0F)
Clearly I can do 16 bit processing on this.
Well I wanted to do 16 bit processing on this image. The secret is then reveled in another question .
For 16 bit I will have to switch to PNG not bmp!
This document says I can use 16 bit PNG in OpenCV
From what I know, OpenCV is only handling 8, 16 and 32 bits images correctly.
depending on what you want to do, you should
either transforming your 12 bits image into 8bits (assuming it s a 12 bits bayer encoded image)
or convert it manually to 16 by padding the values with zeros. From what I found here, this might already been done on your image.
I'd advise you to look closer at how your pixels are exactly placed in your image before doing anything. This will greatly help you to know what is best.
A good way to do this is using bless or another hex editor
EDIT:
Taken from here, Your data are (I think) encoded over 16 bits with padding
Simply convert from 16 bits to 8 bits using Opencv should do the trick, as it is what is done while converting to JPEG.
Have you at least tried ?
Left shift the bits and store them as 16bit.
For a monochrome camera:
cv::Mat imgOpenCV = cv::Mat(cv::Size(img->width, img->height), CV_16UC1, (char*)img->imageData, cv::Mat::AUTO_STEP); //Convert the raw image
imgOpenCV.convertTo(imgOpenCV, CV_16UC1, 1.0*(2^4), 0.0); //Shift left 4 bits
For a color camera:
// Convert the image using the manufacturer's SDK (Imperx in this case)
IpxImage* imgConverted = nullptr;
IpxError err = IPX_CAM_ERR_OK;
IpxSize imgSize;
imgSize.height = img->height;
imgSize.width = img->width;
uint32_t pixelType = II_PIX_BGR12;
err = IpxCreateImage(&imgConverted, imgSize, pixelType);
err = IpxBayer_ConvertImage(hBayer, img, imgConverted);
// Create OpenCV converted image
cv::Mat imgOpenCV = cv::Mat(cv::Size(imgConverted->width, imgConverted->height), CV_16UC3, (char*)imgConverted->imageData, cv::Mat::AUTO_STEP); //Convert the image
imgOpenCV.convertTo(imgOpenCV, CV_16UC3, 1.0*(2^4), 0.0); //Shift left 4 bits
You could also use the manufacturer's SDK to convert to 16 bit directly, but I suspect this scales the bit depth instead of shifting it in some cases. I'd rather preserve the raw bit depth information, so doing the shift myself prevents me from having to look under the hood when I switch manufacturers (GigE cameras force you to use the manufacturer SDK unfortunately).
No function of OpenCV supports 12 bit data.
Read the data as 'char'. 3 char = 2x12 bit data.
This data can be conveniently converted to 16bit data:
Left shift char1 by 4 and store to short1.
Add it with (char2 & 0xF0) to get the first 12 bit data in short1.
Left shift (char2 & 0x0F) by 8 and store to short2.
Add it with char3 to get the next 12 bit data in short2.
Related
I have a image that I am trying to read via imread but after reading the image it comes to a matrix of 256 x 256 x 4 but to work on it i need it to be 256 x 256 x 3. I am trying but I am unable. So how can I try to convert it?
im = imread('Test1.tif');
It is always a good idea to inspect the output of imfinfo whenever you're not sure about an image format...
If you carefully read the documentation of the imread function regarding TIFF images:
If the color image uses the CMYK color space, A is an m-by-n-by-4 array. To determine which color space is used, use imfinfo to get information about the graphics file and look at the value of the PhotometricInterpretation field.
I'm trying to place a png image on a postscript document for conversion to a pdf file using Ghostscript (v 9.15) ps2pdf. I've found that the following code works nicely with a jpg file, but I need to import png files instead. It looks like i must need a different filter, but I can't find one that works. Does anyone have a solution?
239 % number of pixels in the horizontal axis
67 % number of pixels in the vertical axis
8 % bits per color channel (1, 2, 4, or 8)
[239 0 0 -67 0 67] % transform array... maps unit square to pixel [ w 0 0 -h 0 h ]
(My_Logo.jpg) (r) file % see page 587 and page 77 for more details
/DCTDecode filter % see page 589
false % pull channels from separate sources
3 % 3 color channels (RGB)
colorimage % see page 544 and page 288 for more detail
PostScript doesn't support PNG directly, it does support JPEG which is why your code above works.
If you want to read image data from a PNG file you will need to open the file, strip the header, then read each chunk individually parsing the data from it. It might be easiest to write the bitmap data to an intermediate file, but its perfectly possible to write a stream decoder to supply the data as required for a procedural image data source.
Fortunately PostScript (level 3 for certain, most versions of level 2) does support Flate, so you don't have to write the decompression code in PostScript, you can use the filter directly.
You will need to specify a colour space, depending on whether the PNG uses a palette or not.
PostScript is a programming language, so this is all possible, it will take an experienced PostScript programmer a couple of days to write and debug it I should think.
NOTE! PostScript does not support transparency, so you cannot apply alpha channels from PNG files at all.
I am processing microscopy images (in Matlab) in the tiff format, normally uint8 or uint16. Basically I read them, put them in a cell array for processing and then export them in the tiff format either as an image sequence or a stack (using imwrite and either the 'overwrite' or 'append' writemode property of imwrite, respectively). Up to now everything works very well.
The problem I'm having is the following:
When I open the images with ImageJ, they are not in truecolor "RGB" color mode, but rather in composite mode. For example ImageJ reads the data as 8 bit, which it is, but does not open the image as a truecolor (Sorry for the bad choice of words I don't know the right terminology). Hence I have to manually combine the 3 channels together, which is bothersome for large datasets.
Here is a screen shot explaining. On the left is what I would like,i.e. what I obtain if I open the image directly with ImageJ, and on the right is what I currently have after saving images with Matlab and opening them with ImageJ, which I don't want.
The code I'm using to export the image sequence is the following. "FinalSequenceToExport" is the cell array containing the images.
for i = 1:SliceNumber
ExportedName = sprintf('%s%s%d.tiff',fileName,'Z',i);
imwrite(FinalSequenceToExport{i},ExportedName,'tif','WriteMode','overwrite','Compression','none');
end
If I ask Matlab the size of FinalSequenceToExport{1}, for instance, it gives 512 x 512 x 3.
If I open a given image in the command window and then save it with the same code as above, it does what I want and the resulting image opens as I want in ImageJ. Hence my guess would be that the problem arises from the use of the cell array but I don't understand how.
I hope I've been clear enough. If not please ask for more details.
Thanks for the help!
You need to specify the the 'ColorSpace'
Try this
imwrite(FinalSequenceToExport{i},ExportedName,...
'tif','WriteMode','overwrite','Compression','none', ...
'ColorSpace', 'rgb');
After revisiting this question I found the following to work, thanks to the hint from #Ashish:
imwrite(uint8(FinalSequenceToExport{i}/255),...);
I just needed to divide by 255 after converting to uint8.
I am recently developing some firmware on the STM3210E development board which has an ARM cortex M3 processor. It has been interfaced to a 240x320 LCD. After going through the demo firmware, I realised that images are encoded in 32 bit variables (correct me if I am wrong) stored in array as shown below.
uint32_t STM32Banner[50] = {0x6461EB7A, 0x646443BC, 0x64669BFE, 0x6468F440, 0x646B4C82,
0x646DA4C4, 0x646FFD06, 0x64725548, 0x6474AD8A, 0x647705CC,
0x64795E0E, 0x647BB650, 0x647E0E92, 0x648066D4, 0x6482BF16,
0x64851758, 0x64876F9A, 0x6489C7DC, 0x648C201E, 0x648E7860,
0x6490D0A2, 0x649328E4, 0x64958126, 0x6497D968, 0x649A31AA,
0x649C89EC, 0x649EE22E, 0x64A13A70, 0x64A392B2, 0x64A5EAF4,
0x64A84336, 0x64AA9B78, 0x64ACF3BA, 0x64AF4BFC, 0x64B1A43E,
0x64B3FC80, 0x64B654C2, 0x64B8AD04, 0x64BB0546, 0x64BD5D88,
0x64BFB5CA, 0x64C20E0C, 0x64C4664E, 0x64C6BE90, 0x64C916D2,
0x64CB6F14, 0x64CDC756, 0x64D01F98, 0x64D277DA, 0x64D4D01C}
Could you please explain me how to convert a JPEG/PNG/BMP image to this format (RGB565) ?
You have two choices:
Write your own set of decoders.
Use available free decoders
The first solution is only really viable for BMP (and perhaps GIF), which is quite a simple format compared to PNG and JPEG. Even so, writing a BMP decoder that handles all different versions and specialties of BMP gracefully takes quite a bit of work (I have tried it). Hacking together something that can extract the image data from the most common BMP formats is quite easy though.
The second solution is probably the way to go for the other formats. Most open-source decoders are available under LGPL or similar, so licensing shouldn't really be a problem. For JPEG images use libJPEG, for PNG use libPNG and for GIF use giflib.
Most of the decoders do not support decoding to RGB565 so you will have to write a converter to convert from RGB888 to RGB565.
use a program like GIMP to convert to an uncompressed bmp (what you normally get when you save-as bmp).
A bmp has something like a 54 byte header then it goes into the data. Each line is pixels either 3 bytes (RGB) or four bytes (RGBX) per pixel. The width is aligned on a 4 byte boundary so if you have three bytes per and multiply that by the width in pixels if that is not a multiple of four (say 3 bits wide * 3 = 9 as a simple example) then there will be some padding. You know from opening the file in gimp how wide it is, you probably want to use gimp to adjust the image to match your lcd screen anyway. The first bytes of data after the header are the pixel in the lower left corner of the image, you might need to flip the image in the y axis, or just start off this way and see what happens.
Knowing the size of your image, (from opening it with gimp), you can do a little math to see if the size of the file matches with what I am saying, if it is dramatically smaller then there is some compression going on and you need to save again and change the settings for the bmp.
Once you have this figured out then write a simple program to extract the pixels from the bmp and save them in the format you desire. Even better read the code and docs and understand how to program the lcd and you can get from raw pixels to the lcd without having to to through their specific format/code.
I am trying to save a JPEG image onto the disk using imwrite, seems that I am missing something. I am always getting a black image of around 4KBs. What am I doing wrong here?
Image I see seems fine but once onto the disk, its completely black.
std::vector<int> qualityType(1);
qualityType.push_back(CV_IMWRITE_JPEG_QUALITY);
cv::imwrite("Final.jpg",image,qualityType);
The following code works for me on 8bit (1 and 3 channel) images:
std::vector<int> qualityType;
qualityType.push_back(CV_IMWRITE_JPEG_QUALITY);
qualityType.push_back(90);
cv::imwrite("Final.jpg",image,qualityType);
In your code qualityType is initialized incorrectly. Your vector contains 2 values
{<some unknown number>, CV_IMWRITE_JPEG_QUALITY}
but should be
{CV_IMWRITE_JPEG_QUALITY, <desired quality value>}
imwrite prints on a 0 to 255 scale, but your image is in a 0 to 1 scale. To scale up, use this line:
image.convertTo(image, CV_8UC3, 255.0);
I only had to convert it to 16bit image
image.convertTo(image,CV_16UC3,255,255);
as per document, 8 or 16 bit images can be saved.