LibRaw and OpenCV - c++

I use a Canon EOS 1200D.
This camera creates JPEG files with a resolution of 5184 x 3456.
The camera creates also CR2 files.
I use LibRaw to open this file.
LibRaw processor;
processor.open_file("test1.CR2");
If i debug my program i can see:
processor.imgdata.sizes.raw_height = 3516
processor.imgdata.sizes.raw_width = 5344
processor.imgdata.sizes.height = 3465
processor.imgdata.sizes.width = 5202
processor.imgdata.sizes.top_margin = 51
processor.imgdata.sizes.left_margin = 142
processor.imgdata.sizes.iheight = 3465
processor.imgdata.sizes.iwidth = 5202
1/ Why the resolution of 5184 x 3456 does not appear?
I see also four objects in:
processor.tiff_ifd like this:
[0] {t_width=5184 t_height=3456 bps=8 ...}
[1] {t_width=160 t_height=120 bps=8 ...}
[2] {t_width=668 t_height=432 bps=16 ...}
[3] {t_width=5344 t_height=3516 bps=14 ...}
2/ What does these four objects?
3/ I do not understand what the statement:
processor.unpack();
do.
Does it convert from RGBG format to RGB format?
Now, i would like create an cv::Mat with the resolution of 5184 x 3456 and without losing accuracy.
4/ So how i can convert my CR2 file to a cv::Mat with format CV_16UC3?
From several CR2 files, i would like create a new image wich is the average.
5/ So, when i have a cv::Mat with format CV_16UC3, how i can save it in a file without losing accuracy?
Thank you.
EDIT
Ok, so I have to use:
processor.imgdata.params.output_bps = 16;
processor.open_file("test1.CR2");
processor.unpack();
processor.dcraw_process();
libraw_processed_image_t* output = processor.dcraw_make_mem_image();
But how i can specify to use the JPEG resolution?
I think it is with:
processor.imgdata.params.cropbox
but how specify the JPEG resolution without hard coding?

