zoukankan      html  css  js  c++  java
  • 【GDAL】图像处理三:图像平滑(一)

    目的:读取一幅图像中的一个波段,对其进行平滑,采用8邻域。

    遇到一个问题,没有想好怎么解决。如下:

    1.完整代码:

    #include <gdal.h>
    #include <gdal_priv.h>
    #include <iostream>
    #include <fstream>
    
    using namespace std;
    typedef unsigned char BYTE;
    
    int main()
    {
    	//打开图像
    	GDALDataset *poDataset;
    	GDALAllRegister();
    	poDataset = (GDALDataset *) GDALOpen( "test.bmp", GA_ReadOnly );
    	if( poDataset == NULL ) 
    	{
    		cout<<"nothing"<<endl;
    	}
    
    	//获取一个光栅波段
    	GDALRasterBand *poBand; 
    	poBand = poDataset->GetRasterBand( 1 ); 
    	cout<<"DataType编号"<<poBand->GetRasterDataType()<<endl;
    	cout<<"Color Interpretation:	"<<poBand->GetColorInterpretation()<<endl;
    	cout<<"Color Interpretation:	"<<GDALGetColorInterpretationName(poBand->GetColorInterpretation())<<endl;
    
    	int nImgSizeX = poDataset->GetRasterXSize();		//横向像元个数
    	int nImgSizeY = poDataset->GetRasterYSize();		//纵向像元个数
    	int bandcount = poDataset->GetRasterCount();		//波段数
    	BYTE *pafScan  = new BYTE[nImgSizeX * nImgSizeY];	//指向存储数据,一个波段
    	
    	poBand->RasterIO( GF_Read, 0, 0, nImgSizeX, nImgSizeY,
    					  pafScan, nImgSizeX, nImgSizeY, GDT_Byte, 0, 0);//将一个波段存入pafScan
    	
    	//Create
    	GDALDataset *poDstDS;
    	const char	*pszFormat = "BMP";
    	GDALDriver	*poDriver;
    	poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat); //获取驱动
    	if( poDriver == NULL ) 
    		exit( 1 );
    
    	poDstDS = poDriver->Create( "res.bmp", nImgSizeX, nImgSizeY, 1, GDT_Byte, NULL);//创建一个波段的图像
    	
    	//处理图像
    	float sumGray = 0;//灰度值之和
    	for(int i=1; i< nImgSizeY-1; i++)	//中心点不包括外面一层
    	{
    		for(int j=1; j<nImgSizeX-1; j++)
    		{
    			//----------搜索八邻域begin----------
    			for(int k=-1; k<2; k++)
    			{
    				for(int l=-1; l<2; l++)
    				{
    					sumGray += pafScan[(i+k)*nImgSizeX + (j+l)];
    				}
    			}
    			//----------搜索八邻域end----------
    			
    			
    			pafScan[i*nImgSizeX + j] =sumGray / 9.0;
    		}
    	}
    	
    	//分波段存入
    	poDstDS->GetRasterBand(1)->RasterIO( GF_Write, 0, 0,  nImgSizeX, nImgSizeY,
    										 pafScan, nImgSizeX, nImgSizeY, GDT_Byte, 0, 0);//将缓存pafScan中的数据存入结果图像的波段1中
    	
    	
    	//释放空间
    	if( poDstDS != NULL )	
    		delete poDstDS;
    	if(poDataset != NULL )
    		delete poDataset;
    }

    但是输出的图像是不正确的:

    原图:


    读取一个波段后的图像(红波段):

    采用上述算法后的结果(有问题)后:

    调试后发现问题在于变量sumGray,个人觉得跟存储有关。

    2.将搜索八邻域的算法改为如下(不用循环,直接将八邻域列出来,相加):

    //----------搜索八邻域begin----------
    sumGray = (pafScan[(i-1)*nImgSizeX + j-1] + pafScan[(i-1)*nImgSizeX + j]  + pafScan[(i-1)*nImgSizeX + j+1]+ 
    	pafScan[i*nImgSizeX + j]       + pafScan[i*nImgSizeX + j-1]    + pafScan[i*nImgSizeX + j+1]    + 
    	pafScan[(i+1)*nImgSizeX + j-1] + pafScan[(i+1)*nImgSizeX + j]  + pafScan[(i+1)*nImgSizeX + j+1]);
    pafScan[i*nImgSizeX + j] =sumGray / 9.0;
    //----------搜索八邻域end----------


    输出的结果是正确的,结果如下:


    3.或者将搜索八邻域的算法改为如下(先对sumGray赋值一次,后面取平均时除10):

    //----------搜索八邻域begin----------
    	sumGray = pafScan[i*nImgSizeX + j];
    	for(int k=-1; k<2; k++)
    	{
    		for(int l=-1; l<2; l++)
    		{
    			sumGray += pafScan[(i+k)*nImgSizeX + (j+l)];
    		}
    	}
    			
    //----------搜索八邻域end----------
    pafScan[i*nImgSizeX + j] =sumGray / 10.0;

    输出结果如下:


    不清楚那个问题是怎么回事,对gdal的数据类型还是有些疑问。

  • 相关阅读:
    如何对已上架的宝贝进行调整不被降权?
    报错ERR_CONNECTION_REFUSED,如何解决(原创)
    ***在Linux环境下mysql的root密码忘记解决方法(三种)-推荐第三种
    微信获取用户基本信息,头像是一张“暂时无法查看”的图?
    Linux中zip压缩和unzip解压缩命令详解
    Android必知必会-App 常用图标尺寸规范汇总
    国外主机海外主机测评总结
    美国主机BlueHost vs HostEase
    cPanel中添加设置附加域(Addon domain)
    香港新世界机房和电讯盈科机房,沙田机房,葵芳机房哪数据中心一个好?服务器托管
  • 原文地址:https://www.cnblogs.com/shanchuan/p/8150360.html
Copyright © 2011-2022 走看看