Gdal and opencv2.x Data conversion (for multi-channel remote sensing imagery such as multispectral and hyperspectral)

Source: Internet
Author: User

First, preface

Gdal has a powerful image reading and writing function, but the integration of common image processing algorithms is less, OPENCV just has a strong image processing ability, so the effective combination of both the image (remote sensing image) processing brought great convenience. So how to realize the data exchange between Gdal and OpenCV becomes the key step in image processing. Next I'll record: 1 How do I convert an image read from gdal to a OPENCV supported mat format? 2 How do I convert the post-processing mat data to the appropriate image format for storage? (PS: I am also the first to use Gdal and OpenCV, code is very water ... Just record what you learned, and communicate with you.

Second, gdal data to OpenCV's Mat format

About Gdal data to OPENCV format conversion, online already have some resources, but mostly for single or three-channel data, the multi-channel image (Multispectral and hyperspectral images of remote sensing) conversion is not much, say not much, first on the code:

 1 Cv::mat gdal2mat (const QString fileName) 2 {3 gdalallregister (); Registered... 4 Gdaldataset *podataset = (Gdaldataset *) Gdalopen (filename.tostdstring (). C_STR (), ga_readonly); 5 int tmpcols = Podataset->getrasterxsize (); 6 int tmprows = Podataset->getrasterysize (); 7 int tmpbandsize = Podataset->getrastercount (); 8 Double *tmpadfgeotransform = new Double[6];  9 Podataset->getgeotransform (tmpadfgeotransform), Qvector <cv::Mat> Imgmat;   Each band is a float *pafscan = new Float[tmpcols*tmprows]; storing data for (int i = 0;i< tmpbandsize;i++) {Gdalrasterband *pband = Podataset->getrasterban D (i+1);//pafscan = new float[tmpcols*tmprows];18 Pband->rasterio (Gf_read,0,0,tmpcols,tmprows,pafscan , tmpcols,tmprows,gdt_float32,0,0); Cv::mat Tmpmat = Cv::mat (TMPROWS,TMPCOLS,CV_32FC1, Pafscan); Imgmat.push_back (Tmpmat.clone ());}23 Delete []pafscan;24 Pafscan = null;25 cv::mat img;27 img.create (TMPROWS,TMPCOLS,CV_32FC (tmpbandsize)); Cv::merge (i Mgmat.tostdvector (), IMG); imgmat.clear (); Gdalclose ((Gdaldataseth) podataset); return img;32}

The idea is to get its gdaldataset data set according to the file name, then divide the band (band equivalent channel) in the format of the Vector<cv::mat> container, and finally use the Mat's merge function to combine the channel data. The above method is suitable for arbitrary band data, and is more practical for multi-channel imagery, such as multispectral and hyperspectral data in remote sensing images. However, there is a problem: the red part of the code, the purpose is to release podataset memory, but always error, comment after there is no problem, do not know why, which warrior if know why and also happen to pass here, please give help, thank you! (problem solved, gdaldataset data set can not release the pointer of each band, otherwise error, code has been modified, the same)

Third, the mat format data into Gdal data set format and save the appropriate file

The idea is the inverse process of the second part above. First, create a data set and file driver, according to the relevant parameters to create a file, and the multi-channel mat data through the Cv::split function for channel separation, and finally the channel data and the Gdal data set of the band data corresponding to write to the data set. The code is as follows:

 1 bool Mat2file (cv::mat img, const QString fileName) 2 {3 if (Img.empty ())//Determine if NULL 4 return 0; 5 6 const int Nbandcount=img.channels (); 7 const int Nimgsizex=img.cols; 8 const int Nimgsizey=img.rows; 9 10//Separate channel//Imgmat per channel data continuous std::vector<cv::mat> Imgmat (nbandcount); Cv::split (img,img   Mat); 14 15//Sub-band write file Gdalallregister (); Gdaldataset *podataset;      Gdal data set Gdaldriver *podriver;         Driver, used to create a new file Podriver = Getgdaldrivermanager ()->getdriverbyname ("ENVI"); if (podriver = NULL) 22                                 Return 0;23 podataset=podriver->create (filename.tostdstring (). C_STR (), nimgsizex,nimgsizey,nbandcount,24 Gdt_float32,null); 25//Loop Write file Gdalrasterband *pband = null;27 float *ppafscan = new float[nimgsizex*nimgsizey];28 Cv::mat tmpmat;//= Cv::mat (NIMGSIZEY,NIMGSIZEX,CV_32FC1); int n1 = NImgSizeY;3 1 int NC = nimgsizex;32 33 for (int i = 1;i<=nbandcount;i++) {Pband = Podataset->getrasterband (i); Tmpmat = img          mat.at (i-1); PNs if (tmpmat.iscontinuous ()). {N1 NC = n1*nc;40 1;41 for (int r = 0;r<n1;r++) $ {Tmpi int = r*nimgsizex;45 float *p = tmpmat.ptr&             Lt;float> (R); +/-(int c = 0;c<nc;c++) ~ {Ppafscan[tmpi+c] = p[c];49 }50}51 Pband->rasterio (gf_write,0,0,nimgsizex,nimgsizey,ppafscan,52 n      imgsizex,nimgsizey,gdt_float32,0,0);}54 delete []ppafscan;55 Ppafscan = null;56 gdalclose (podataset); 57 Return 1;58}
 choosesample::mat2file bool (std::vector<cv::mat> imgmat, const QString fileName) (Imgmat.empty ()) Determine if the empty qmessagebox::information (this, "Message Error", "Data null!"); 0; Nbandcount=imgmat.size (); a const int nimgsizex=imgmat[0].cols; + const int nimgsizey=imgmat[0].rows; 71 72//Sub-band write file Gdalallregister ();   Gdaldataset *podataset;      Gdal data set Gdaldriver *podriver; Driver, used to create a new file Podriver = Getgdaldrivermanager ()->getdriverbyname ("ENVI"); if (Podriver = = NULL) return 0;                                 Podataset=podriver->create (Filename.tostdstring () c_str (), Nimgsizex,nimgsizey,nbandcount, 81 Gdt_float32,null); 82//Loop Write file Gdalrasterband *pband = NULL; *ppafscan float = new Float[nimgsizex*nimgsizey]; Cv::mat tmpmat;//= Cv::mat (NIMGSIZEY,NIMGSIZEX,CV_32FC1); N1 int = NImGsizey; Nimgsizex int NC =;       for (int i = 1;i<=nbandcount;i++), Pband = Podataset->getrasterband (i); Tmpmat = imgmat.at (i-1);         94 if (Tmpmat.iscontinuous ()) ()-------------N1*NC; 98} 99 for (int r = 0;r<n1;r++), {101 int tmpi = r*nimgsizex;102 float *p = tmpmat.ptr<f             Loat> (R); 103 for (int c = 0;c<nc;c++) 104 {Ppafscan[tmpi+c] = p[c];106                         }107}108 Pband->rasterio (gf_write,0,0,nimgsizex,nimgsizey,ppafscan,109 nimgsizex,nimgsizey,gdt_float32,0,0);}111 delete []ppafscan;112 Ppafscan = null;113 Gdalclose (poData set); return 1;115}

Similarly, the problem is that whenever you release memory, you will get an error (red font in the code). In addition, there is a small detail problem with the Cv::split function, as follows:

1     //    separate Channel 2     //  Imgmat per channel data 3     std::vector<cv::mat> Imgmat (nbandcount); 4     CV:: Split (Img,imgmat); 5 6     //  Imgmat 7     qvector<cv::mat> Imgmat (nbandcount) per channel data, 8     CV:: Split (Img,imgmat.tostdvector ());

Gdal and opencv2.x Data conversion (for multi-channel remote sensing imagery such as multispectral and hyperspectral)

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.