Gdal read/write image segmentation (excellent Edition)

Source: Internet
Author: User

Use gdal to define the projection Coordinate System

 

Gdal raster vectoring (reproduced) gdal read/write image block processing (excellent edition) (reproduced)

/* Copyright holder: Zhao Wen */

Reprinted from http://hi.baidu.com/sheefeng/blog/item/90612550c0ac144cd009065a.html

1. gdal Data Operations
After gdal is installed, you can call the functions in the gdal library.
(Header file to be included: gdal_priv.h)
1. Open a dataset
The first step in using the gdal database for data (image) operations is to open a dataset. You may not get used to the term "dataset", but in general format, a "dataset" is a file. For example, a TIFF file is a file with the tiff extension. However, for a large number of RS data, a dataset contains more than just a file. For a lot of RS data, they divide an image into several image files and put them in a folder to organize the relationship between them with some additional files, form a "dataset" (this is a bit difficult to understand and can be left blank for the time being ). Next we open a tiff (geotiff) file by the given file path file name. (This is the way to open any supported formats)

Cstring strfilepath;
Strfilepath = 'd:/rsdata/2005_234.tif ';
Gdaldataset * podataset; // gdal Dataset
Gdalallregister ();
Podataset = (gdaldataset *) gdalopen (strfilepath, ga_readonly );

In this way, the file is opened. You can use the dataset podataset to call various function functions, such:
Getrastercount (); // obtain the number of image bands;
Getrasterxsize (); // get the Image Width
Getrasterysize (); // get the Image Height
Getrasterband (); // obtain an image in a certain band
Getgeotransform (double * P); // obtains an array of six geographic coordinates of an image.
Rasterio (); // scale, read, and write image data.
......
(For more details about the API list, see here ).

2. Get image information and read image
After opening the file, you need to get the information of the file and save it in the corresponding variable. Read the image data into the memory and wait for subsequent processing.

2.1 obtain basic information
Because different formats of data contain different information, we usually need to obtain the image height, width, band number, geographic coordinate information, data type, and so on. The gdal library has corresponding functions to implement these functions. The following code retrieves the information:

Int nbandcount = podataset-> getrastercount ();
Int nimgsizex = podataset-> getrasterxsize ();
Int nimgsizey = podataset-> getrasterysize ();
Double adfgeotransform [6];
Podataset-> getgeotransform (adfgeotransform );
// If the image does not contain geographical coordinates, the default return value is: (0, 1, 0, 0, 0, 1 ), the fourth column in the table indicates the data format with // geographic coordinate information.
// Adfgeotransform [0] is the east coordinate of the pixel in the upper left corner;
// Adfgeotransform [3] is the north coordinate of the pixel in the upper left corner;
// Adfgeotransform [1] indicates the pixel width;
// Adfgeotransform [5] is the pixel height;
// Coordinate calculation formula for other image points:
// XP = adfgeotransform [0] + p * adfgeotransform [1] + L * adfgeotransform [2];
// Yp = adfgeotransform [3] + p * adfgeotransform [4] + L * adfgeotransform [5];
// Note: Using getgeotransform () does not reasonably represent the geographical coordinates of an image. When the image range is large
//, This coordinate representation method will not apply.

2.2 read image data into memory as required
Image read/write is implemented through rasterio. Rasterio () is very powerful. It can output or input the specified rectangular pixel block on the image to the user-specified buffer in the form of scaling according to the specified data type.
Prototype:
Cplerr gdaldataset: rasterio (
Gdalrwflag erwflag, // If the read/write flag is gf_read, the image content is written into the memory. If
// If it is gf_write, the content in the memory is written to the file.
Int nxoff, int nyoff, // The row and column offset relative to the vertex (starting from scratch) in the upper left corner of the image
Int nxsize, int nysize, // number of pixels in the X direction of the block to be read and written, and number of pixel columns in the Y direction
Void * pdata, // pointer to the target buffer, allocated by the user
Int nbufxsize, int nbufysize, // the size of the target block in the X and Y directions
Gdaldatatype ebuftype, // data type of the target buffer. The original type is automatically converted to the target type.
Int nbandcount, // Number of bands to process
Int * panbandmap, // record the array of the band index to be operated (band index starts from 1), if it is null
// The index of the first nbandcount band is stored in the array.
Int npixelspace, // The Byte offset between two adjacent pixels in the X direction. The default value is 0,
// The actual byte offset between columns is determined by the target data type ebuftype.
Int nlinespace, // The Byte offset between two adjacent lines in the Y direction. The default value is 0, then the actual bytes in the line
// The offset is ebuftype * nbufxsize
Int nbandspace // The Byte offset between two adjacent bands. The default value is 0, which means that the band is a sequential structure.
//, During which the byte offset is nlinespace * nbufysize
);
The following uses an example to demonstrate how to use it. What we can do is to read the 2nd, 3, 4, and 4 bands in a 7-band image into the memory in the order of 3, 4, and 2, and store them by Pixel:
Int bandmap [7];
Bandmap [0] = 3;
Bandmap [1] = 4;
Bandmap [2] = 2;
Scanline = (nimagsizex * 8 + 31)/32*4;
Byte pafscan = (byte) cplmalloc (sizeof (byte) * nimgsizex * nimgsizey * 3)
Podataset-> rasterio (gf_read, 0, 0, nimgsizex, nimgsizey, pafscan,
Nimgsizex, nimgsizey, gdt_byte, 3, bandmap, 3, scanline * 3, 1 );