Please refer to LibRAW documentation.
LibRAW uses all information stored in the raw file. In-camera and many commercial converters apply some cropping for various reasons. (see discussion here http://www.libraw.org/node/2117).
Raw files frequently contain several images: apart from raw data itself, there in normally one or more small preview images (thumbnails).
unpack method only unpacks data from raw file format without any demosaic. It is still the same raw data. To get RGB data, please refer to "Postprocessing" section in the documentation, particularly dcraw_process

Related

ITK: Could not create IO object

I am trying to calculate the gradient of an image. I tried this code on the sample image given (Gourds6.png).
I used cmake . to create the CMakeFiles and then make. Everything works fine and the executable file is created. Now when I run the code using command ./computeGradient Gourds6.png out.png 1.5, it complains that:
Error:
itk::ImageFileWriterException (0x1446b40)
Location: "void itk::ImageFileWriter<TInputImage>::Write() [with TInputImage = itk::Image<float, 2u>]"
File: /usr/local/include/ITK-4.3/itkImageFileWriter.hxx
Line: 152
Description: Could not create IO object for file out.png
Tried to create one of the following:
You probably failed to set a file suffix, or
set the suffix to an unsupported type.
I haven't done any change to this code. It should work. I don't know what is wrong with it :( Do you have any idea?
Also, why don't we need to update the reader to read the image? Why do we only update the writer?
I appreciate for any help!
The pixel type of the output file in this example of ITK is float. And writing an image of float as a PNG image is not possible.
A list of supported files formats and corresponding data types is given on the wiki of ITK.
To save this image of float, here are formats that are expected to work :
Analyze (.img)
DICOM (.dic : failed on my PC)
GIPL (.gipl)
MetaImage (mhd) (out.mhd+out.raw)
Nrrd (.nhdr, .nrrd)
Stimulate (.spr)
VTK (.vtk)
The VTK file format works well and may be opened by the paraview software.
To use a PNG format, the image should be casted to unsigned char type. It may be performed by the CastImageFilter(). See this example. Another solution is to use the RescaleIntensityImageFilter(). See this example.
This question and its answer (which happens to be mine) explains how to convert a float image type to a ùnsigned char` image type and save it as PNG.
typedef itk::RescaleIntensityImageFilter< FloatImageType, UCharImageType > RescaleFilterType;
RescaleFilterType::Pointer rescaleFilter = RescaleFilterType::New();
rescaleFilter ->SetInput(importFilter->GetOutput());
rescaleFilter->SetOutputMinimum(0);
rescaleFilter->SetOutputMaximum(255);
typedef itk::ImageFileWriter< UCharImageType > WriterType;
WriterType::Pointer writer = WriterType::New();
writer->SetFileName( "output.png" );
writer->SetInput(rescaleFilter->GetOutput() );
writer->Update();
Finally, your last question : why do we only update the writer ? As the writer is updated, it will first check if its entries are up to date. If it is not the case, it will call filter->Update(), and so on.

Can't get CreateDDSTextureFromFile to work

So, I've been trying to figure out my problem for a few hours now, but I have no idea what I'm doing wrong. I'm a noob when it comes to DirectX programming, so I've been following some tutorials, and right now, I'm trying to create a obj loader.
http://www.braynzarsoft.net/index.php?p=D3D11OBJMODEL
However, I can't get my texture to work.
This is how I try to load the DDS-texture:
ID3D11ShaderResourceView* tempMeshSRV = nullptr;
hr = CreateDDSTextureFromFile(gDevice, L"boxTexture.dds", NULL, &tempMeshSRV);
if (SUCCEEDED(hr))
{
textureNameArray.push_back(L"boxTexture.dds");
material[matCount - 1].texArrayIndex = meshSRV.size();
meshSRV.push_back(tempMeshSRV);
material[matCount - 1].hasTexture = true;
}
However, my HRESULT will never Succeed, but it doesn't crash either. If I hoover over the hr, it just says "HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED) I also tried to remove the if statement, but that will just turn my box black.
Any idea on what I'm doing wrong? =/
Thanks in advance!
The most likely problem is that your "boxTexture.dds" is a 24 bit-per-pixel format file. In Direct3D 9, this was D3DFMT_R8G8B8 and was reasonably common. However, there is no DXGI equivalent format for 24 bits-per-pixel and it therefore requires format conversion to work.
The DDSTextureLoader module in DirectX Tool Kit is designed to be a minimum-overhead function, and therefore does no runtime conversions at all. If the data directly maps to a DXGI format, it loads. If it doesn't, it fails with HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED).
There are two different solutions depending on your usage scenario.
The ideal solution is to convert 'boxTexture.dds' to a supported format. You can do this with the texconv command-line tool provided with DirectXTex. This is by far the best option so that the potentially expensive conversion operation is done once and not very single time your application runs and loads the data.
If you don't actually control the source of the dds files you are trying load (i.e. they are arbitrary files provided by a user or you are doing some kind of content tool that has to support legacy formats), then you should make use of the DirectXTex 'full-fat' LoadFromDDSFile function which has extensive conversion code for handling legacy DDS file formats.
Note this situation can happen for a number of legacy format DDS files as list in the CodePlex wiki documentation
D3DFMT_R8G8B8 (24bpp RGB) - Use a 32bpp format
D3DFMT_X8B8G8R8 (32bpp RGBX) - Use BGRX, BGRA, or RGBA
D3DFMT_A2R10G10B10 (BGRA 10:10:10:2) - Use RGBA 10:10:10:2
D3DFMT_X1R5G5B5 (BGR 5:5:5) - Use BGRA 5:5:5:1 or BGR 5:6:5
D3DFMT_A8R3G3B2, D3DFMT_R3G3B2 (BGR 3:3:2) - Expand to a supported format
D3DFMT_P8, D3DFMT_A8P8 (8-bit palette) - Expand to a supported format
D3DFMT_A4L4 (Luminance 4:4) - Expand to a supported format
D3DFMT_UYVY (YUV 4:2:2 16bpp) - Swizzle to YUY2
See also Direct3D 11 Textures and Block Compression
If you look at the source code for CreateTextureFromDDS (which is called by CreateDDSTextureFromFile to do the main data processing) - http://directxtk.codeplex.com/SourceControl/latest#Src/DDSTextureLoader.cpp - you will see that there are a lot of reasons you could be getting "HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED)".
It's not likely a problem with opening or reading the file since that would return a different error code. So most likely its an unsupported DXGI_FORMAT, a malformed cubemap, an invalid mipmap count, or invalid image dimensions (i.e. larger than the limits found here: http://msdn.microsoft.com/en-us/library/ff819065(v=vs.85).aspx ).

Saving output frame as an image file CUDA decoder

I am trying to save the decoded image file back as a BMP image using the code in CUDA Decoder project.
if (g_bReadback && g_ReadbackSID)
{
CUresult result = cuMemcpyDtoHAsync(g_bFrameData[active_field], pDecodedFrame[active_field], (nDecodedPitch * nHeight * 3 / 2), g_ReadbackSID);
long padded_size = (nWidth * nHeight * 3 );
CString output_file;
output_file.Format(_T("image/sample_45.BMP"));
SaveBMP(g_bFrameData[active_field],nWidth,nHeight,padded_size,output_file );
if (result != CUDA_SUCCESS)
{
printf("cuMemAllocHost returned %d\n", (int)result);
}
}
But the saved image looks like this
Can anybody help me out here what am i doing wrong .. Thank you.
After investigating further, there were several modifications I made to your approach.
pDecodedFrame is actually in some non-RGB format, I think it is NV12 format which I believe is a particular YUV variant.
pDecodedFrame gets converted to an RGB format on the GPU using a particular CUDA kernel
the target buffer for this conversion will either be a surface provided by OpenGL if g_bUseInterop is specified, or else an ordinary region allocated by the driver API version of cudaMalloc if interop is not specified.
The target buffer mentioned above is pInteropFrame (even in the non-interop case). So to make an example for you, for simplicity I chose to only use the non-interop case, because it's much easier to grab the RGB buffer (pInteropFrame) in that case.
The method here copies pInteropFrame back to the host, after it has been populated with the appropriate RGB image by cudaPostProcessFrame. There is also a routine to save the image as a bitmap file. All of my modifications are delineated with comments that include RMC so search for that if you want to find all the changes/additions I made.
To use, drop this file in the cudaDecodeGL project as a replacement for the videoDecodeGL.cpp source file. Then rebuild the project. Then run the executable normally to display the video. To capture a specific frame, run the executable with the nointerop command-line switch, eg. cudaDecodGL nointerop and the video will not display, but the decode operation and frame capture will take place, and the frame will be saved in a framecap.bmp file. If you want to change the specific frame number that is captured, modify the g_FrameCapSelect = 37; variable to some other number besides 37, and recompile.
Here is the replacement for videoDecodeGL.cpp I used pastebin because SO has a limit on the number of characters that can be entered in a question body.
Note that my approach is independent of whether readback is specified. I would recommend not using readback for this sequence.

converting a binary stream into a png format

I will try to be clear ....
My project idea is as follow :
I took several compression algorithms which I implemented using C++, after that I took a text file and applied to it the compression algorithms which I implemented, then applied several encryption algorithms on the compressed files, now I am left with final step which is converting these encrypted files to any format of image ( am thinking about png since its the clearest one ).
MY QUESTION IS :
How could I transform a binary stream into a png format ?
I know the image will look rubbish.
I want the binary stream to be converted to a an png format so I can view it as an image
I am using C++, hope some one out there can help me
( my previous thread which was closed )
https://stackoverflow.com/questions/5773638/converting-a-text-file-to-any-format-of-images-png-etc-c
thanx in advance
Help19
If you really really must store your data inside a PNG, it's better to use a 3rd party library like OpenCV to do the work for you. OpenCV will let you store your data and save it on the disk as PNG or any other format that it supports.
The code to do this would look something like this:
#include <cv.h>
#include <highgui.h>
IplImage* out_image = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, bits_pr_pixel);
char* buff = new char[width * height * bpp];
// then copy your data to this buff
out_image->imageData = buff;
if (!cvSaveImage("fake_picture.png", out_image))
{
std::cout << "ERROR: Failed cvSaveImage" << std::endl;
}
cvReleaseImage(&out_image);
The code above it's just to give you an idea on how to do what you need using OpenCV.
I think you're better served with a bi-dimensional bar code instead of converting your blob of data into a png image.
One of the codes that you could use is the QR code.
To do what you have in mind (storing data in an image), you'll need a lossless image format. PNG is a good choice for this. libpng is the official PNG encoding library. It's written in C, so you should be able to easily interface it with your C++ code. The homepage I linked you to contains links to both the source code so you can compile libpng into your project as well as a manual on how to use it. A few quick notes on using libpng:
It uses setjmp and longjmp for error handling. It's a little weird if you haven't worked with C's long jump functionality before, but the manual provides a few good examples.
It uses zlib for compression, so you'll also have to compile that into your project.

Convert video file to TIFF with ffmpeg.dll or avcodec.dll? Is "on-the-fly" possible?

I want to create a program, which gets a video-file from Qt, converts that video file to TIFF-files and sends them to an algorithm which handles these TIFF-Files.
My questions:
is it possible with ffmpeg or avcodec not to convert a video-file to TIFF-files first on harddrive and send them to the algorithm after that, but to convert frame for frame and send it to the algorithm right away?
The more important question: Is it possible to do that not with an external process with ffmpeg.exe, but with ffmpeg.dll? Or is it only possible with avcodec.dll? (It doesn't have to be "on-the-fly" like at my point above) How can I create a ffmpeg.dll with header and lib?
for exporting tif :
http://www.repaire.net/forums/cinema-numerique/215306-projet-dencodage-dcp.html
Creating a tiff from second 29 in a mpeg, using ffmpeg dd201110 can be done like this:
ffmpeg -i 'test.mpg' -vframes 1 -compression_level 0 -ss 29 'test.tiff'
YMMV :-D
If you dont want to store the image as a file, take a look at ffmpeg-php
http://ffmpeg-php.sourceforge.net/
$movie->getFrame([Integer framenumber])
Returns a frame from the movie as an ffmpeg_frame object.
$frame->toGDImage()
Returns a truecolor GD image of the frame.
There may be C code underneath you can reuse..