参考:
1、https://docs.opencv.org/3.2.0/
其中m1 参考:http://blog.csdn.net/wc781708249/article/details/78394933
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
数据:遥感图像 16bit 4波段
对应opencv数据格式为CV_16UC4,转成float32对应的数据格式为CV_32FC4
操作:滤波操作
"""
from scipy import ndimage
try:
from osgeo import gdal
except:
import gdal
import gdalnumeric
from osgeo.gdalconst import *
import numpy as np
from datetime import datetime
import m1
import cv2
start_time=datetime.now()
# 为了支持中文路径,请添加下面这句代码
gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8","NO")
gdal.AllRegister() #注册驱动
img1_path="D:/test.tiff"
img=m1.Multiband2Array(img1_path)
raster_fn="D:/test_2.tif"
# 各种滤波处理
dst=cv2.blur(img,(15,15)) # 均值滤波 可以处理CV_32FC4
dst=cv2.GaussianBlur(img,(5,5),0) # 高斯滤波 可以处理CV_32FC4
dst=cv2.medianBlur(img,5) # 中值滤波 可以处理CV_32FC4
# 双边过滤 只能处理CV_32FC3数据 只取前3个波段处理,处理CV_32FC4报错
dst=cv2.bilateralFilter(img[:,:,:-1],9,75,75)
src_ds = gdal.Open(img1_path,GA_ReadOnly)
geoTrans = src_ds.GetGeoTransform()
srcPro = src_ds.GetProjection()
src_ds=None
# 输出影像
target_ds = gdal.GetDriverByName('GTiff').Create(raster_fn, dst.shape[1], dst.shape[0], dst.shape[2], gdal.GDT_UInt16)
target_ds.SetGeoTransform(geoTrans) # 设置掩膜的地理参考
target_ds.SetProjection(srcPro) # 设置掩膜坐标引用
# target_ds.GetRasterBand(1).WriteRaster(0,0,img.shape[1],img.shape[0],img.tobytes())
[target_ds.GetRasterBand(i+1).WriteArray(dst[:,:,i],0,0) for i in range(dst.shape[2])]
target_ds.FlushCache()
target_ds=None
end_time=datetime.now()
print((end_time-start_time).total_seconds())
参考:http://blog.csdn.net/wc781708249/article/details/78479584
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include
#include
#include
#include
#include
using namespace std;
using namespace cv;
//创建一个存放影像信息的structure
typedef struct
{
//GDALDataset *poDataset = NULL;
int Xsize = 0;
int Ysize = 0;
int nbands = 0;
double *tmpadfGeoTransform = new double[6]; //存储地理6参数
const char* proj = NULL;//存储投影
GDALDataType iDataType = GDT_Byte;
}MyStruct;
cv::Mat GDAL2Mat(GDALDataset *poDataset, MyStruct &St);
bool Mat2File(cv::Mat img, MyStruct &St, GDALDataset *poDataset);
int main()
{
//注册驱动
GDALAllRegister();
string src_path = "D:/test.tiff";
string dst_path = "D:/test_2.tif";
MyStruct St;
GDALDataset *srcDataset = (GDALDataset *)GDALOpen(src_path.c_str(), GA_ReadOnly);
St.Xsize = srcDataset->GetRasterXSize();
St.Ysize = srcDataset->GetRasterYSize();
St.nbands = srcDataset->GetRasterCount();
srcDataset->GetGeoTransform(St.tmpadfGeoTransform);
St.proj = srcDataset->GetProjectionRef();
//获取数据类型
St.iDataType = srcDataset->GetRasterBand(1)->GetRasterDataType();
//影像转Mat
Mat img = GDAL2Mat(srcDataset, St);
//判断是否加载成功
if (!img.data) //或者image.empty()
{
cout << src_path << " cannot open!" << endl;
return -1;
}
//
/*各种滤波处理*/
Mat dst;//输出Mat
//如果将数据转成CV_32FC4,再滤波会出现问题(Python中却不会)
blur(img, dst, Size(5, 5), Point(-1, -1)); //均匀滤波
GaussianBlur(img, dst, Size(5, 5), 0, 0); //高斯滤波
medianBlur(img, dst, 5); //中值滤波
//bilateralFilter(img, dst, 3, 3 * 2, 3 / 2);//双边滤波
//注:输入数据的格式CV_16UC4
//Bilateral filtering is only implemented for 8u and 32f images
img.convertTo(dst, CV_32FC4); //转成32F类型
bilateralFilter(dst, dst, 3, 3 * 2, 3 / 2);//双边滤波
//src.type() == CV_32FC1 || src.type() == CV_32FC3
//可以取前3个波段使用双边滤波处理
/
//定义输出数据
GDALDataset *dstDataset; //GDAL数据集
GDALDriver *poDriver; //驱动,用于创建新的文件
//poDriver = GetGDALDriverManager()->GetDriverByName("ENVI");
poDriver = GetGDALDriverManager()->GetDriverByName("GTiff");
if (poDriver == NULL)
return 0;
dstDataset = poDriver->Create(dst_path.c_str(), St.Xsize, St.Ysize, St.nbands,
St.iDataType, NULL);//GDT_Float32
//重新设置地理参考和投影系
dstDataset->SetGeoTransform(St.tmpadfGeoTransform);
dstDataset->SetProjection(St.proj);
GDALClose((GDALDatasetH)srcDataset);
//保存Mat到影像
Mat2File(dst, St, dstDataset);
GDALClose((GDALDatasetH)dstDataset);
return 0;
}
//GDAL数据转opencv的Mat格式
cv::Mat GDAL2Mat(GDALDataset *poDataset, MyStruct &St) //const QString fileName
{
//获取数据类型
//GDALDataType iDataType = poDataset->GetRasterBand(1)->GetRasterDataType();
//int idepth = GDALGetDataTypeSize((GDALDataType)iDataType);
//将GDAL的数据类型与Mat的数据类型对应起来
auto MdataType = NULL;
auto MdataTypes = NULL;
if (St.iDataType == GDT_Byte)
{
MdataType = CV_MAKETYPE(CV_8U, 1);
MdataTypes = CV_MAKETYPE(CV_8U, St.nbands);
}
if (St.iDataType == GDT_UInt16)
{
MdataType = CV_MAKETYPE(CV_16U, 1);
MdataTypes = CV_MAKETYPE(CV_16U, St.nbands);
}
//QVector imgMat;
vector imgMat;// 每个波段
float *pafScan = new float[St.Xsize*St.Ysize]; // 存储数据
for (int i = 0; i< St.nbands; i++)
{
GDALRasterBand *pBand = poDataset->GetRasterBand(i + 1);
//pafScan = new float[tmpCols*tmpRows];
pBand->RasterIO(GF_Read, 0, 0, St.Xsize, St.Ysize, pafScan,
St.Xsize, St.Ysize, St.iDataType, 0, 0); //GDT_Float32
cv::Mat tmpMat = cv::Mat(St.Ysize, St.Xsize, MdataType, pafScan);//CV_32FC1
imgMat.push_back(tmpMat.clone());
}
delete[]pafScan;
pafScan = NULL;
cv::Mat img;
img.create(St.Ysize, St.Xsize, MdataTypes);// CV_32FC(St.nbands)
//cv::merge(imgMat.toStdVector(), img);
cv::merge(imgMat, img);
//释放内存
imgMat.clear();
//GDALClose((GDALDatasetH)poDataset);
return img;
}
//Mat 数据保存成影像
bool Mat2File(cv::Mat img, MyStruct &St, GDALDataset *poDataset)//const QString fileName
{
if (img.empty()) // 判断是否为空
return 0;
const int nBandCount = St.nbands;
const int nImgSizeX = St.Xsize;
const int nImgSizeY = St.Ysize;
// 将通道分开
// imgMat每个通道数据连续
std::vector imgMat(nBandCount);
cv::split(img, imgMat);
// 分波段写入文件
GDALAllRegister();
// 循环写入文件
GDALRasterBand *pBand = NULL;
float *ppafScan = new float[nImgSizeX*nImgSizeY];
cv::Mat tmpMat;// = cv::Mat(nImgSizeY,nImgSizeX,CV_32FC1);
for (int i = 1; i <= nBandCount; i++)
{
pBand = poDataset->GetRasterBand(i);
tmpMat = imgMat.at(i - 1);
if (tmpMat.isContinuous())
{
if (St.iDataType == GDT_Byte)
memmove(ppafScan, (void*)tmpMat.ptr(0), sizeof(unsigned char)*nImgSizeX*nImgSizeY);//GDT_Byte
if (St.iDataType == GDT_UInt16)
memmove(ppafScan, (void*)tmpMat.ptr(0), sizeof(unsigned short)*nImgSizeX*nImgSizeY);//GDT_Uint16
//memmove(ppafScan, (void*)tmpMat.ptr(0),sizeof(float)*nImgSizeX*nImgSizeY);//GDT_Float32
}
else
return false;
CPLErr err = pBand->RasterIO(GF_Write, 0, 0, nImgSizeX, nImgSizeY, ppafScan,
nImgSizeX, nImgSizeY, St.iDataType, 0, 0);
}
delete[] ppafScan;
ppafScan = NULL;
imgMat.clear();
//GDALClose(poDataset);
return 1;
}