After reading in this way, you can directly build bitmap for display. You can perform other read operations as needed. The preceding reading method is only for ease of display. For example, if image processing is performed, it is more convenient to read all data in the band:
Podataset-> rasterio (gf_read, 0, 0, nimgsizex, nimgsizey, pafscan,
Nimgsizex, nimgsizey, gdt_byte, bandcount, 0, 0, 0 );
Previously opened memory changed:
Byte pafscan = new byte [nimgsizex * nimgsizey * bandcount];

After reading the image data into the memory, you can use the pointer pafscan to perform the operations you want on the image.

3. save another image
Another method of saving a file is to create a new file and then write the data to the new file.
There are two ways to create a new file using gdal: Create () and createcopy (); some file formats support the CREATE () function (see the third column of the table on the first page), you can use create () directly create files in this format. For other image formats that do not support the CREATE () function, you must first create a TIFF file and then copy and generate a target file.
Cstring strfilepath1; // enter the path name of the image file
Cstring strfilepath2; // save it as the TIFF Format Image path
Cstring strfilepath2; // save as the JPEG image path
Gdaldataset * podataset1; // gdal Dataset
Gdaldataset * podataset2; // The gdal dataset to be created
Gdaldataset * podataset2; // The gdal dataset to be created
Gdaldriver * podriver; // driver, used to create a new file
Gdalallregister ();
Podataset1 = (gdaldataset *) gdalopen (strfilepath1, ga_readonly );
// Open the file
If (podataset1 = NULL)
{
Afxmessagebox ("file opening failed !!! ");
M_fileflag = false;
Return;
}
// Create a new TIFF file using the create method:
Nbandcount = podataset1-> getrastercount ();
Nimgsizex = podataset1-> getrasterxsize ();
Nimgsizey = podataset1-> getrasterysize ();
// Obtain image-related information

// Create a new file
Cstring fomat;
Fomat = "gtiff"
Podriver = getgdaldrivermanager ()-> getdriverbyname (fomat );
// Set the file type. The second column of the table is the format identifier. Save it as another lattice and change the fomat value.

// Obtain the format type
Char ** papszmetadata = podriver-> getmetadata ();

// Create a new dataset Based on the file path file name, image width, height, band number, data type, file type
Podataset2 = podriver-> Create (strfilepath2, nimgsizex, nimgsizey, nbandcount, gdt_byte, papszmetadata );
// Coordinate assignment
Double adfgeotransform [6] = {0, 0, 0, 0 };
Podataset2-> setgeotransform (adfgeotransform );

// Read the original image data and write it into a new file
Byte * ppafscan = new byte [nimgsizex * nimgsizey * nbandcount];
Podataset1-> rasterio (gf_read, 0, 0, nimgsizex, nimgsizey, ppafscan,
Nimgsizex, nimgsizey, gdt_byte, nbandcount, 0, 0, 0 );
.
.
"Processing images in the middle 』
.
// Write image data into the new image
Podataset2-> rasterio (gf_write, 0, 0, nimgsizex, nimgsizey,
Ppafscan, pafsizex, pafsizey, gdt_byte, nbandcount, 0, 0, 0 );

Delete podataset2;
Delete podriver;
// Save the image.

Create a jpeg file using createcopy:
In the following process, do not delete the image (that is, you have already created an image in TIFF format using the create method)
Fomat = "Jpeg"
Podriver = getgdaldrivermanager ()-> getdriverbyname (fomat );
Podataset3 = podriver-> createcopy (strfilepath3, podataset2, 1, papszmetadata, null, null );
Delete podataset3;
Delete podataset2;
Delete podriver;

