The answer to the question is there's no need to convert the data to a bitmap format at run time. You can pass the data obtained by the
RasterIO function to your opencv functions.
This question is for when I worked in a company as an apprentice. The time when I didn't know anything about GDAL. So I've asked the question generally and it did not receive much attention.
Here I give some guidelines about GDAL functions in a hypothetical project and the next visitors of the question should ask their own specific questions here or in other stackexchange sites like stackoverflow or game developement.
Because operations like panning and zooming is not related to GDAL library at all. It's related to OpenGL or other Graphical interfaces you have chosen for your project.
Suppose that you have a project where you should open and show a geotiff image, do some image processing operations on it and then save the result.
First of all for opening the geotiff file you should create a pointer to object of the class
GDALDataset like the following.
Create these variables to store different characters of this data set like the digital numbers of the pixels, etc.
To open the file call the
GDALOpen and store the address of the returned variable in your
poDataset = (GDALDataset*)GDALOpen(ascii.m_psz,GA_ReadOnly);
Now you can obtain various characteristics of the data from this pointer:
RasterXSize = poDataset -> GetRasterXSize();
RasterYSize = poDataset -> GetRasterYSize();
RasterCount = poDataset -> GetRasterCount();
poRasterBand = poDataset -> GetRasterBand(1);
eType = poRasterBand -> GetRasterDataType();
BytesPerPixel = GDALGetDataTypeSize(eType)/8;
To read the header of geotiff you should call various functions on this pointer. Here I've added the code for a function that uses GDAL library to read the header of geotiff and returns the information as a string which you can display in the console or in a text box on your MFC dialog.
char* bufferTitle = "Image header information:\n";
char* buffer1 = new char;
char* buffer2 = new char;
sprintf(buffer2,"Size is %dx%dx%d\n",poDataset->GetRasterXSize(),poDataset->GetRasterYSize(),poDataset->GetRasterCount());
char* buffer3 = new char;
if( poDataset->GetProjectionRef()!= NULL )
sprintf(buffer3,"Projection is `%s'\n",poDataset->GetProjectionRef());
buffer3 = "Projection is not specified.\n";
char* buffer4 = new char;
char* buffer5 = new char;
char* buffer6 = new char;
if( poDataset->GetGeoTransform( adfGeoTransform ) == CE_None )
sprintf(buffer4,"Origin = (%.6f,%.6f)\n",adfGeoTransform,adfGeoTransform);
sprintf(buffer5,"Pixel Size = (%.6f,%.6f)\n",adfGeoTransform,adfGeoTransform);
sprintf(buffer6,"Rotation relative to north = (%.6f,%.6f)\n",adfGeoTransform,adfGeoTransform);
buffer4 = "Geotransform parameters are not specified.";
CString StringbufferTitle = TbufferTitle.m_psz;
CString Stringbuffer1 = Tbuffer1.m_psz;
CString Stringbuffer2 = Tbuffer2.m_psz;
CString Stringbuffer3 = Tbuffer3.m_psz;
CString Stringbuffer4 = Tbuffer4.m_psz;
CString Stringbuffer5 = Tbuffer5.m_psz;
CString Stringbuffer6 = Tbuffer6.m_psz;
CString headerInfo = StringbufferTitle + Stringbuffer1 + Stringbuffer2 + Stringbuffer3 + Stringbuffer4 + Stringbuffer5 + Stringbuffer6;
Now read the DNs of pixels and store it in the vector that you created earlier:
pRasterData.resize(RasterXSize * RasterYSize * RasterCount * BytesPerPixel);
CPLErr error = poDataset -> RasterIO(GF_Read,0,0,RasterXSize,RasterYSize,&pRasterData,RasterXSize,RasterYSize,eType,RasterCount,0,0,0,0);
Notice the declaration of the
RasterIO function, you will store the data in an array which is passed as a pointer to the function. This is a common operation in C++ language. You will use this vector of data in the next step where you should apply a Gaussian filter to the image with the help of OpenCV library.
Create two instances of the class
Mat in OpenCV and use the information you obtained above to store image data in one of these instances. Apply the filter and store the result in an array:
OpenCVGaussian = img2.reshape(1,1);
pRasterDataOut = OpenCVGaussian;
As you see there's no need to convert the data to a bitmap to be able to manipulate it in OpenCV. You can pass the data obtained by GDAL library as an array to the OpenCV library and use the functionalities of both libraries.
You can now assign the vector generated by the
OpenCVGaussian function to another pointer of the class
GDALDataset and store the data in a file. Finally you can close both files.
First of all create a geotiff format file and open it a writable to be able to write the data on it
const char *fileFormat = "GTiff";
poDriver = GetGDALDriverManager()->GetDriverByName(fileFormat);
pofileMetadata = poDriver->GetMetadata();
CT2A ascii( filepath );
char **pofileOptions = NULL;
poDatasetOut = poDriver->Create( ascii.m_psz, RasterXSize, RasterYSize, RasterCount, eType, pofileOptions );
pass the pointer to the vector
poRasterDataOut to the
RasterIO called on the pointer
poDatasetOut of the class
GDALDataset created earlier by the
Create function of the class
CPLErr error = poDatasetOut -> RasterIO(GF_Write,0,0,RasterXSize,RasterYSize,&pRasterDataOut,RasterXSize,RasterYSize,eType,RasterCount,0,0,0,0);
Write the header of this file by calling functions like
SetProjection on this output pointer of the class
GDALDataset and finally close the two files
GDALClose( (GDALDatasetH) m_saveFiles.poDatasetOut);
GDALClose( (GDALDatasetH) m_openFiles.poDataset);
Remember to add the following in the initialization code of your MFC Dialog to be able to use GDAL library.
To add functionalities like zoom in, zoom out, pan, full extent to your program, you should be able to work with the OpenGL library. To start I recommend the class Setting Up OpenGL in an MFC Control. Use your programming knowledge and customize this class for your own needs.
Use your object oriented programming knowledge to connect objects of three major classes
- A class of OpenGL library for displaying capabilities
- A class of OpenCV library for manipulating capabilities
- A class of GDAL library for reading and writing data from and to
in your program and add fantastic functionalities to your software.
Here's the code of a class used to set up OpenGL in MFC control