#include <iostream>
#include <string>
#include "gdal_priv.h"
using namespace std;
//图像的膨胀
//算法的实现依然有重复的地方,会造成空间和时间上的浪费,但是效果还可以,暂定如此,如有好的算法再进行改进
void Expand(unsigned char* date,unsigned char* ExpandImage,int Width,int Height)
{
int x, y;
int Direction[8][2] = {-1, -1, 0, -1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, -1, 0};
int Index;
for(int i = 1;i < Height - 1;++i)
{
for(int j = 1;j < Width - 1;++j)
{
if(date[i * Width + j] == 255)
{
for(int k = 0;k < 8;++k)
{
x = i + Direction[k][0];
y = j + Direction[k][1];
Index = x * Width + y;
ExpandImage[Index] = 255;
}
}
}
}
return;
}
//图像的腐蚀
void Erosion(unsigned char* date,unsigned char* ErosionImage,int Width,int Height)
{
int x, y;
int Direction[8][2] = {-1, -1, 0, -1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, -1, 0};
int Index;
for(int i = 1;i < Height - 1;++i)
{
for(int j = 1;j < Width - 1;++j)
{
if(date[i * Width + j] == 0)
{
for(int k = 0;k < 8;++k)
{
x = i + Direction[k][0];
y = j + Direction[k][1];
Index = x * Width + y;
ErosionImage[Index] = 0;
}
}
}
}
return;
}
int main()
{
GDALAllRegister();
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO");
string str1="1.1.bmp";
string str2="1.2.tif";
string str3 = "1.3.tif";
GDALDataset* pInDataset=(GDALDataset*)GDALOpen(str1.data() ,GA_ReadOnly);
if(pInDataset == nullptr)
{
cout<<"未找到输入图像"<<endl;
getchar();
return 1;
}
int Width=pInDataset->GetRasterXSize();
int Height = pInDataset->GetRasterYSize();
int band = pInDataset->GetRasterCount();
double dGeoTrans[6]={};
pInDataset->GetGeoTransform(dGeoTrans);
const char* cProjectionRef = pInDataset->GetProjectionRef();
unsigned char* date = new unsigned char[Width * Height];
GDALRasterBand* pRasterBand = pInDataset->GetRasterBand(1);
CPLErr err=pRasterBand->RasterIO(GF_Read ,0 ,0 ,Width ,Height ,date ,Width ,Height ,GDT_Byte ,0 ,0);
//生成对于图像膨胀的图像
unsigned char* ExpandImage = new unsigned char[Width * Height];
memset(ExpandImage,0,sizeof(unsigned char) * Width * Height);
Expand(date ,ExpandImage,Width ,Height);
GDALDriver* pExpandDriver = GetGDALDriverManager()->GetDriverByName("GTiff");
GDALDataset* pOutExpandDataset = pExpandDriver->Create(str2.data() ,Width ,Height ,1 ,GDT_Byte ,NULL);
pOutExpandDataset->SetGeoTransform(dGeoTrans);
pOutExpandDataset->SetProjection(cProjectionRef);
GDALRasterBand* pOutExpandRasterband=pOutExpandDataset->GetRasterBand(1);
pOutExpandRasterband->RasterIO(GF_Write ,0 ,0 ,Width ,Height ,ExpandImage ,Width ,Height ,GDT_Byte ,0 ,0);
//生成对于图像腐蚀的图像,注意初始赋值时的不同
unsigned char* ErosionImage = new unsigned char[Width * Height];
memset(ErosionImage,255,sizeof(unsigned char) * Width * Height);
Erosion(date,ErosionImage,Width,Height);
GDALDriver* pDriver = GetGDALDriverManager()->GetDriverByName("GTiff");
GDALDataset* pOutDataset = pDriver->Create(str3.data() ,Width ,Height ,1 ,GDT_Byte ,NULL);
pOutDataset->SetGeoTransform(dGeoTrans);
pOutDataset->SetProjection(cProjectionRef);
GDALRasterBand* pOutRasterband=pOutDataset->GetRasterBand(1);
pOutRasterband->RasterIO(GF_Write ,0 ,0 ,Width ,Height ,ErosionImage ,Width ,Height ,GDT_Byte ,0 ,0);
GDALClose(pOutDataset);
GDALClose(pOutExpandDataset);
GDALClose(pInDataset);
GetGDALDriverManager()->DeregisterDriver(pDriver);
GetGDALDriverManager()->DeregisterDriver(pExpandDriver);
delete date;
delete ExpandImage;
delete ErosionImage;
return 0;
}
通过腐蚀和膨胀可以实现开运算和闭运算。
开运算:先腐蚀再膨胀
闭运算:先膨胀再腐蚀
然后弱小目标检测:闭运算减去开运算
具体实现:
unsigned char* ExpandImage = new unsigned char[Width * Height];
memset(ExpandImage,0,sizeof(unsigned char) * Width * Height);
Expand(date ,ExpandImage,Width ,Height);
unsigned char* ErosionImage = new unsigned char[Width * Height];
memset(ErosionImage,255,sizeof(unsigned char) * Width * Height);
Erosion(date,ErosionImage,Width,Height);
unsigned char* OpeningImage = new unsigned char[Width * Height];
memset(OpeningImage,0,sizeof(unsigned char) * Width * Height);
Expand(ErosionImage,OpeningImage,Width,Height);
unsigned char* ClosingImage = new unsigned char[Width * Height];
memset(ClosingImage,255,sizeof(unsigned char) * Width * Height);
Erosion(ExpandImage,ClosingImage,Width,Height);
//弱小目标检测:闭运算减去开运算
unsigned char* ResultImage = new unsigned char[Width * Height];
memset(ResultImage,255,sizeof(unsigned char) * Width * Height);
//ResultImage即为弱小目标检测结果
Subtraction(ResultImage,ClosingImage,OpeningImage,Width,Height);