예제 #1
0
void Arc3DModel::depthFilter(FloatImage &depthImgf, FloatImage &countImgf, float depthJumpThr,
														 bool dilation, int dilationNumPasses, int dilationWinsize,
														 bool erosion, int erosionNumPasses, int erosionWinsize)
{
	FloatImage depth;
	FloatImage depth2;
	int w = depthImgf.w;
	int h = depthImgf.h;

	depth=depthImgf;

	if (dilation)
	{
		for (int k = 0; k < dilationNumPasses; k++)
		{
			depth.Dilate(depth2, dilationWinsize / 2);
			depth=depth2;
		}
	}

	if (erosion)
	{
		for (int k = 0; k < erosionNumPasses; k++)
		{
			depth.Erode(depth2, erosionWinsize / 2);
			depth=depth2;
		}
	}

  Histogramf HH;
  HH.Clear();
  HH.SetRange(0,depthImgf.MaxVal()-depthImgf.MinVal(),10000);
  for(int i=1; i < static_cast<int>(depthImgf.v.size()); ++i)
    HH.Add(fabs(depthImgf.v[i]-depth.v[i-1]));

  int deletedCnt=0;

  depthJumpThr = static_cast<float>(HH.Percentile(0.8));
    for (int y = 0; y < h; y++)
        for (int x = 0; x < w; x++)
        {
                if ((depthImgf.Val(x, y) - depth.Val(x, y)) / depthImgf.Val(x, y) > 0.6)
        {
                    countImgf.Val(x, y) = 0.0f;
          ++deletedCnt;
        }
        }

    countImgf.convertToQImage().save("tmp_filteredcount.jpg","jpg");

}
예제 #2
0
Point3m Arc3DModel::TraCorrection(CMeshO &m, int subsampleFactor, int minCount, int smoothSteps)
{
    FloatImage depthImgf;
    CharImage countImgc;
    depthImgf.Open(depthName.toUtf8().data());
    countImgc.Open(countName.toUtf8().data());

    QImage TextureImg;
    TextureImg.load(textureName);

    CombineHandMadeMaskAndCount(countImgc,maskName);  // set count to zero for all masked points

    FloatImage depthSubf;  // the subsampled depth image
    FloatImage countSubf;  // the subsampled quality image (quality == count)

    SmartSubSample(subsampleFactor,depthImgf,countImgc,depthSubf,countSubf,minCount);

    CharImage FeatureMask; // the subsampled image with (quality == features)
    GenerateGradientSmoothingMask(subsampleFactor, TextureImg, FeatureMask);

    depthSubf.convertToQImage().save("tmp_depth.jpg", "jpg");

    float depthThr = ComputeDepthJumpThr(depthSubf,0.8f);
    for(int ii=0;ii<smoothSteps;++ii)
        Laplacian2(depthSubf,countSubf,minCount,FeatureMask,depthThr);

    vcg::tri::Grid<CMeshO>(m,depthSubf.w,depthSubf.h,depthImgf.w,depthImgf.h,&*depthSubf.v.begin());

    // The depth is filtered and the minimum count mask is update accordingly.
    // To be more specific the border of the depth map are identified by erosion
    // and the relative vertex removed (by setting mincount equal to 0).
    ComputeDepthJumpThr(depthSubf,0.95f);

    int vn = m.vn;
    for(int i=0;i<vn;++i)
        if(countSubf.v[i]<minCount)
        {
            m.vert[i].SetD();
            m.vn--;
        }

        cam.Open(cameraName.toUtf8().data());

        CMeshO::VertexIterator vi;
        Matrix33d Rinv= Inverse(cam.R);
        Point3m correction(0.0,0.0,0.0);
        int numSamp=0;

        for(vi=m.vert.begin();vi!=m.vert.end();++vi)if(!(*vi).IsD())
        {
            Point3m in=(*vi).P();
            Point3d out;
            correction+=cam.DepthTo3DPoint(in[0], in[1], in[2], out);
            numSamp++;

        }
        if (numSamp!=0)
            correction/=(double)numSamp;

        return correction;

}
예제 #3
0
bool Arc3DModel::BuildMesh(CMeshO &m, int subsampleFactor, int minCount, float minAngleCos, int smoothSteps,
    bool dilation, int dilationPasses, int dilationSize,
    bool erosion, int erosionPasses, int erosionSize,float scalingFactor)
{
    FloatImage depthImgf;
    CharImage countImgc;
    clock();
    depthImgf.Open(depthName.toUtf8().data());
    countImgc.Open(countName.toUtf8().data());

    QImage TextureImg;
    TextureImg.load(textureName);
    clock();

    CombineHandMadeMaskAndCount(countImgc,maskName);  // set count to zero for all masked points

    FloatImage depthSubf;  // the subsampled depth image
    FloatImage countSubf;  // the subsampled quality image (quality == count)

    SmartSubSample(subsampleFactor,depthImgf,countImgc,depthSubf,countSubf,minCount);

    CharImage FeatureMask; // the subsampled image with (quality == features)
    GenerateGradientSmoothingMask(subsampleFactor, TextureImg, FeatureMask);

    depthSubf.convertToQImage().save("tmp_depth.jpg", "jpg");

    clock();

    float depthThr = ComputeDepthJumpThr(depthSubf,0.8f);
    for(int ii=0;ii<smoothSteps;++ii)
        Laplacian2(depthSubf,countSubf,minCount,FeatureMask,depthThr);

    clock();

    vcg::tri::Grid<CMeshO>(m,depthSubf.w,depthSubf.h,depthImgf.w,depthImgf.h,&*depthSubf.v.begin());

    clock();


    // The depth is filtered and the minimum count mask is update accordingly.
    // To be more specific the border of the depth map are identified by erosion
    // and the relative vertex removed (by setting mincount equal to 0).
    float depthThr2 = ComputeDepthJumpThr(depthSubf,0.95f);
    depthFilter(depthSubf, countSubf, depthThr2,
        dilation, dilationPasses, dilationSize,
        erosion, erosionPasses, erosionSize);

    int vn = m.vn;
    for(int i=0;i<vn;++i)
        if(countSubf.v[i]<minCount)
        {
            m.vert[i].SetD();
            m.vn--;
        }

        cam.Open(cameraName.toUtf8().data());

        CMeshO::VertexIterator vi;
        Matrix33d Rinv= Inverse(cam.R);

        for(vi=m.vert.begin();vi!=m.vert.end();++vi)if(!(*vi).IsD())
        {
            Point3m in=(*vi).P();
            Point3d out;
            cam.DepthTo3DPoint(in[0], in[1], in[2], out);

            (*vi).P().Import(out);
            QRgb c = TextureImg.pixel(int(in[0]), int(in[1]));
            vcg::Color4b tmpcol(qRed(c),qGreen(c),qBlue(c),0);
            (*vi).C().Import(tmpcol);
            if(FeatureMask.Val(int(in[0]/subsampleFactor), int(in[1]/subsampleFactor))<200) (*vi).Q()=0;
            else (*vi).Q()=1;
            (*vi).Q()=float(FeatureMask.Val(in[0]/subsampleFactor, in[1]/subsampleFactor))/255.0;
        }

        clock();

        CMeshO::FaceIterator fi;
        Point3m CameraPos = Point3m::Construct(cam.t);
        for(fi=m.face.begin();fi!=m.face.end();++fi)
        {

            if((*fi).V(0)->IsD() ||(*fi).V(1)->IsD() ||(*fi).V(2)->IsD() )
            {
                (*fi).SetD();
                --m.fn;
            }
            else
            {
                Point3m n=vcg::TriangleNormal(*fi);
                n.Normalize();
                Point3m dir=CameraPos-vcg::Barycenter(*fi);
                dir.Normalize();
                if(dir.dot(n) < minAngleCos)
                {
                    (*fi).SetD();
                    --m.fn;
                }
            }
        }

        tri::Clean<CMeshO>::RemoveUnreferencedVertex(m);
        clock();

        Matrix44m scaleMat;
        scaleMat.SetScale(scalingFactor,scalingFactor,scalingFactor);
        vcg::tri::UpdatePosition<CMeshO>::Matrix(m, scaleMat);

        return true;
}