Ii. Use rasterio () to block large images
The rasterio () function can read data in any band in any specified area of the image in a specified data type and arrange the data in a specified manner into the memory and write the data into the file. Therefore, you can read the large image in blocks, operation and write operation. For large image processing, according to the traditional method, first read all the image data into the memory, perform the corresponding operation, and then write the processed data into the file at a time, this requires a large amount of memory, which is prone to memory overflow and poor execution performance. Using Block Processing Technology, a 1g image can only occupy dozens of megabytes of memory during the entire data processing process, and the computing workload will not increase. The following is an example:
/Example of processing all band segments
Void ctestzwdoc: onlowers ()
{
Inoutput DLG; // dialog box for obtaining the file path
If (DLG. domodal () = idcancel)
{
Return;
}
Cstring strfilepath1 (DLG. m_input );
Cstring strfilepath2 (DLG. m_output );
Gdaldataset * podataset1; // gdal Dataset
Gdaldataset * podataset2; // gdal Dataset
Gdaldriver * podriver;
Gdalallregister ();

Podataset1 = (gdaldataset *) gdalopen (strfilepath1, ga_readonly );
If (podataset1 = NULL)
{
Afxmessagebox ("file opening failed !!! ");
M_fileflag = false;
Return;
}
Int bandcount = podataset1-> getrastercount ();
Int nimgsizex = podataset1-> getrasterxsize ();
Int nimgsizey = podataset1-> getrasterysize ();

// Create a new file
Cstring format;
Format = "gtiff ";
Podriver = getgdaldrivermanager ()-> getdriverbyname (format );
Char ** papszmetadata = podriver-> getmetadata ();
Podataset2 = podriver-> Create (strfilepath2, nimgsizex, nimgsizey, nbandcount, gdt_byte, papszmetadata );
// Set the image coordinates. If this step is missing, the created image cannot be opened with ERDAS.
Podataset2-> setgeotransform (adfgeotransform );
//////////////////////////////////////// /////////////
// Block Processing. Divide the image into many blocks of 512*512 size and process each block cyclically.
Int nxnum = (nImgSizeX-1)/512 + 1; // calculates the number of upper blocks in the column direction
Int nynum = (nImgSizeY-1)/512 + 1; // calculates the number of rows
Int pafsizex; // current block width
Int pafsizey; // current block height
Byte * LP;
Byte * ppafscan = new byte [512*512 * nbandcount];
For (INT Nyi = 0; Nyi <nynum; Nyi ++)
For (INT nxi = 0; nxi <nxnum; nxi ++)
{
Pafsizex = 512;
Pafsize= 512;
// Process small pieces at the end of the row or column
If (nxi = nxNum-1) pafsizex = (nImgSizeX-1) % 512 + 1;
If (NYI = nyNum-1) pafsizey = (nImgSizeY-1) % 512 + 1;
// Read the current block data
Podataset1-> rasterio (gf_read, nxi * 512, Nyi * 512, pafsizex,
Pafsizey, ppafscan, pafsizex, pafsizey, gdt_byte, bandcount, 0, 0, 0 );
// Process the current block and extract the edge
For (INT nnum = 0; nnum <nbandcount; nnum ++)
For (INT I = 0; I <pafsizey; I ++)
For (Int J = 0; j <pafsizex; j ++)
{
{
Lp = ppafscan + nnum * pafsizex * pafsizey + I * pafsizex + J;
If (j = pafsizex-1 & I! = Pafsizey-1)
* Lp = ABS (* Lp-* (LP + pafsizex ));
Else if (I = pafsizey-1 & J = pafsizex-1)
* Lp = 0;
Else if (I = pafsizey-1 & J! = Pafsizex-1)
* Lp = ABS (* Lp-* (LP + 1 ));
Else * Lp = ABS (* LP)-* (LP + 1) + ABS (* Lp-* (LP + pafsizex ));

// Edge processing is difficult
If (* LP <15)
* LPP = 0;
Else if (15 <= * LPP <30)
* Lpp= 128;
Else if (* LPP> = 30)
* Lpp= 255;
}
}
// Write the current block data to the corresponding position of the new image
Podataset2-> rasterio (gf_write, nxi * 512, Nyi * 512, pafsizex, pafsizey, ppafscan, pafsizex, pafsizey, gdt_byte, nbandcount );
}
Delete [] ppafscan;
// After the write operation is complete, it must be released. Otherwise, the write operation fails.
Delete podataset2;
Delete podataset1;
Delete podriver;
Delete DLG;
}

In the previous article about reading and storing images in the gdal library, there are many shortcomings. I personally think it is best to create a bitmap in the memory and display it quickly.
The Byte offset between two adjacent pixels. If it is stored by band, it is set to 0.
Row offset. If it is stored by band, it is set to 0.
1-pixel storage, 0-band storage

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.