예제 #1
0
cv::Mat blurPatch(const cv::Mat &_patch, cv::Point2f one, cv::Point2f two) {
    cv::Mat blurredWindow = _patch.clone();
    //std::cout << "Start Blurring" << std::endl;

    cv::Mat patch = _patch.clone();
    patch.convertTo(patch, cv::DataType<double>::type);

	cv::Mat kernel = evaluateKernel(one,two);

	cv::Point2f anchor = cv::Point( -1, -1 );

	int delta = 0, ddepth = -1;
	filter2D(patch, patch, ddepth, kernel, anchor, delta, cv::BORDER_DEFAULT);

    patch.convertTo(patch, CV_8U);
    //std::cout << "Stop Blurring" << std::endl;

  //  hconcat(blurredWindow, patch, blurredWindow);
  //  imshow("Blurring", blurredWindow);
  //  cv::waitKey(1);

	return patch;
}
예제 #2
0
파일: Solver.cpp 프로젝트: segfault11/SPH2S
//------------------------------------------------------------------------------
void Solver::computeAcceleration (unsigned char res)
{
    IDList::const_iterator i = mFluidParticles[res]->ActiveIDs.begin();
    IDList::const_iterator e = mFluidParticles[res]->ActiveIDs.end();

    for (; i != e; i++)
    {
        float *pos = &mFluidParticles[res]->Positions[2*(*i)];
        float *vel = &mVelocities[res][2*(*i)];
        float *acc = &mAccelerations[res][2*(*i)];
        float den = mDensities[res][*i];
        float pre = mPressures[res][*i];


        //	std::cout << mDensities[LOW][*i] << std::endl;

        float ene[2];
        ene[0] = 0.0f;
        ene[1] = 0.0f;
        float psiSum = 0.0f;

        // reset acc
        acc[0] = 0.0f;
        acc[1] = 0.0f;

        // reserve mem for tension force
        float accT[2];
        accT[0] = 0.0f;
        accT[1] = 0.0f;

        // reserve mem for boundary force
        float accB[2];
        accB[0] = 0.0f;
        accB[1] = 0.0f;

        //======================================================================
        // 	Compute force contribution from the same domain
        //======================================================================

        // get neighbor ids
        mFluidHashTable[res]->Query(Vector2f(pos));
        const IDList& neighbors = mFluidHashTable[res]->GetResult();

        IDList::const_iterator j = neighbors.begin();
        IDList::const_iterator je = neighbors.end();

        for (; j != je; j++)
        {
            float *posj = &mFluidParticles[res]->Positions[2*(*j)];
            float *velj = &mVelocities[res][2*(*j)];
            float denj = mDensities[res][*j];
            float prej = mPressures[res][*j];
            float dist = computeDistance(pos, posj);
            float xij[2];
            xij[0] = pos[0] - posj[0];
            xij[1] = pos[1] - posj[1];
            float vij[2];
            vij[0] = vel[0] - velj[0];
            vij[1] = vel[1] - velj[1];

            if (dist < mConfiguration.EffectiveRadius[res])
            {
                // compute SPH pressure coefficient
                float coeff = (pre/(den*den) + prej/(denj*denj));
                float vx = computeDotProduct(xij, vij);
                float h = mConfiguration.EffectiveRadius[res];

                // check if artificial viscosity shoud be applied
                if (vx < 0.0f)
                {
                    // add artificial velocity to the SPH Force coefficient
                    float x2 = dist*dist;
                    float nu = -2.0f*mConfiguration.Alpha*h*
                               mConfiguration.SpeedSound/(den + denj);
                    coeff += nu*vx/(x2 + 0.01f*h*h);
                }

                // evaluate kernel gradient and add contribution of particle j
                // to acc
                Vector2f grad = evaluateKernelGradient(Vector2f(xij), dist, h);
                acc[0] += mBlendValues[res][*j]*coeff*grad.X;
                acc[1] += mBlendValues[res][*j]*coeff*grad.Y;

                // compute tension force and add to the acc
                float kernelT = mBlendValues[res][*j]*evaluateKernel(dist, h);
                accT[0] -= mConfiguration.TensionCoefficient*xij[0]*kernelT;
                accT[1] -= mConfiguration.TensionCoefficient*xij[1]*kernelT;


                float w2 = mConfiguration.FluidParticleMass[res]/
                           mConfiguration.FluidParticleMass[LOW];
                float mw = w2*mexicanHat2D
                           (
                               xij[0]/mConfiguration.EffectiveRadius[LOW],
                               xij[1]/mConfiguration.EffectiveRadius[LOW]
                           );
                ene[0] += velj[0]*mw;
                ene[1] += velj[1]*mw;
                psiSum += mw;

                mStates[res][*i] |= (mStates[res][*j] << 1) & 0x04;

            }

        }

        //======================================================================
        // 	Compute force contribution from the contemp. domain
        //======================================================================

        float accC[2];
        accC[0] = 0.0f;
        accC[1] = 0.0f;

        float accCT[2];
        accCT[0] = 0.0f;
        accCT[1] = 0.0f;

        unsigned char resc = (res + 1) % 2;
        mFluidHashTable[resc]->Query
        (
            Vector2f(pos),
            mConfiguration.EffectiveRadius[LOW]
        );
        const IDList& neighborsc = mFluidHashTable[resc]->GetResult();

        IDList::const_iterator jc = neighborsc.begin();
        IDList::const_iterator jce = neighborsc.end();

        for (; jc != jce; jc++)
        {
            float *posj = &mFluidParticles[resc]->Positions[2*(*jc)];
            float *velj = &mVelocities[resc][2*(*jc)];
            float denj = mDensities[resc][*jc];
            float prej = mPressures[resc][*jc];
            float dist = computeDistance(pos, posj);
            float xij[2];
            xij[0] = pos[0] - posj[0];
            xij[1] = pos[1] - posj[1];
            float vij[2];
            vij[0] = vel[0] - velj[0];
            vij[1] = vel[1] - velj[1];

            if (dist < mConfiguration.EffectiveRadius[LOW])
            {
                // compute SPH pressure coefficient
                float coeff = (pre/(den*den) + prej/(denj*denj));
                float vx = computeDotProduct(xij, vij);
                float h = mConfiguration.EffectiveRadius[res];
                float hc = mConfiguration.EffectiveRadius[resc];

                if (vx < 0.0f)
                {
                    // add artificial velocity to the SPH Force coefficient
                    float x2 = dist*dist;
                    float nu = -2.0f*mConfiguration.Alpha*h*
                               mConfiguration.SpeedSound/(den + denj);
                    coeff += nu*vx/(x2 + 0.01f*h*h);
                }

                Vector2f grad = evaluateKernelGradient
                                (
                                    Vector2f(xij),
                                    dist,
                                    h
                                );
                Vector2f gradc = evaluateKernelGradient
                                 (
                                     Vector2f(xij),
                                     dist,
                                     hc
                                 );

                accC[0] += mBlendValues[resc][*jc]*coeff*
                           (grad.X + gradc.X)*0.5f;
                accC[1] += mBlendValues[resc][*jc]*coeff*
                           (grad.Y + gradc.Y)*0.5f;

                float wt = evaluateKernel(dist, h);
                float wct = evaluateKernel(dist, hc);

                accCT[0] -= mConfiguration.TensionCoefficient*xij[0]*
                            (wt + wct)/2.0f*mBlendValues[resc][*jc];
                accCT[1] -= mConfiguration.TensionCoefficient*xij[1]*
                            (wt + wct)/2.0f*mBlendValues[resc][*jc];


                float w3 = 1.0f;
                if (res == HIGH && dist > mConfiguration.EffectiveRadius[HIGH])
                {
                    w3 = 0.0f;
                }

                float w2 = mConfiguration.FluidParticleMass[res]/
                           mConfiguration.FluidParticleMass[LOW];
                float mw = w3*w2*mexicanHat2D
                           (
                               xij[0]/mConfiguration.EffectiveRadius[LOW],
                               xij[1]/mConfiguration.EffectiveRadius[LOW]
                           );
                ene[0] += velj[0]*mw;
                ene[1] += velj[1]*mw;
                psiSum += mw;

                mStates[res][*i] |= (mStates[res][*jc] << 1) & 0x04;
            }

        }

        //======================================================================
        // 	compute penalty force of the boundary
        //======================================================================

        mBoundaryHashTable->Query(Vector2f(pos));
        const IDList& bneighbors = mBoundaryHashTable->GetResult();

        IDList::const_iterator k = bneighbors.begin();
        IDList::const_iterator ke = bneighbors.end();

        for (; k != ke; k++)
        {
            float *posk = &mBoundaryParticles->Positions[2*(*k)];
            float xik[2];
            xik[0] = pos[0] - posk[0];
            xik[1] = pos[1] - posk[1];
            float dist = computeNorm(xik);

            if (dist < mConfiguration.EffectiveRadius[LOW])
            {
                float w = evaluateBoundaryWeight
                          (
                              dist,
                              mConfiguration.EffectiveRadius[LOW],
                              mConfiguration.SpeedSound
                          );
                float c = mConfiguration.BoundaryParticleMass/
                          (mConfiguration.FluidParticleMass[LOW] +
                           mConfiguration.BoundaryParticleMass);

                float d = c*w;
                accB[0] += d*xik[0];
                accB[1] += d*xik[1];
            }

        }

        //======================================================================
        // 	Update acceleration of particle i
        //======================================================================

        acc[0] *= -mConfiguration.FluidParticleMass[res];
        acc[1] *= -mConfiguration.FluidParticleMass[res];
        accC[0] *= -mConfiguration.FluidParticleMass[resc];
        accC[1] *= -mConfiguration.FluidParticleMass[resc];
        accCT[0] *= (mConfiguration.FluidParticleMass[resc]/
                     mConfiguration.FluidParticleMass[res]);
        accCT[1] *= (mConfiguration.FluidParticleMass[resc]/
                     mConfiguration.FluidParticleMass[res]);
        acc[0] += accT[0];
        acc[1] += accT[1];
        acc[0] += accC[0];
        acc[1] += accC[1];
        acc[0] += accCT[0];
        acc[1] += accCT[1];
        acc[0] += accB[0];
        acc[1] += accB[1];
        acc[1] -= 9.81f;

        float energy = 1.0f/(psiSum*psiSum*mConfiguration.EffectiveRadius[res])*
                       (ene[0]*ene[0] + ene[1]*ene[1]);


        if (pos[0] > 0.5f)
        {
            //mFluidParticles[res]->Colors[*i] = 1.0f;
            mStates[res][*i] |= 0x08;
        }
        else
        {
            //mFluidParticles[res]->Colors[*i] = 0.0f;
        }
        mFluidParticles[res]->Colors[*i] = std::min
                                           (
                                               abs(energy)/200.0f,
                                               1.0f
                                           );

//		xicm[0] = pos[0] - xicm[0]/mt;
//		xicm[1] = pos[1] - xicm[1]/mt;
//
//		float col = std::min
//		(
//			computeNorm(xicm), 0.003f
//		)/0.003f;
//
//		std::cout << col << std::endl;
//
//		mFluidParticles[res]->Colors[*i] = col;
    }
}
예제 #3
0
파일: Solver.cpp 프로젝트: segfault11/SPH2S
//------------------------------------------------------------------------------
void Solver::computeDensity (unsigned char res)
{
    IDList::const_iterator i = mFluidParticles[res]->ActiveIDs.begin();
    IDList::const_iterator e = mFluidParticles[res]->ActiveIDs.end();

    for (; i != e; i++)
    {

        float xicm[2];
        xicm[0] = 0.0f;
        xicm[1] = 0.0f;
        float mt = 0.0f;


        //======================================================================
        // 	compute densities in the same domain
        //======================================================================

        float *pos = &mFluidParticles[res]->Positions[2*(*i)];

        // get neighbor ids
        mFluidHashTable[res]->Query(Vector2f(pos));
        const IDList& neighbors = mFluidHashTable[res]->GetResult();

        //
        float density = 0.0f;

        IDList::const_iterator j = neighbors.begin();
        IDList::const_iterator je = neighbors.end();

        // iterate through neighbors and add up their contribution to
        // the density of particle i
        for (; j != je; j++)
        {
            float *posj = &mFluidParticles[res]->Positions[2*(*j)];
            float posij[2];
            posij[0] = pos[0] - posj[0];
            posij[1] = pos[1] - posj[1];
            float dist = std::sqrt(posij[0]*posij[0] + posij[1]*posij[1]);

            if (dist < mConfiguration.EffectiveRadius[res])
            {
                density += mBlendValues[res][*j]*evaluateKernel
                           (
                               dist,
                               mConfiguration.EffectiveRadius[res]
                           );

                float mass = mConfiguration.FluidParticleMass[res];
                xicm[0] += mass*posj[0];
                xicm[1] += mass*posj[1];
                mt += mass;

            }

        }

        density *= mConfiguration.FluidParticleMass[res];

        //======================================================================
        // compute densities in the complementary domain
        //======================================================================

        unsigned char resc = (res + 1) % 2;
        float densityc = 0.0f;

        // get neighbor ids
        // (in the contemp. domain, we always have a search radius of the
        // low effective radius)
        mFluidHashTable[resc]->Query
        (
            Vector2f(pos),
            mConfiguration.EffectiveRadius[LOW]
        );
        const IDList& neighborsc = mFluidHashTable[resc]->GetResult();

        IDList::const_iterator jc = neighborsc.begin();
        IDList::const_iterator jce = neighborsc.end();

        for (; jc != jce; jc++)
        {
            float *posjc = &mFluidParticles[resc]->Positions[2*(*jc)];
            float posijc[2];
            posijc[0] = pos[0] - posjc[0];
            posijc[1] = pos[1] - posjc[1];
            float distc = std::sqrt(posijc[0]*posijc[0] + posijc[1]*posijc[1]);

            if (distc < mConfiguration.EffectiveRadius[LOW])
            {

                float w = evaluateKernel
                          (
                              distc,
                              mConfiguration.EffectiveRadius[res]
                          );

                float wc = evaluateKernel
                           (
                               distc,
                               mConfiguration.EffectiveRadius[resc]
                           );

                densityc += mBlendValues[resc][*jc]*0.5f*(w + wc);

                float mass = mConfiguration.FluidParticleMass[resc];
                xicm[0] += mass*posjc[0];
                xicm[1] += mass*posjc[1];
                mt += mass;

            }

        }

        densityc *= mConfiguration.FluidParticleMass[resc];

        //======================================================================
        // 	Update density and pressure of particle i
        //======================================================================

        // add contr. of contemp. domain
        density += densityc;

        mDensities[res][*i] = density;

        float a = density/mConfiguration.RestDensity;
        float a3 = a*a*a;
        mPressures[res][*i] = mConfiguration.TaitCoefficient*(a3*a3*a - 1.0f);

        xicm[0] = pos[0] - xicm[0]/mt;
        xicm[1] = pos[1] - xicm[1]/mt;


        //======================================================================
        // 	find out if particle is a surface particle
        //======================================================================
        float col = std::min
                    (
                        computeNorm(xicm), 0.003f
                    )/0.003f;

        //std::cout << col << std::endl;

        mFluidParticles[res]->Colors[*i] = col;

        if (col >= 1.0f)
        {
            mStates[res][*i] |= 0x02;
        }
        else
        {
            mStates[res][*i] &= 0xF9; // reset surf and nsurf bit
        }
    }

}
예제 #4
0
cv::Mat deblurPatch(const cv::Mat &_patch, cv::Point2f one, cv::Point2f two) {
    ////std::cout << "Start Deblurring" << one << std::endl << two << std::endl;
    cv::Mat blurredWindow = _patch.clone();
    cv::Mat patch = _patch.clone();
    patch.convertTo(patch, cv::DataType<double>::type);
    cv::Mat kernel = evaluateKernel(one,two);
//    //std::cout << " kernel" << kernel << std::endl;
	cv::Mat kernel_hat = kernel.clone(), result = patch.clone();
	cv::Mat est_conv = result.clone(), relative_blur = patch.clone(), error_est = patch.clone();
	cv::Mat patch_hat = patch.clone(), k_est_conv = kernel.clone(), k_relative_blur = kernel.clone(), k_error_est = kernel.clone();

	int rows = kernel.rows, cols = kernel.cols, maxIter = 3;
	int pRows = patch.rows, pCols = patch.cols;
	cv::Point2f anchor = cv::Point( -1, -1 );
	int delta = 0, ddepth = -1;

    double eps = DBL_MIN;
	for(int l=0; l<maxIter; l++) {

		//Improvement
		for(int i=0; i<pRows; i++)
			for(int j=0; j<pCols; j++)
				patch_hat.at<double>(i,j) = patch.at<double>(pRows-i-1,pCols-j-1);
		filter2D(kernel, k_est_conv, ddepth, patch, anchor, delta, cv::BORDER_DEFAULT);
		for(int i=0; i<rows; i++)
			for(int j=0; j<cols; j++) {
                //if(est_conv.at<double>(i,j) < eps)
				//	est_conv.at<double>(i,j) = 10*eps;
				k_relative_blur.at<double>(i,j) = kernel.at<double>(i,j) / k_est_conv.at<double>(i,j);
            }
		filter2D(k_relative_blur, k_error_est, ddepth, patch_hat);
		for(int i=0; i<rows; i++)
			for(int j=0; j<cols; j++) {
				kernel.at<double>(i,j) = kernel.at<double>(i,j) * k_error_est.at<double>(i,j);
            }

		// Classical LR
		for(int i=0; i<rows; i++)
			for(int j=0; j<cols; j++)
				kernel_hat.at<double>(i,j) = kernel.at<double>(rows-i-1,cols-j-1);
		filter2D(result, est_conv, ddepth, kernel);
		for(int i=0; i<pRows; i++)
			for(int j=0; j<pCols; j++) {
                //if(est_conv.at<double>(i,j) < eps)
				//	est_conv.at<double>(i,j) = 10*eps;
				relative_blur.at<double>(i,j) = patch.at<double>(i,j) / est_conv.at<double>(i,j);

            }
		filter2D(relative_blur, error_est, ddepth, kernel_hat, anchor, delta, cv::BORDER_DEFAULT);
		for(int i=0; i<pRows; i++)
			for(int j=0; j<pCols; j++) {
				result.at<double>(i,j) = result.at<double>(i,j) * error_est.at<double>(i,j);
            }
	}



    result.convertTo(result, CV_8U);

    hconcat(blurredWindow, result, blurredWindow);
    imshow("Deblurring", blurredWindow);


    //std::cout << "Stop Deblurring" << std::endl;

	return result;
}