精华内容
下载资源
问答
  • 四叉树是一种树数据结构,具有4个“子级”,通常称为节点,这些节点中的每个节点内还有4个以上的节点,依此类推,直到达到指定的粒度为止。 出于优化目的,仅在必要时才创建子代,例如,在下图中,我们可以看到四叉...
  • 这个代码是一个四叉树的C#实现,使用四叉树文成一个可视项目。四叉树是一种树结构可以用于编码和2D碰撞检测。多用在2D碰撞检测中,在大量的碰撞检测中可以提高效率,但结构略复杂。
  • QuadTree四叉树顾名思义就是树状的数据结构,其每个节点有个孩子节点,可将二维平面递归分割子区域。QuadTree常用于空间数据库索引,3D的椎体可见区域裁剪,甚至图片分析处理,我们今天介绍的是QuadTree最常被游戏...
  • 从十月份开始,接触HEVC已经将近两个月了,可是效果并不是很明显,这两天都在看代码,经过一段时间的折腾...首先,对于叉树的分割形式,大家想必都已经了解了,这里就不进行过多的赘述,下面是常见的四叉树结构示意图

        从十月份开始,接触HEVC已经将近两个月了,可是效果并不是很明显,这两天都在看代码,经过一段时间的折腾,加上分析学习HEVC_CJL兄弟的文章,终于对HEVC帧内预测编码有了一定的理解,现在主要把本人对于如何LCU如何进一步细分成CU的过程跟大家分享一下,好了,闲话少叙,下面进入主题:


    首先,对于四叉树的分割形式,大家想必都已经了解了,这里就不进行过多的赘述,下面是常见的四叉树结构示意图:

    接下来是代码部分:

    该过程主要由TEncCu::xCompressCU函数的递归实现

        // further split进一步进行CU的分割
        if( bSubBranch && bTrySplitDQP && uiDepth < g_uiMaxCUDepth - g_uiAddCUDepth )
        {
          UChar       uhNextDepth         = uiDepth+1;
          TComDataCU* pcSubBestPartCU     = m_ppcBestCU[uhNextDepth];
          TComDataCU* pcSubTempPartCU     = m_ppcTempCU[uhNextDepth];
    
          for ( UInt uiPartUnitIdx = 0; uiPartUnitIdx < 4; uiPartUnitIdx++ )//每次分成四个更小的CU
        {
            pcSubBestPartCU->initSubCU( rpcTempCU, uiPartUnitIdx, uhNextDepth, iQP );           // clear sub partition datas or init.
            pcSubTempPartCU->initSubCU( rpcTempCU, uiPartUnitIdx, uhNextDepth, iQP );           // clear sub partition datas or init.
    
            Bool bInSlice = pcSubBestPartCU->getSCUAddr()+pcSubBestPartCU->getTotalNumPart()>pcSlice->getDependentSliceCurStartCUAddr()&&pcSubBestPartCU->getSCUAddr()<pcSlice->getDependentSliceCurEndCUAddr();
            if(bInSlice && ( pcSubBestPartCU->getCUPelX() < pcSlice->getSPS()->getPicWidthInLumaSamples() ) && ( pcSubBestPartCU->getCUPelY() < pcSlice->getSPS()->getPicHeightInLumaSamples() ) )
            {
              if( m_bUseSBACRD )
              {
                if ( 0 == uiPartUnitIdx) //initialize RD with previous depth buffer
                {
                  m_pppcRDSbacCoder[uhNextDepth][CI_CURR_BEST]->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]);
                }
                else
                {
                  m_pppcRDSbacCoder[uhNextDepth][CI_CURR_BEST]->load(m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]);
                }
              }
    
    #if AMP_ENC_SPEEDUP
              if ( rpcBestCU->isIntra(0) )
              {
                xCompressCU( pcSubBestPartCU, pcSubTempPartCU, uhNextDepth, SIZE_NONE );//递归函数
              }
              else
              {
                xCompressCU( pcSubBestPartCU, pcSubTempPartCU, uhNextDepth, rpcBestCU->getPartitionSize(0) );//递归函数
              }
    #else
              xCompressCU( pcSubBestPartCU, pcSubTempPartCU, uhNextDepth );         
    #endif
    
              rpcTempCU->copyPartFrom( pcSubBestPartCU, uiPartUnitIdx, uhNextDepth );         // Keep best part data to current temporary data.
              xCopyYuv2Tmp( pcSubBestPartCU->getTotalNumPart()*uiPartUnitIdx, uhNextDepth );
            }
            else if (bInSlice)
            {
              pcSubBestPartCU->copyToPic( uhNextDepth );
              rpcTempCU->copyPartFrom( pcSubBestPartCU, uiPartUnitIdx, uhNextDepth );
            }
          }


    既然已经知道,CU的分割是通过递归实现的,那么怎么确定哪个uiDepth的CU为rpcBestCU呢?

    上述递归函数结束后,然后再通过xCheckBestMode( rpcBestCU, rpcTempCU, uiDepth);判断决定是否选择本层CU还是下层CU.

    以下是编程实现输出一个LCU的分割模式:

      // We need to split, so don't try these modes.
      if(!bSliceEnd && !bSliceStart && bInsidePicture )
      {
        for (Int iQP=iMinQP; iQP<=iMaxQP; iQP++)
        {
          if (isAddLowestQP && (iQP == iMinQP))
          {
            iQP = lowestQP;
          }
          // variables for fast encoder decision
          bEarlySkip  = false;
          bTrySplit    = true;
          fRD_Skip    = MAX_DOUBLE;
    
          rpcTempCU->initEstData( uiDepth, iQP );
         //==输出分区深度信息depth==//
          cout<<"Depth:";
          for(Int i=0;i<=uiDepth;i++)
           cout<<"->";
           cout<<uiDepth<<endl;
    
          // do inter modes, SKIP and 2Nx2N
    打印输出的结构为:

    Depth:->0
    Depth:->->1
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->1
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->1
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->1
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3


    如有错误,还望不吝赐教,特别感谢zhuix7788的指导。

    最终的LCU分割结果详见下一篇http://blog.csdn.net/yangxiao_xiang/article/details/8275181。






    展开全文
  • 基于十进制的四叉树结构的编程(栅格数据) 其中有两个功能; 已知行列求莫顿码; 已知莫顿码求行列
  • 四叉树的详细讲解对四叉树的详细讲解对四叉树的详细讲解对四叉树的详细讲解
  • python生成四叉树

    2017-12-05 14:36:14
    把一个四叉树结构的list转变成一棵叉树的对象,并通过前序遍历遍历这棵树,一个脚本,一个类两个函数
  • 线性四叉树的实现C++

    2020-11-06 19:28:39
    1.为了通过数组下标明确父节点与子节点的关系,采用的是完全四叉树的结构,由于地理空间对象可能分布不均衡,这样会导致四叉树生成一棵极为不平衡的树,也会造成树结构的不平衡以及存储空间的极大浪费。 2.为了判断...

    线性四叉树的实现

    1)线性四叉树只存储最后的叶节点信息,包括叶节点的位置,大小和深度(根据数组下标可以直接得到)。
    2)使用节点引用类型的vector容器表示一颗完全四叉树。
    3) 完全四叉树的父节点数组下标为i时,对应的子节点下标为4*i+num,num∈{1,2,3,4}。

    不足:
    1.为了通过数组下标明确父节点与子节点的关系,采用的是完全四叉树的结构,由于地理空间对象可能分布不均衡,这样会导致四叉树生成一棵极为不平衡的树,也会造成树结构的不平衡以及存储空间的极大浪费。
    2.为了判断是否是叶子结点,在数组声明时,将数组元素的leaf成员声明为true,但是在插入数据之前并不知道树的深度,需要预留大量空间,并对数组中所有元素赋初值,导致时间和vector空间的浪费。
    3.存储非叶子节点的vector空间浪费。

    
    #include <iostream>
    #include <vector>
    #include<cstdlib>
    #include<math.h>
    #include <time.h>
    #include<fstream>
    const int MAX_NUM=100;
    using namespace std;
    struct Region;
    //最小外接矩形
    struct Region {
    	int right;
    	int left;
    	int up;
    	int bottom;
    };
    //点
    struct Point {
    	float x;
    	float y;	
    }p;
    //定义四叉树的节点
    struct QuadtNode {
       vector<Point> list;//存储四叉树该节点的所有坐标
       int depth;//四叉树的深度
       int size;//记录节点数,最大值MAX_NUM
       bool leaf;//记录是否为叶子节点
      Region region;  
    };
    vector<Point> xy;
    vector<Point> a_xy;
    vector< QuadtNode> q;
    vector< QuadtNode> &quadtree= q;//节点的vector容器来表示一颗四叉树
    void creatQuadtree();//创建空四叉树
    void insertQuadtree(long int , Point );//插入一个坐标
    void regionSet(QuadtNode node, int b, int u, int l, int r);//更新MBR
    void splitNode(long int index);//节点分裂
    void queryEle(int index, Point ele);//点查询
    void out();//文件输出
    int main()
    {
       long int i;
       quadtree.resize(100000);
      // cout << quadtree.capacity();
    	for (i = 0; i < 100000; i++) {
    		quadtree[i].leaf = 1;
    		quadtree[i].size = 0;
    		//cout<<quadtree[i].leaf;
    	}
    	//creatQuadtree();
    	//for (vector<QuadtNode>::iterator i = quadtree.begin(); i < quadtree.end(); i++) {
    		
    	Point p;
    	srand((int)time(NULL));//随机数
    	for (int i = 0; i < 1000; i++) {
    		p.y = (float)(rand() % 360 - 180 + (float)(rand() % 1000) / 1000);
    		p.x = (float)(rand() % 180 - 90 + (float)(rand() % 1000) / 1000);
    		insertQuadtree(0, p);
    		a_xy.push_back(p);
    	}
    	//for (vector<QuadtNode>::iterator it = quadtree.begin(); it < quadtree.end(); it++) {
    
    	//	if ((*it).leaf == 1&&(*it).leaf!=NULL)
    	//		for (vector<Point>::iterator count = (*it).list.begin(); count < (*it).list.end(); count++) {
    
    	//			cout << (*count).x << "," << (*count).y << endl;
    	//		}
    	//}
    	Point ele;
    	ele.x = -24;
    	ele.y = -20;
    	queryEle(0, ele);
    	out();
    }
    //查询
    void queryEle( int index,  Point ele) {
    	if (quadtree[index].leaf == 1) {
    		printf("附近点有%d个,分别是:\n", quadtree[index].size);
    		for (int j = 0; j < quadtree[index].size; j++) {
    			printf("%f,%f\n", quadtree[index].list[j].x, quadtree[index].list[j].y);
    			xy.push_back(quadtree[index].list[j]);
    		}
    		return;
    	}
    
    	double mid_vertical = (quadtree[index].region.up + quadtree[index].region.bottom) / 2;
    	double mid_horizontal = (quadtree[index].region.left + quadtree[index].region.right) / 2;
    
    	if (ele.x > mid_vertical) {
    		if (ele.y > mid_horizontal) {
    			queryEle(4 * index + 1, ele);
    		}
    		else {
    			queryEle(4 * index + 4, ele);
    		}
    	}
    	else {
    		if (ele.y > mid_horizontal) {
    			queryEle(4 * index + 2, ele);
    		}
    		else {
    			queryEle(4 * index + 3, ele);
    		}
    	}
    }
    //创建空四叉树
    void creatQuadtree()
    {
    	QuadtNode node;
    	p.x = 0;
    	p.y = 0;
    	node.list.push_back(p);
    	node.size = 0;
    	node.depth = 0;
    	node.region.bottom = -90;
    	node.region.up = 90;
    	node.region.left = -180;
    	node.region.right = 180;
    	node.leaf = 1;
    	quadtree.push_back(node);
    }
    //插入一个点,index是当前节点的下标
    void insertQuadtree(long int index, Point p)
    {
    	if (quadtree[index].leaf==true ) {//如果当前节点是叶子节点
    		if ((quadtree[index].size + 1 )> MAX_NUM){//节点数据已满
    			splitNode(index);//节点分裂			
    			insertQuadtree(index, p);
    		}
    		else {
    			quadtree[index].list.push_back(p);//节点未满则插入点坐标
    			quadtree[index].size++;	//更新节点所包含点数		
    		}
    		return;
    	}
    	//进入四分区域
    	double mid_vertical = (quadtree[index].region.up + quadtree[index].region.bottom) / 2;
    	double mid_horizontal = (quadtree[index].region.left + quadtree[index].region.right) / 2;
    	if (p.x > mid_vertical) {
    		if (p.y > mid_horizontal) {
    			insertQuadtree(4 * index + 1, p);//
    		}
    		else {
    			insertQuadtree(4 * index + 4, p);
    		}
    	}
    	else {
    		if (p.y > mid_horizontal) {
    			insertQuadtree(4 * index + 2, p);
    		}
    		else {
    			insertQuadtree(4 * index + 3, p);
    		}
    	}	
    }
    //更新MBR
    void regionSet(QuadtNode node,int b,int u,int l,int r )
    {	
    	node.region.bottom = b;
    	node.region.up = u;
    	node.region.left = l;
    	node.region.right = r;
    }
    //分裂节点
    void splitNode(long int index) {
    	double mid_vertical = (quadtree[index].region.up + quadtree[index].region.bottom) / 2;
    	double mid_horizontal = (quadtree[index].region.left + quadtree[index].region.right) / 2;
    	quadtree[index].leaf = 0;
    	regionSet(quadtree[4 * index + 1], mid_vertical, quadtree[4 * index + 1].region.up, mid_horizontal, quadtree[4 * index + 1].region.right);
    	regionSet(quadtree[4 * index + 2], mid_vertical, quadtree[4 * index + 2].region.up, quadtree[4*index+2].region.left, mid_horizontal);
    	regionSet(quadtree[4 * index + 3], quadtree[4 * index + 3].region.bottom, mid_vertical, mid_horizontal, quadtree[4 * index + 3].region.right);
    	regionSet(quadtree[4 * index + 4], quadtree[4 * index + 4].region.bottom, mid_vertical, quadtree[4 * index + 4].region.left, mid_horizontal);
    	for (int i = 0; i < quadtree[index].size; i++) {		
    		insertQuadtree(index, quadtree[index].list[i]);		
    		quadtree[index].size--;
    	} 
    	
    }
    //文件输出
    void out() {
    	fstream ofs1;
    	int i, j;
    	ofs1.open("XY.txt", ios::out);
    	for (i = 0; i < xy.size(); i++) {
    		ofs1 << xy[i].x << " ";
    		ofs1 << xy[i].y << endl;
    	}
    	fstream ofs2;
    	ofs2.open("allXY.txt", ios::out);
    	for (i = 0; i < a_xy.size(); i++) {
    		ofs2 << a_xy[i].x << " ";
    		ofs2 << a_xy[i].y << endl;
    	}
    
    }## 标题
    
    展开全文
  • 栅格数据的四叉树编/解码

    千次阅读 2021-02-16 18:22:39
    区域型物体的叉树(Quad-tree)表示方法最早出现在加拿大地理信息系统CGIS中,将四叉树结构表达的信息以一种线性编码的方式存储起来,称之为叉树编码,其在图像分割、数据压缩、地理信息系统等方面应用广泛。...

    问题描述

    区域型物体的四叉树(Quad-tree)表示方法最早出现在加拿大地理信息系统CGIS中,将四叉树结构表达的信息以一种线性编码的方式存储起来,称之为四叉树编码,其在图像分割、数据压缩、地理信息系统等方面应用广泛。请实现黑白栅格数据的四叉树分割和编/解码算法。

    基本要求

    (1)读取一个待压缩的栅格数据文件,文件中的每个像元仅有黑白(0、1)两种取值(即二值图像),用一个矩阵存储原始数据;
    (2)对该矩阵进行自上而下的四叉树分割,构建四叉树结构;
    (3)对得到的所有叶子节点进行线性四叉树编码,将编码作为一个数组结果写入文件;
    (4)实现线性四叉树编码的解码程序,将编码结果解码得到栅格数据。

    详细设计

    #include<stdio.h>
    #include<stdlib.h>
    
    #define Matrix_MAXNUM 8     //2^n
    #define Position_MAXNUM 4   //=1+ln(Matrix_MAXNUM)
    
    typedef struct quadtree
    {
    	int value; //-1表示此节点不是叶子节点
    	int position[Position_MAXNUM];//第1位表示深度,后ln(Matrix_MAXNUM)位表示从根节点到叶结点的路径
    	struct quadtree* NW;//1代表其路径
    	struct quadtree* NE;//2
    	struct quadtree* SW;//3
    	struct quadtree* SE;//4
    }QuTree, * QuTreePtr;
    
    int Matrix[Matrix_MAXNUM][Matrix_MAXNUM] =
    {
    	{0,0,0,0,0,0,0,0},
    	{0,0,0,0,0,0,0,0},
    	{0,0,0,0,1,1,1,1},
    	{0,0,0,0,1,1,1,1},
    	{0,0,0,1,1,1,1,1},
    	{0,0,1,1,1,1,1,1},
    	{0,0,1,1,1,1,0,0},
    	{0,0,1,1,1,0,0,0}
    };
    void PreOrder_traverse(QuTreePtr pHead)
    {
    	if (pHead->value != -1)
    	{
    		//写入文件
    		int QuTreeCode[Position_MAXNUM];
    		for (int i = 0; i < Position_MAXNUM - 1; i++)
    		{
    			QuTreeCode[i] = pHead->position[i + 1];
    		}
    		QuTreeCode[Position_MAXNUM - 1] = pHead->position[0];
    		FILE* fp;
    		fopen_s(&fp, "QuadTree_EncodingFile.txt", "a");
    		for (int i = 0; i < Position_MAXNUM; i++)
    		{
    			fwrite(&QuTreeCode[i], sizeof(int), 1, fp);
    		}
    		fclose(fp);
    
    		printf("value:%d\tdepth:%d\tpath:", pHead->value, pHead->position[0]);
    		for (int i = 1; i < Position_MAXNUM; i++)
    		{
    			printf("%d ", pHead->position[i]);
    		}
    
    		printf("\n");
    	}
    	else
    	{
    		PreOrder_traverse(pHead->NW);
    		PreOrder_traverse(pHead->NE);
    		PreOrder_traverse(pHead->SW);
    		PreOrder_traverse(pHead->SE);
    	}
    }
    void QuTree_Encoding(QuTreePtr pHead, int Frow, int Lrow, int Fline, int Lline)
    {
    	if (pHead != NULL)
    	{
    		//pHead->NW
    		QuTreePtr P1;
    		P1 = (QuTreePtr)malloc(sizeof(QuTree));
    
    		//判断左上角区域属性是否一致
    		bool same1 = true;
    		for (int i = Frow; i <= (Frow + Lrow) / 2; i++)
    		{
    			for (int j = Fline; j <= (Fline + Lline) / 2; j++)
    			{
    				if (Matrix[i][j] != Matrix[Frow][Fline])
    				{
    					same1 = false;
    					break;
    				}
    			}
    			if (!same1)break;
    		}
    		P1->position[0] = pHead->position[0] + 1;//子树深度等于根节点深度加1
    		for (int i = 1; i < P1->position[0]; i++)//继承根节点的路径
    		{
    			P1->position[i] = pHead->position[i];
    		}
    		P1->position[P1->position[0]] = 0;//由根节点到子树的路径*
    		for (int i = P1->position[0] + 1; i < Position_MAXNUM; i++)//用0补全后面的位置
    		{
    			P1->position[i] = 0;
    		}
    		P1->NW = NULL;
    		P1->NE = NULL;
    		P1->SW = NULL;
    		P1->SE = NULL;
    		pHead->NW = P1;
    		if (same1 == true)
    		{
    			P1->value = Matrix[Frow][Fline];
    		}
    		else//如果属性不同,递归调用
    		{
    			P1->value = -1;
    			QuTree_Encoding(P1, Frow, (Frow + Lrow) / 2, Fline, (Fline + Lline) / 2);
    		}
    
    		//pHead->NE
    		QuTreePtr P2;
    		P2 = (QuTreePtr)malloc(sizeof(QuTree));
    		bool same2 = true;
    		for (int i = Frow; i <= (Frow + Lrow) / 2; i++)
    		{
    			for (int j = (Fline + Lline) / 2 + 1; j <= Lline; j++)
    			{
    				if (Matrix[i][j] != Matrix[Frow][(Fline + Lline) / 2 + 1])
    				{
    					same2 = false;
    					break;
    				}
    			}
    			if (!same2)break;
    		}
    		P2->position[0] = pHead->position[0] + 1;
    		for (int i = 1; i < P2->position[0]; i++)
    		{
    			P2->position[i] = pHead->position[i];
    		}
    		P2->position[P2->position[0]] = 1;//2
    		for (int i = P2->position[0] + 1; i < Position_MAXNUM; i++)
    		{
    			P2->position[i] = 0;
    		}
    		P2->NW = NULL;
    		P2->NE = NULL;
    		P2->SW = NULL;
    		P2->SE = NULL;
    		pHead->NE = P2;
    		if (same2 == true)
    		{
    			P2->value = Matrix[Frow][(Fline + Lline) / 2 + 1];
    		}
    		else
    		{
    			P2->value = -1;
    			QuTree_Encoding(P2, Frow, (Frow + Lrow) / 2, (Fline + Lline) / 2 + 1, Lline);
    		}
    
    		//pHead->SW
    		QuTreePtr P3;
    		P3 = (QuTreePtr)malloc(sizeof(QuTree));
    		bool same3 = true;
    		for (int i = (Frow + Lrow) / 2 + 1; i <= Lrow; i++)
    		{
    			for (int j = Fline; j <= (Fline + Lline) / 2; j++)
    			{
    				if (Matrix[i][j] != Matrix[(Frow + Lrow) / 2 + 1][Fline])
    				{
    					same3 = false;
    					break;
    				}
    			}
    			if (!same3)break;
    		}
    		P3->position[0] = pHead->position[0] + 1;
    		for (int i = 1; i < P3->position[0]; i++)
    		{
    			P3->position[i] = pHead->position[i];
    		}
    		P3->position[P3->position[0]] = 2;//3
    		for (int i = P3->position[0] + 1; i < Position_MAXNUM; i++)
    		{
    			P3->position[i] = 0;
    		}
    		P3->NW = NULL;
    		P3->NE = NULL;
    		P3->SW = NULL;
    		P3->SE = NULL;
    		pHead->SW = P3;
    		if (same3 == true)
    		{
    			P3->value = Matrix[(Frow + Lrow) / 2 + 1][Fline];
    		}
    		else
    		{
    			P3->value = -1;
    			QuTree_Encoding(P3, (Frow + Lrow) / 2 + 1, Lrow, Fline, (Fline + Lline) / 2);
    		}
    
    		//pHead->SE
    		QuTreePtr P4;
    		P4 = (QuTreePtr)malloc(sizeof(QuTree));
    		bool same4 = true;
    		for (int i = (Frow + Lrow) / 2 + 1; i <= Lrow; i++)
    		{
    			for (int j = (Fline + Lline) / 2 + 1; j <= Lline; j++)
    			{
    				if (Matrix[i][j] != Matrix[(Frow + Lrow) / 2 + 1][(Fline + Lline) / 2 + 1])
    				{
    					same4 = false;
    					break;
    				}
    			}
    			if (!same4)break;
    		}
    		P4->position[0] = pHead->position[0] + 1;
    		for (int i = 1; i < P4->position[0]; i++)
    		{
    			P4->position[i] = pHead->position[i];
    		}
    		P4->position[P4->position[0]] = 3;//4
    		for (int i = P4->position[0] + 1; i < Position_MAXNUM; i++)
    		{
    			P4->position[i] = 0;
    		}
    		P4->NW = NULL;
    		P4->NE = NULL;
    		P4->SW = NULL;
    		P4->SE = NULL;
    		pHead->SE = P4;
    		if (same4 == true)
    		{
    			P4->value = Matrix[(Frow + Lrow) / 2 + 1][(Fline + Lline) / 2 + 1];
    		}
    		else
    		{
    			P4->value = -1;
    			QuTree_Encoding(P4, (Frow + Lrow) / 2 + 1, Lrow, (Fline + Lline) / 2 + 1, Lline);
    		}
    	}
    }
    
    
    void main()
    {
    	QuTreePtr p;
    	p = (QuTreePtr)malloc(sizeof(QuTree));
    	for (int i = 0; i < Position_MAXNUM; i++)
    	{
    		p->position[i] = 0;
    	}
    	p->value = -1;
    	p->NW = NULL;
    	p->NE = NULL;
    	p->SW = NULL;
    	p->SE = NULL;
    	QuTree_Encoding(p, 0, Matrix_MAXNUM - 1, 0, Matrix_MAXNUM - 1);
    	PreOrder_traverse(p);
    	system("pause");
    }
    

    测试与结果
    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • 通过对原始图像在多个尺度上进行最小二乘多项式逼近,将图像进行非均匀剖分,并以四叉树结构的形式进行表达。该四叉树结构既实现了对原始图像的逼近,同时携带了图像的纹理结构信息。通过统计各子区域上的剖分网格...
  • 四叉树索引的基本思想是将地理空间递归划分为不同层次的树结构。它将已知范围的空间等分成个相等的子空间,如此递归下去,直至树的层次达到一定深度或者满足某种要求后停止分割。四叉树的结构比较简单,并且当空间...

    参考:http://blog.csdn.net/zhouxuguang236/article/details/12312099

    原博客地址还有c++源码。。。

    四叉树索引的基本思想是将地理空间递归划分为不同层次的树结构。它将已知范围的空间等分成四个相等的子空间,如此递归下去,直至树的层次达到一定深度或者满足某种要求后停止分割。四叉树的结构比较简单,并且当空间数据对象分布比较均匀时,具有比较高的空间数据插入和查询效率,因此四叉树是GIS中常用的空间索引之一。常规四叉树的结构如图所示,地理空间对象都存储在叶子节点上,中间节点以及根节点不存储地理空间对象。

     

     

    四叉树示意图

     

    四叉树对于区域查询,效率比较高。但如果空间对象分布不均匀,随着地理空间对象的不断插入,四叉树的层次会不断地加深,将形成一棵严重不平衡的四叉树,那么每次查询的深度将大大的增多,从而导致查询效率的急剧下降。

     

    本节将介绍一种改进的四叉树索引结构。四叉树结构是自顶向下逐步划分的一种树状的层次结构。传统的四叉树索引存在着以下几个缺点:

    (1)空间实体只能存储在叶子节点中,中间节点以及根节点不能存储空间实体信息,随着空间对象的不断插入,最终会导致四叉树树的层次比较深,在进行空间数据窗口查询的时候效率会比较低下。

    (2)同一个地理实体在四叉树的分裂过程中极有可能存储在多个节点中,这样就导致了索引存储空间的浪费。

    (3)由于地理空间对象可能分布不均衡,这样会导致常规四叉树生成一棵极为不平衡的树,这样也会造成树结构的不平衡以及存储空间的浪费。

    相应的改进方法,将地理实体信息存储在完全包含它的最小矩形节点中,不存储在它的父节点中,每个地理实体只在树中存储一次,避免存储空间的浪费。首先生成满四叉树,避免在地理实体插入时需要重新分配内存,加快插入的速度,最后将空的节点所占内存空间释放掉。改进后的四叉树结构如下图所示。四叉树的深度一般取经验值4-7之间为最佳。

     

    图改进的四叉树结构

     

    为了维护空间索引与对存储在文件或数据库中的空间数据的一致性,作者设计了如下的数据结构支持四叉树的操作。

    (1)四分区域标识

    分别定义了一个平面区域的四个子区域索引号,右上为第一象限0,左上为第二象限1,左下为第三象限2,右下为第四象限3。

    typedef enum

    {

          UR = 0,// UR第一象限

          UL = 1, // UL为第二象限

          LL = 2, // LL为第三象限

          LR = 3  // LR为第四象限

    }QuadrantEnum;

    (2)空间对象数据结构

    空间对象数据结构是对地理空间对象的近似,在空间索引中,相当一部分都是采用MBR作为近似。

    /*空间对象MBR信息*/

    typedef struct SHPMBRInfo

    {

          int nID;       //空间对象ID号

          MapRect Box;    //空间对象MBR范围坐标

    }SHPMBRInfo;

    nID是空间对象的标识号,Box是空间对象的最小外包矩形(MBR)。

    (3)四叉树节点数据结构

    四叉树节点是四叉树结构的主要组成部分,主要用于存储空间对象的标识号和MBR,也是四叉树算法操作的主要部分。

    /*四叉树节点类型结构*/

    typedef struct QuadNode

    {

          MapRect            Box;                   //节点所代表的矩形区域

          int                nShpCount;        //节点所包含的所有空间对象个数

          SHPMBRInfo* pShapeObj;          //空间对象指针数组

          int         nChildCount;            //子节点个数

          QuadNode *children[4];             //指向节点的四个孩子

    }QuadNode;

    Box是代表四叉树对应区域的最小外包矩形,上一层的节点的最小外包矩形包含下一层最小外包矩形区域;nShpCount代表本节点包含的空间对象的个数;pShapeObj代表指向空间对象存储地址的首地址,同一个节点的空间对象在内存中连续存储;nChildCount代表节点拥有的子节点的数目;children是指向孩子节点指针的数组。

     

     参考:http://blog.csdn.net/zhouxuguang236/article/details/12312099

    四叉树原理

    四叉树是种很直接的空间索引技术。在四叉树中,每个节点表示覆盖了部分进行索引的空间的边界框,根节点覆盖了整个区域。每个节点要么是叶节点,有包含一个或多个索引点的列表,没有孩子。要么是内部节点,有四个孩子,每个孩子对应将区域沿两根轴对半分得到的四个象限中的一个,四叉树也因此得名。

    图1    展示四叉树是怎样划分索引区域的 来源:维基百科

    将数据插入四叉树很简单:从根节点开始,判断你的数据点属于哪个象限。递归到相应的节点,重复步骤,直到到达叶节点,然后将该点加入节点的索引点列表中。如果列表中的元素个数超出了预设的最大数目,则将节点分裂,将其中的索引点移动到相应的子节点中去。

    图2    四叉树的内部结构

    查询四叉树时从根节点开始,检查每个子节点看是否与查询的区域相交。如果是,则递归进入该子节点。当到达叶节点时,检查点列表中的每一个项看是否与查询区域相交,如果是则返回此项。

    注意四叉树是非常规则的,事实上它是一种字典树,因为树节点的值不依赖于插入的数据。因此我们可以用直接的方式给节点编号:用二进制给每个象限编号(左上是00,右上是10等等 译者注:第一个比特位为0表示在左半平面,为1在右半平面。第二个比特位为0表示在上半平面,为1在下半平面),任一节点的编号是由从根开始,它的各祖先的象限号码串接而成的。在这个编号系统中,图2中右下角节点的编号是1101。

    如果我们定义了树的最大深度,不需通过树就可以计算数据点所在节点的编号:只要把节点的坐标标准化到适当的整数区间中(比如32位整数),然后把转化后x, y坐标的比特位交错组合。每对比特指定了假想的四叉树中的一个象限。

     

     

    如何在iOS地图上高效的显示大量数据

    参考:http://blog.163.com/l1_jun/blog/static/143863882013111651737708/

    展开全文
  • #include #include #include #include #include using namespace std;int tree[400][4];///四叉树的数组 int leaf[350];///存储叶子节点 int image[16][16];///图像的矩阵 int m;///叶
  • 四叉树数据结构 四叉树数据结构 常规四叉树 线性四叉树 1 四叉树分割的基本思想 k k 把一副图像或一副栅格地图2 x2 ,k>1等分成部分逐 块检查其格网值 如果某个子区的所有格网都含有相 2 3 1 同的值则子区不再分割 ...
  • 四叉树+二叉树QTBT编码结构,已经被JVET采纳加入到了新一代编码标准和JEM中。
  • 基于四叉树数据结构进行有损图像压缩
  • HEVC中四叉树划分详解

    千次阅读 2018-01-16 11:49:28
    偶然看到一篇论文,关于四叉树划分,感觉写的挺清楚的,随手记录下。 HEVC中,一帧图像被分割为多个互补重叠的LCU,LCU大小一般设为64*64。每个LCU又可按照四叉树的方式递归划分为多个子CU。编码器编码时,需要判断...
  • 四叉树matlab代码介绍 我们在这里提供了一个基于 Matlab 的 polytree 网格细化,用于裂纹结构的极限分析。 关键思想是开发基于所谓的多树网格结构的通用细化算法。 该方法非常适用于任意多边形元素以及传统的三角形...
  • vc++实现图像数据结构图遍历算法四叉树
  • 四叉树数据结构

    千次阅读 2011-12-16 10:26:58
    /********************************************//** ...* Puruose: FourTreeTpl.h四叉树模板结构定义 * Author: 刘巍 * Describe: 定义四叉树数据结构,包括节点,以及基本树操作 ******************
  • 四叉树

    千次阅读 2019-05-30 11:53:00
    本文着重于对四叉树与八叉树的原理与结构的介绍,帮助您在脑海中建立四叉树与八叉树的基本思想。本文并不对这两种数据结构同时进行详解,而只对四叉树进行详解,因为八叉树的建立可由四叉树的建立推得。...
  • matlab图像分解四叉树分解显示

    热门讨论 2012-02-11 10:28:04
    此资源为matlab代码,对图像进行四叉树分解,并把分解后的结果显示于原图。
  • 四叉树——图片应用实例

    千次阅读 2019-06-19 21:51:07
    元树又称四叉树是一种树状数据结构,在每一个节点上会有个子区块。元树常应用于二维空间数据的分析与分类。 它将数据区分成为个象限。数据范围可以是方形或矩形或其他任意形状。 这种数据结构是由 拉斐尔·...
  • 为提高空间数据的检索效率,针对普通四叉树的查询方法,提出一种新的索引结构--线索四叉树。从区域检索原理出发,导出线索四叉树的检索方法,并论证了其检索结果与普通四叉树是相同的。实验证明,线索四叉树能够有效...
  • geojson-qt实现了一个包含 GeoJSON 特征的四叉树,并允许轻松查找和浏览所述特征。 geojson-qt假设 GeoJSON 中使用的坐标在直角坐标系中; 也可以使用 WGS84 坐标,但它们是线性处理的。 安装 npm install geojson...
  • 四叉树空间索引原理及其实现

    万次阅读 多人点赞 2013-10-05 15:59:19
    四叉树索引的基本思想是将地理空间递归划分为不同层次的树结构。它将已知范围的空间等分成个相等的子空间,如此递归下去,直至树的层次达到一定深度或者满足某种要求后停止分割。四叉树的结构比较简单,并且当空间...
  • 一个入门四叉树例子

    千次阅读 2014-05-06 17:57:15
    概述   四叉树读书笔记  源代码: http://www.pudn.com/downloads343/sourcecode/windows/opengl/detail1500968.html   正文:
  • Unity 四叉树QuadTree应用之碰撞检测

    千次阅读 2020-06-09 17:25:56
    四叉树顾名思义,就是每科树都包含4个分支,每个分支可以看做一个区域象限,用来存放一些数据的空间索引 这里只讨论四叉树在二维空间的碰撞检测,Unity的实现方式 2.树的结构 public interface IRect { /// &...
  • 四叉树与八叉树

    万次阅读 多人点赞 2011-08-21 15:34:13
    前序 四叉树元树也被称为Q树(Q-Tree)。四叉树广泛应用于图像处理、空间数据索引、2D中的快速碰撞检测、存储稀疏数据等,而...本文着重于对四叉树与八叉树的原理与结构的介绍,帮助您在脑海中建立四叉树与八叉树
  • 空间划分的数据结构(网格/四叉树/八叉树/BSP树/k-d树/BVH/自定义划分) 目录 网格 (Grid) 网格的应用 四叉树/八叉树 (Quadtree/Octree) 四叉树/八叉树的应用 BSP树 (Binary Space Partitioning Tree) ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 66,853
精华内容 26,741
关键字:

四叉树结构