// ***************************************************************************
bool			CAABBox::intersect(const CVector &a, const CVector &b, const CVector &c) const
{
	// Trivial test.
	if(include(a) || include(b) || include(c))
		return true;
	// Else, must test if the polygon intersect the pyamid.
	CPlane		planes[6];
	makePyramid(planes);
	CPolygon	poly(a,b,c);
	poly.clip(planes, 6);
	if(poly.getNumVertices()==0)
		return false;
	return true;
}
// ***************************************************************************
bool			CAABBox::intersect(const CVector &a, const CVector &b) const
{
	// Trivial test.
	if(include(a) || include(b))
		return true;
	// Else, must test if the segment intersect the pyamid.
	CPlane		planes[6];
	makePyramid(planes);
	CVector		p0=a , p1=b;
	// clip the segment against all planes
	for(uint i=0;i<6;i++)
	{
		if(!planes[i].clipSegmentBack(p0, p1))
			return false;
	}
	return true;
}
// ***************************************************************************
bool			CAABBox::clipSegment(CVector &a, CVector &b) const
{
	// Trivial test. If both are in, they are inchanged
	if(include(a) && include(b))
		return true;
	// Else, must clip the segment againts the pyamid.
	CPlane		planes[6];
	makePyramid(planes);
	CVector		p0=a , p1=b;
	// clip the segment against all planes
	for(uint i=0;i<6;i++)
	{
		if(!planes[i].clipSegmentBack(p0, p1))
			return false;
	}
	// get result
	a= p0;
	b= p1;
	return true;
}
Пример #4
0
int main(int argc, char **argv){

  if(argc != 9){
    printf("wrong # args\n");
    printf("inputfile outDir(./lol/) invert (0 or 1) k*1000 windowRadius gaussPyramidThresh(>= survive) finalMixThresh(>= survive) writeDebugImages(0 or 1)\n");
  }

  int width, height, channels;
  unsigned char *data;
  char *dir = argv[2];
  int inv = atoi(argv[3]);
  float k = float(atoi(argv[4]))/1000.f;
  int window = atoi(argv[5]);
  int gaussPyramidThresh = atoi(argv[6]);
  int finalMixThresh = atoi(argv[7]);
  bool debugImages = atoi(argv[8]);

  bool res = loadImage(argv[1], &width, &height, &channels, &data);

  if(!res){
    printf("error reading image\n");
    return 1;
  }

  printf("start\n");

  // to grayscale
  unsigned char *dataGray = new unsigned char[width*height];
  toGrayscale(width,height,data,dataGray);

  // build SAT
  unsigned int *sat = new unsigned int[width*height];
  float * satSquared = new float[width*height];
  SAT(dataGray,sat,width,height);
  SATSquared(dataGray,satSquared,width,height);

  // do thresh
  thresh(dataGray, sat, satSquared, width, height, k, window);
  if(inv){invert(dataGray,width,height);}

  char filename[200];
  sprintf(filename,"%sresRaw.bmp",dir);
  if(debugImages){saveImage(filename, width, height, 1, dataGray);}

  unsigned char ** pyramid=NULL;
  makePyramid(dataGray, &pyramid, pyramidLevels, gaussPyramidThresh, width,height);

  for(int L=0; L<pyramidLevels; L++){
    char filename[200];
    sprintf(filename,"%sres_raw_%d.bmp",dir,L);
    if(debugImages){saveImage(filename,width/pow(2,L),height/pow(2,L),1,pyramid[L]);}
  }


  // label
  int vecSizeY=32;
  int vecSizeX=128;

  unsigned char *dist=new unsigned char[width*height];
  unsigned short *labels = new unsigned short[width*height];
  unsigned short area[maxLabels];
  unsigned char *reason = new unsigned char[width*height];
  unsigned char *tile = new unsigned char[width*height];
  
  for(int l = pyramidLevels-1; l>=0; l--){
    int lw = width/pow(2,l);
    int lh = height/pow(2,l);
    
    // write out debug data
    char filename[200];
    sprintf(filename,"%sres_%dp2.bmp",dir,l);
    if(debugImages){saveImage(filename, lw,lh, 1, pyramid[l]);}
  }

  for(int L = pyramidLevels-1; L>=0; L--){
    int lw = width/pow(2,L);
    int lh = height/pow(2,L);

    // clear out labels so that we can do progressive cleanup passes
    for(int i=0; i<lw*lh; i++){reason[i]=0;labels[i]=0;}

    unsigned short firstId = 1;

    int tileId = 0;

    int minArea = 6;
    if(L<2){minArea = 30;}

    int nTilesX = ceil((float)lw/(float)vecSizeX);
    int nTilesY = ceil((float)lh/(float)vecSizeY);

    int lastFixup = 0;

    for(int by=0; by<nTilesY; by++){
      int endY = (by+1)*vecSizeY;
      if(endY>lh){endY=lh;}
      
      bool fixupRanThisRow = false;

      for(int bx=0; bx<nTilesX; bx++){

	int endX = (bx+1)*vecSizeX;
	if(endX>lw){endX=lw;}

	label(pyramid[L],labels,reason,area,lw,lh,minArea,vecSizeX*bx,endX,vecSizeY*by,endY,maxLabels);
	unsigned short lastId=0;
	if(!condenseLabels(labels,area,firstId,&lastId,lw,lh,vecSizeX*bx,endX,vecSizeY*by,endY,maxLabels)){
	  printf("Error: ran out of labels!\n");
	  goto writeout;  // an exception occured
	}
	firstId=lastId+1;
	//printf("ML %d\n",(int)firstId);
	
	// for debugging
	for(int x=vecSizeX*bx; x<endX; x++){
	  for(int y=vecSizeY*by; y<endY; y++){
	    tile[x+y*lw]=tileId;
	  }
	}

	tileId++;

	if(firstId > (maxLabels*4)/5 && !fixupRanThisRow){
	  labelProp(labels,area,lw,lh,0,lw,0,endY,maxLabels);
	  filter(pyramid,L,reason,labels,minArea,lw,lh,width,0,lw,lastFixup,endY,maxLabels);
	  computeArea(labels,area,lw,lh,0,lw,0,endY,maxLabels);
	  condenseLabels(labels,area,1,&firstId,lw,lh,0,lw,0,endY,maxLabels);
	  firstId++;
	  printf("fixup TL %d\n",firstId);
	  
	  lastFixup = (by+1)*vecSizeY;
	  fixupRanThisRow=true;
	}
	
      }

    }
    
    // fix labels across region boundries
    labelProp(labels,area,lw,lh,0,lw,0,lh,maxLabels);
    computeArea(labels,area,lw,lh,0,lw,0,lh,maxLabels);
    condenseLabels(labels,area,1,&firstId,lw,lh,0,lw,0,lh,maxLabels);
    //printf("TL %d\n",firstId);
    
    distanceTransform(pyramid[L],dist,0,lw,lh);
    
    filter(pyramid,L,reason,labels,minArea,lw,lh,width,0,lw,0,lh,maxLabels);

    // now what's left "must" be text, so delete it from other pyrmid levels and save it
    
    writeout:
    // write out debug data
    char filename[200];
    if(debugImages){
      sprintf(filename,"%sL_%d.bmp",dir,L);
      saveImage(filename, lw,lh, labels);
      sprintf(filename,"%sD_%d.bmp",dir,L);
      saveImage(filename, lw,lh, 1, dist);
      sprintf(filename,"%sres_%d.bmp",dir,L);
      saveImage(filename, lw,lh, 1, pyramid[L]);
      sprintf(filename,"%sR_%d.bmp",dir,L);
      saveImage(filename, lw,lh, 1, reason);
      sprintf(filename,"%sT_%d.bmp",dir,L);
      saveImage(filename, lw,lh, 1, tile);
    }

    if(L==pyramidLevels-1){
      for(int l = 2; l>=0; l--){
	int lw = width/pow(2,l);
	int lh = height/pow(2,l);
	
	// write out debug data
	char filename[200];
	sprintf(filename,"%sres_%dp.bmp",dir,l);
	if(debugImages){saveImage(filename, lw,lh, 1, pyramid[l]);}
      }
    }
    
  }
  
  for(int y=0; y<height; y++){
    for(int x=0; x<width; x++){
      int count=0;
      for(int l=0; l<pyramidLevels; l++){
	int lx = x/pow(2,l);
	int ly = y/pow(2,l);

	int lw = width/pow(2,l);

	if(pyramid[l][lx+ly*lw]){count++;}
      }
      if(count<finalMixThresh){
	dataGray[x+y*width]=0;
      }
    }
  }

  sprintf(filename,"%sres.bmp",dir);
  saveImage(filename, width, height, 1, dataGray);

  return 0;
}