Exemplo n.º 1
0
void colorize(const Image<uint32_t> &input, const Image<uint32_t> &strokes, Image<uint32_t> &output) {
    int w     = input.width();
    int h     = input.height();
    int x,y;

    int max_d          = floor(log(min(h,w))/log(2)-2);
    float scale_factor = 1.0f/( pow(2,max_d-1) );
    int padded_w       = ceil(w*scale_factor)*pow(2,max_d-1);
    int padded_h       = ceil(h*scale_factor)*pow(2,max_d-1);

    // RGB 2 YUV and padarray
    Image<float> yuv_fused(padded_w,padded_h,3);
    hl_fuse_yuv(input, strokes, yuv_fused);


    // Extract Strokes mask
    Image<float> stroke_mask(padded_w, padded_h);
    hl_nonzero(strokes,stroke_mask);

    Image<float> result(padded_w,padded_h,3);

    int n = padded_h;
    int m = padded_w;
    int k = 1;

    Tensor3d D,G,I;
    Tensor3d Dx,Dy,iDx,iDy;
    MG smk;
    G.set(n,m,k);
    D.set(n,m,k);
    I.set(n,m,k);

    int in_itr_num  = 5;
    int out_itr_num = 1;

    Dx.set(n,m,k-1);
    Dy.set(n,m,k-1);
    iDx.set(n,m,k-1);
    iDy.set(n,m,k-1);

    // Fill in label mask and luminance channels
    for ( y = 0; y<n; y++){
        for ( x = 0; x<m; x++){
            I(y,x,0) = stroke_mask(x,y);
            G(y,x,0) = yuv_fused(x,y,0);
            I(y,x,0) = !I(y,x,0);
        }
    }

    // Write output luminance
    for ( y=0; y<n; y++){
        for ( x=0; x<m; x++){
            result(x,y,0)=G(y,x,0);
        }
    }

    smk.set(n,m,k,max_d);
    smk.setI(I) ;
    smk.setG(G);
    smk.setFlow(Dx,Dy,iDx,iDy);

    // Solve chrominance
    for (int t=1; t<3; t++){
        for ( y=0; y<n; y++){
            for ( x=0; x<m; x++){
                D(y,x,0)       = yuv_fused(x,y,t);
                smk.P()(y,x,0) = yuv_fused(x,y,t);
                D(y,x,0)      *= (!I(y,x,0));
            }
        }

        smk.Div() = D ;

        Tensor3d tP2;

        for (int itr=0; itr<out_itr_num; itr++){
            smk.setDepth(max_d);
            Field_MGN(&smk, in_itr_num, 2) ;
            smk.setDepth(ceil(max_d/2));
            Field_MGN(&smk, in_itr_num, 2) ;
            smk.setDepth(2);
            Field_MGN(&smk, in_itr_num, 2) ;
            smk.setDepth(1);
            Field_MGN(&smk, in_itr_num, 4) ;
        }

        tP2 = smk.P();

        for ( y=0; y<n; y++){
            for ( x=0; x<m; x++){
                result(x,y,t) = tP2(y,x,0);
            }
        }
    }
    
    hl_yuv2rgb(result,output);
    

}
Exemplo n.º 2
0
int
main(int argc, char * argv[])
{
  string mesh_path;
  string samples_path;
  string out_path;

  int curr_opt = 0;
  for (int i = 1; i < argc; ++i)
  {
    string arg = argv[i];
    if (!beginsWith(arg, "-"))
    {
      switch (curr_opt)
      {
        case 0: mesh_path = arg; break;
        case 1: samples_path = arg; break;
        case 2: out_path = arg; break;
      }

      curr_opt++;
      if (curr_opt > 3)
        break;
    }
    else
    {
      if (beginsWith(arg, "--max-nbrs="))
      {
        if (sscanf(arg.c_str(), "--max-nbrs=%d", &max_nbrs) != 1 || max_nbrs <= 0)
        {
          THEA_ERROR << "Invalid --max-nbrs parameter";
          return -1;
        }
      }
      else if (beginsWith(arg, "--min-samples="))
      {
        if (sscanf(arg.c_str(), "--min-samples=%ld", &min_samples) != 1 || min_samples <= 0)
        {
          THEA_ERROR << "Invalid --min-samples parameter";
          return -1;
        }
      }
      else if (arg == "-n" || arg == "--normals")
      {
        consistent_normals = true;
      }
      else if (arg == "-r" || arg == "--reachability")
      {
        reachability = true;
      }
      else
      {
        THEA_ERROR << "Unknown parameter: " << arg;
        return -1;
      }
    }
  }

  if (curr_opt != 3)
  {
    THEA_CONSOLE << "";
    THEA_CONSOLE << "Usage: " << argv[0] << " [OPTIONS] <mesh|dense-points> <points> <graph-outfile>";
    THEA_CONSOLE << "";
    THEA_CONSOLE << "Options:";
    THEA_CONSOLE << "  --max-nbrs=N          Maximum degree of proximity graph";
    THEA_CONSOLE << "  --min-samples=N       Minimum number of original plus generated samples";
    THEA_CONSOLE << "  --normals | -n        Run extra tests assuming consistently oriented mesh normals";
    THEA_CONSOLE << "  --reachability | -r   Reachability test for adjacency (requires -n)";
    THEA_CONSOLE << "";

    return -1;
  }

  if (reachability && !consistent_normals)
  {
    THEA_ERROR << "Reachability test requires consistent normals";
    return -1;
  }

  //===========================================================================================================================
  // Load points
  //===========================================================================================================================

  TheaArray<Vector3> sample_positions;
  TheaArray<Vector3> sample_normals;
  if (loadSamples(samples_path, sample_positions, sample_normals))
    return -1;

  bool has_normals = (!sample_positions.empty() && sample_normals.size() == sample_positions.size());

  THEA_CONSOLE << "Loaded " << sample_positions.size() << " sample(s) from " << samples_path;

  //===========================================================================================================================
  // Load mesh or dense samples
  //===========================================================================================================================

  TheaArray<Vector3> dense_positions;
  TheaArray<Vector3> dense_normals;
  bool dense_has_normals = false;
  KDTree kdtree;
  if (mesh_path != "-")
  {
    // First try to load the file as a set of points
    int dense_load_status = loadSamples(mesh_path, dense_positions, dense_normals);
    dense_has_normals = (!dense_positions.empty() && dense_normals.size() == dense_positions.size());

    if (dense_load_status != 0 && dense_load_status != UNSUPPORTED_FORMAT)
    {
      return -1;
    }
    else if (dense_load_status == 0)
    {
      THEA_CONSOLE << dense_positions.size() << " extra samples added from: " << mesh_path;
    }
    else  // Now try to load the file as a mesh, if the above failed
    {
      MG mg;
      try
      {
        mg.load(mesh_path);
      }
      THEA_STANDARD_CATCH_BLOCKS(return -1;, ERROR, "Could not load mesh %s", mesh_path.c_str())

      THEA_CONSOLE << "Loaded mesh from " << mesh_path;

      // Make sure the mesh is properly scaled
      AxisAlignedBox3 mesh_bounds = mg.getBounds();
      AxisAlignedBox3 samples_bounds;
      for (array_size_t i = 0; i < sample_positions.size(); ++i)
        samples_bounds.merge(sample_positions[i]);

      Real scale_error = (mesh_bounds.getLow()  - samples_bounds.getLow()).length()
                       + (mesh_bounds.getHigh() - samples_bounds.getHigh()).length();
      if (scale_error > 0.01 * mesh_bounds.getExtent().length())
      {
        // Rescale the mesh
        Real scale = (samples_bounds.getExtent() / mesh_bounds.getExtent()).max();  // samples give a smaller bound than the
                                                                                    // true bound, so take the axis in which
                                                                                    // the approximation is best

        AffineTransform3 tr = AffineTransform3::translation(samples_bounds.getCenter())
                            * AffineTransform3::scaling(scale)
                            * AffineTransform3::translation(-mesh_bounds.getCenter());
        MeshTransformer func(tr);
        mg.forEachMeshUntil(&func);
        mg.updateBounds();

        THEA_CONSOLE << "Matched scale of source mesh and original samples";
      }

      kdtree.add(mg);
      kdtree.init();

      // If the samples have no normals, compute them
      if (consistent_normals && !has_normals)
      {
        sample_normals.resize(sample_positions.size());

        for (array_size_t i = 0; i < sample_positions.size(); ++i)
        {
          long elem = kdtree.closestElement<MetricL2>(sample_positions[i]);
          if (elem < 0)
          {
            THEA_ERROR << "Could not find nearest neighbor of sample " << i << " on mesh";
            return false;
          }

          sample_normals[i] = kdtree.getElements()[(array_size_t)elem].getNormal();
        }

        has_normals = true;

        THEA_CONSOLE << "Computed sample normals";
      }

      // Augment the number of samples if necessary
      if ((long)sample_positions.size() < min_samples)
      {
        dense_positions.clear();
        dense_normals.clear();

        MeshSampler<Mesh> sampler(mg);
        sampler.sampleEvenlyByArea((long)(min_samples - sample_positions.size()), dense_positions,
                                   (consistent_normals ? &dense_normals : NULL));

        if (!dense_positions.empty())
          THEA_CONSOLE << dense_positions.size() << " extra samples added to original set, for density";

        dense_has_normals = (!dense_positions.empty() && dense_normals.size() == dense_positions.size());
      }
    }
Exemplo n.º 3
0
void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[]){
  int winSize=int(mxGetScalar(prhs[2])+0.5);
  int deg=int(mxGetScalar(prhs[3])+0.5);

  const int*  sizes;
  sizes=mxGetDimensions(prhs[1]);
  int sizel;
  sizel=mxGetNumberOfDimensions(prhs[1]);
  int n=sizes[1];
  int m=sizes[0];
  int k,max_d, max_d1,max_d2, in_itr_num, out_itr_num, itr;
  int x,y,z;

  if (sizel>3){
    k=sizes[3];
  }else{
    k=1;
  }
  max_d1=int(floor(log(n)/log(2)-2)+0.1);
  max_d2=int(floor(log(m)/log(2)-2)+0.1);
  if (max_d1>max_d2){
    max_d=max_d2;
  }else{
    max_d=max_d1;
  }
  double *lblImg_pr, *img_pr;
  double * res_pr;
  double **res_prv;
  double *dx_pr,*dy_pr,*idx_pr,*idy_pr;
  lblImg_pr=mxGetPr(prhs[0]);

  img_pr=mxGetPr(prhs[1]);
  Tensor3d D,G,I;
  Tensor3d Dx,Dy,iDx,iDy;
  MG smk;
  G.set(m,n,k);
  D.set(m,n,k);
  I.set(m,n,k);

  dy_pr=mxGetPr(prhs[2]);
  dx_pr=mxGetPr(prhs[3]);
  idy_pr=mxGetPr(prhs[4]);
  idx_pr=mxGetPr(prhs[5]);

  if (nrhs>6){
    in_itr_num=int(mxGetScalar(prhs[6])+0.5);
  }else{
    in_itr_num=5;
  }
  if (nrhs>7){
    out_itr_num=int(mxGetScalar(prhs[7])+0.5);
  }else{
    out_itr_num=2;
  }

  Dx.set(m,n,k-1);
  Dy.set(m,n,k-1);
  iDx.set(m,n,k-1);
  iDy.set(m,n,k-1);
  for ( z=0; z<(k-1); z++){
    for ( y=0; y<n; y++){
      for ( x=0; x<m; x++){
	Dx(x,y,z)=*dx_pr; dx_pr++;
	Dy(x,y,z)=*dy_pr; dy_pr++;
	iDx(x,y,z)=*idx_pr; idx_pr++;
	iDy(x,y,z)=*idy_pr; idy_pr++;
      }
    }
  }

  int dims[4];
  dims[0]=m; dims[1]=n; dims[2]=3; dims[3]=k;
  plhs[0]=mxCreateNumericArray(4,dims,  mxDOUBLE_CLASS ,mxREAL);
  res_pr=mxGetPr(plhs[0]);
  res_prv=new double*[k];
  for (z=0; z<k; z++){
    res_prv[z]=res_pr+n*m*3*z;
  }


  for ( z=0; z<k; z++){
    for ( y=0; y<n; y++){
      for ( x=0; x<m; x++){
	I(x,y,z)=lblImg_pr[x+m*y+z*n*m];
	G(x,y,z)=img_pr[x+y*m+z*m*n*3];
	I(x,y,z)=!I(x,y,z);
      }
    }
  }

  for ( z=0; z<k; z++){
    for ( y=0; y<n; y++){
      for ( x=0; x<m; x++){
	(*res_prv[z])=G(x,y,z);
	res_prv[z]++;
      }
    }
  }
  smk.set(m,n,k,max_d);
  smk.setI(I) ;
  smk.setG(G);
  smk.setFlow(Dx,Dy,iDx,iDy);

  for (int t=1; t<3; t++){
     for ( z=0; z<k; z++){
       for ( y=0; y<n; y++){
	 for ( x=0; x<m; x++){
	   D(x,y,z)=img_pr[x+y*m+n*m*t+z*m*n*3];
	   smk.P()(x,y,z)=img_pr[x+y*m+n*m*t+z*m*n*3];
	   D(x,y,z)*=(!I(x,y,z));
	 }
       }
     }

     smk.Div() = D ;


     Tensor3d tP2;


     if (k==1){
       for (itr=0; itr<out_itr_num; itr++){
	 smk.setDepth(max_d);
	 Field_MGN(&smk, in_itr_num, 2) ;
	 smk.setDepth(ceil(max_d/2));
	 Field_MGN(&smk, in_itr_num, 2) ;
	 smk.setDepth(2);
	 Field_MGN(&smk, in_itr_num, 2) ;
	 smk.setDepth(1);
	 Field_MGN(&smk, in_itr_num, 4) ;
       }
     } else{
       for (itr=0; itr<out_itr_num; itr++){
	 smk.setDepth(2);
	 Field_MGN(&smk, in_itr_num, 2) ;
	 smk.setDepth(1);
	 Field_MGN(&smk, in_itr_num, 4) ;
	}
     }


     tP2=smk.P();

     for ( z=0; z<k; z++){
       for ( y=0; y<n; y++){
	 for ( x=0; x<m; x++){
	   (*res_prv[z])=tP2(x,y,z);
	   res_prv[z]++;
	 }
       }
     }
  }
}