遥感影像轮廓追踪C/C++(有效区域提取)

版权声明:本文为博主newston原创文章,允许转载,但转载必须保留原创链接。 https://blog.csdn.net/newston/article/details/88653981
	遥感图像处理中,有时需要获取正射后影像的有效区域,背景值可以通过GDAL中的

GetNoDataValue()

函数获取。如果没有,可以通过设置来给定这个值。一般DOM背景无效值为0,DSM为-9999.00000。而海洋遥感数据背景无效值可能为-32767.00000。
首选,使用无效值将影像二值化,然后对二值数据进行边界追踪。其中最重要的是两点:1初始点的选取;2追踪规则(方向)。代码如下:

struct Point
{
	double x,y;
};
template<class TT> vector<Point> GetImageArea(TT *pData, TT nodata, int width, int height)
{
	//如果遥感影像过大,先采样,再返回
	//首先将影像二值化
	unsigned char *pBinaryData= new unsigned char[(width)*(height)];
	memset(pBinaryData, sizeof(unsigned char)*(width)*(height), 255);//二值化时,255背景区域,0位有效区域
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			if (pData[i*width + j] != nodata)
				pBinaryData[i*width + j] = 0;
		}
	}
	//int direction[8][2] = { { -1, 1 }, { 0, 1 }, { 1, 1 }, { 1, 0 }, { 1, -1 }, { 0, -1 }, { -1, -1 }, { -1, 0 } };//普通图像左下角为(0,0)
	int direction[8][2] = { { 1, 1 }, { 0, 1 }, { -1, 1 }, { -1, 0 }, { -1, -1 }, { 0, -1 }, { 1, -1 }, { 1, 0 } };//遥感图像右上角为(0,0)
	//边界起始点,待处理的当前点,当前点的邻域点
	Point startP, currentP, neighborP;
	vector<Point> vPoints = vector<Point>();
	//是否当前点与起始边界点重合的标志变量
	int findStartPoint = 0;
	//循环变量,图像坐标
	int i, j;
	for (i = 0; i<height; i++){
		for (j = 0; j<width; j++){
			//找到起始边界点
			if (pBinaryData[i*width + j] == 0){
				startP.x = j;
				startP.y = i;
				vPoints.push_back(startP);
				findStartPoint = 1;
				break;
			}
		}
		//已经找到起始边界点
		if (findStartPoint)
			break;
	}
	//边界跟踪
	//从初始点开始跟踪
	currentP.x = startP.x;
	currentP.y = startP.y;
	//邻域点是否边界点标志变量
	int isContourP;
	//开始方向
	int startDirect = 0;

	//0表示还没有返回最初的边界起始点
	findStartPoint = 0;
	while (findStartPoint == 0){
		isContourP = false;
		while (isContourP == false){
			neighborP.x = currentP.x + direction[startDirect][0];
			neighborP.y = currentP.y + direction[startDirect][1];
			//搜索到邻域点
            //如果邻域点超出范围
			if (neighborP.x >= 0 && neighborP.y >= 0 && neighborP.x < width && neighborP.y < height && pBinaryData[int(neighborP.y)*width + int(neighborP.x)] == 0){
				isContourP = true;
				currentP.x = neighborP.x;
				currentP.y = neighborP.y;

				if (currentP.x == startP.x&&currentP.y == startP.y)
					findStartPoint = true;//回到边界起始点了

				vPoints.push_back(currentP);
				//扫描方向逆时针旋转90度
				startDirect -= 2;
				if (startDirect < 0)
					startDirect += 8;
			}
			else{
				//扫描方向顺时针旋转45度
				startDirect++;
				if (startDirect == 8)
					startDirect = 0;
			}

		}
	}
	if (pBinaryData != NULL)
	{
		delete pBinaryData;
		pBinaryData= NULL;
	}
	return vPoints ;
}
参见

Visual C++数字图像处理

猜你喜欢

转载自blog.csdn.net/newston/article/details/88653981