void MapperGradSimilar::calculate(
    const cv::Mat& img1, const cv::Mat& image2, cv::Ptr<Map>& res) const
{
    Mat gradx, grady, imgDiff;
    Mat img2;

    CV_DbgAssert(img1.size() == image2.size());
    CV_DbgAssert(img1.channels() == image2.channels());
    CV_DbgAssert(img1.channels() == 1 || img1.channels() == 3);

    if(!res.empty()) {
        // We have initial values for the registration: we move img2 to that initial reference
        res->inverseWarp(image2, img2);
    } else {
        img2 = image2;
    }

    // Get gradient in all channels
    gradient(img1, img2, gradx, grady, imgDiff);

    // Matrices with reference frame coordinates
    Mat grid_r, grid_c;
    grid(img1, grid_r, grid_c);

    // Calculate parameters using least squares
    Matx<double, 4, 4> A;
    Vec<double, 4> b;
    // For each value in A, all the matrix elements are added and then the channels are also added,
    // so we have two calls to "sum". The result can be found in the first element of the final
    // Scalar object.
    Mat xIx_p_yIy = grid_c.mul(gradx);
    xIx_p_yIy += grid_r.mul(grady);
    Mat yIx_m_xIy = grid_r.mul(gradx);
    yIx_m_xIy -= grid_c.mul(grady);

    A(0, 0) = sum(sum(sqr(xIx_p_yIy)))[0];
    A(0, 1) = sum(sum(xIx_p_yIy.mul(yIx_m_xIy)))[0];
    A(0, 2) = sum(sum(gradx.mul(xIx_p_yIy)))[0];
    A(0, 3) = sum(sum(grady.mul(xIx_p_yIy)))[0];

    A(1, 1) = sum(sum(sqr(yIx_m_xIy)))[0];
    A(1, 2) = sum(sum(gradx.mul(yIx_m_xIy)))[0];
    A(1, 3) = sum(sum(grady.mul(yIx_m_xIy)))[0];

    A(2, 2) = sum(sum(sqr(gradx)))[0];
    A(2, 3) = sum(sum(gradx.mul(grady)))[0];

    A(3, 3) = sum(sum(sqr(grady)))[0];

    // Lower half values (A is symmetric)
    A(1, 0) = A(0, 1);
    A(2, 0) = A(0, 2);
    A(3, 0) = A(0, 3);

    A(2, 1) = A(1, 2);
    A(3, 1) = A(1, 3);

    A(3, 2) = A(2, 3);

    // Calculation of b
    b(0) = -sum(sum(imgDiff.mul(xIx_p_yIy)))[0];
    b(1) = -sum(sum(imgDiff.mul(yIx_m_xIy)))[0];
    b(2) = -sum(sum(imgDiff.mul(gradx)))[0];
    b(3) = -sum(sum(imgDiff.mul(grady)))[0];

    // Calculate affine transformation. We use Cholesky decomposition, as A is symmetric.
    Vec<double, 4> k = A.inv(DECOMP_CHOLESKY)*b;

    Matx<double, 2, 2> linTr(k(0) + 1., k(1), -k(1), k(0) + 1.);
    Vec<double, 2> shift(k(2), k(3));
    if(res.empty()) {
        res = Ptr<Map>(new MapAffine(linTr, shift));
    } else {
        MapAffine newTr(linTr, shift);
        res->compose(newTr);
   }
}
Exemplo n.º 2
0
static inline void* cvAlignPtr( const void* ptr, int align = 32 )
{
    CV_DbgAssert ( (align & (align-1)) == 0 );
    return (void*)( ((size_t)ptr + align - 1) & ~(size_t)(align-1) );
}
Exemplo n.º 3
0
static inline int cvAlign( int size, int align )
{
    CV_DbgAssert( (align & (align-1)) == 0 && size < INT_MAX );
    return (size + align - 1) & -align;
}
Exemplo n.º 4
0
 template<typename _Tp> inline const _Tp *oclMat::ptr(int y) const
 {
     CV_DbgAssert( (unsigned)y < (unsigned)rows );
     CV_Error(CV_GpuNotSupported, "This function hasn't been supported yet.\n");
     return (const _Tp *)(data + step * y);
 }
Exemplo n.º 5
0
/*!
  Aligns buffer size by the certain number of bytes

  This small inline function aligns a buffer size by the certian number of bytes by enlarging it.
*/
static inline size_t alignSize(size_t sz, int n)
{
    CV_DbgAssert((n & (n - 1)) == 0); // n is a power of 2
    return (sz + n-1) & -n;
}
Exemplo n.º 6
0
inline
const uchar* GpuMat::ptr(int y) const
{
    CV_DbgAssert( (unsigned)y < (unsigned)rows );
    return data + step * y;
}
Exemplo n.º 7
0
 inline const uchar *oclMat::ptr(int y) const
 {
     CV_DbgAssert( (unsigned)y < (unsigned)rows );
     CV_Error(CV_GpuNotSupported, "This function hasn't been supported yet.\n");
     return data + step * y;
 }
Exemplo n.º 8
0
    Vec2d computeProbabilities(const Mat& sample, Mat* probs, int ptype) const
    {
        // L_ik = log(weight_k) - 0.5 * log(|det(cov_k)|) - 0.5 *(x_i - mean_k)' cov_k^(-1) (x_i - mean_k)]
        // q = arg(max_k(L_ik))
        // probs_ik = exp(L_ik - L_iq) / (1 + sum_j!=q (exp(L_ij - L_iq))
        // see Alex Smola's blog http://blog.smola.org/page/2 for
        // details on the log-sum-exp trick

        int stype = sample.type();
        CV_Assert(!means.empty());
        CV_Assert((stype == CV_32F || stype == CV_64F) && (ptype == CV_32F || ptype == CV_64F));
        CV_Assert(sample.size() == Size(means.cols, 1));

        int dim = sample.cols;

        Mat L(1, nclusters, CV_64FC1), centeredSample(1, dim, CV_64F);
        int i, label = 0;
        for(int clusterIndex = 0; clusterIndex < nclusters; clusterIndex++)
        {
            const double* mptr = means.ptr<double>(clusterIndex);
            double* dptr = centeredSample.ptr<double>();
            if( stype == CV_32F )
            {
                const float* sptr = sample.ptr<float>();
                for( i = 0; i < dim; i++ )
                    dptr[i] = sptr[i] - mptr[i];
            }
            else
            {
                const double* sptr = sample.ptr<double>();
                for( i = 0; i < dim; i++ )
                    dptr[i] = sptr[i] - mptr[i];
            }

            Mat rotatedCenteredSample = covMatType != COV_MAT_GENERIC ?
                    centeredSample : centeredSample * covsRotateMats[clusterIndex];

            double Lval = 0;
            for(int di = 0; di < dim; di++)
            {
                double w = invCovsEigenValues[clusterIndex].at<double>(covMatType != COV_MAT_SPHERICAL ? di : 0);
                double val = rotatedCenteredSample.at<double>(di);
                Lval += w * val * val;
            }
            CV_DbgAssert(!logWeightDivDet.empty());
            L.at<double>(clusterIndex) = logWeightDivDet.at<double>(clusterIndex) - 0.5 * Lval;

            if(L.at<double>(clusterIndex) > L.at<double>(label))
                label = clusterIndex;
        }

        double maxLVal = L.at<double>(label);
        double expDiffSum = 0;
        for( i = 0; i < L.cols; i++ )
        {
            double v = std::exp(L.at<double>(i) - maxLVal);
            L.at<double>(i) = v;
            expDiffSum += v; // sum_j(exp(L_ij - L_iq))
        }

        if(probs)
            L.convertTo(*probs, ptype, 1./expDiffSum);

        Vec2d res;
        res[0] = std::log(expDiffSum)  + maxLVal - 0.5 * dim * CV_LOG2PI;
        res[1] = label;

        return res;
    }
Exemplo n.º 9
0
void LBSP::setReference(const cv::Mat& img) {
	CV_DbgAssert(img.empty() || img.type()==CV_8UC1 || img.type()==CV_8UC3);
	m_oRefImage = img;
}
Exemplo n.º 10
0
    cl_program getOrBuildProgram(const Context* ctx, const cv::ocl::ProgramEntry* source, const String& options)
    {
        cl_int status = 0;
        cl_program program = NULL;
        std::vector<char> binary;
        if (!enable_disk_cache || !readConfigurationFromFile(options, binary))
        {
            program = clCreateProgramWithSource(getClContext(ctx), 1, (const char**)&source->programStr, NULL, &status);
            openCLVerifyCall(status);
            cl_device_id device = getClDeviceID(ctx);
            status = clBuildProgram(program, 1, &device, options.c_str(), NULL, NULL);
            if(status == CL_SUCCESS)
            {
                if (enable_disk_cache)
                {
                    size_t binarySize;
                    openCLSafeCall(clGetProgramInfo(program,
                                            CL_PROGRAM_BINARY_SIZES,
                                            sizeof(size_t),
                                            &binarySize, NULL));

                    std::vector<char> binary(binarySize);

                    char* ptr = &binary[0];
                    openCLSafeCall(clGetProgramInfo(program,
                                            CL_PROGRAM_BINARIES,
                                            sizeof(char*),
                                            &ptr,
                                            NULL));

                    if (!writeConfigurationToFile(options, binary))
                    {
                        std::cerr << "Can't write data to file: " << fileName_ << std::endl;
                    }
                }
            }
        }
        else
        {
            cl_device_id device = getClDeviceID(ctx);
            size_t size = binary.size();
            const char* ptr = &binary[0];
            program = clCreateProgramWithBinary(getClContext(ctx),
                    1, &device,
                    (const size_t *)&size, (const unsigned char **)&ptr,
                    NULL, &status);
            openCLVerifyCall(status);
            status = clBuildProgram(program, 1, &device, options.c_str(), NULL, NULL);
        }

        if(status != CL_SUCCESS)
        {
            if(status == CL_BUILD_PROGRAM_FAILURE)
            {
                cl_int logStatus;
                char *buildLog = NULL;
                size_t buildLogSize = 0;
                logStatus = clGetProgramBuildInfo(program,
                        getClDeviceID(ctx), CL_PROGRAM_BUILD_LOG, buildLogSize,
                        buildLog, &buildLogSize);
                if(logStatus != CL_SUCCESS)
                    std::cout << "Failed to build the program and get the build info." << std::endl;
                buildLog = new char[buildLogSize];
                CV_DbgAssert(!!buildLog);
                memset(buildLog, 0, buildLogSize);
                openCLSafeCall(clGetProgramBuildInfo(program, getClDeviceID(ctx),
                                                     CL_PROGRAM_BUILD_LOG, buildLogSize, buildLog, NULL));
                std::cout << "\nBUILD LOG: " << options << "\n";
                std::cout << buildLog << std::endl;
                delete [] buildLog;
            }
            openCLVerifyCall(status);
        }
        return program;
    }
Exemplo n.º 11
0
// calc the sum of an area 
inline bool calcAreaMean(const cv::Mat &src,
	cv::Point currpos,
	cv::Size blockSize,
	const cv::Mat &sum=cv::Mat(),
	double *mean=NULL,
	const cv::Mat &sqsum=cv::Mat(),
	double *sd=NULL){

		//////////////////////////////////////////////////////////////////////////
		///// exceptions
		if(blockSize.width%2==0||blockSize.height%2==0){
			CV_Error(CV_StsBadArg,"[calcAreaMean] either block's height or width is 0.");
		}


		//////////////////////////////////////////////////////////////////////////
		///// initialization
		int SSFilterSize_h	=	blockSize.height/2;	// SSFilterSize: Single Side Filter Size
		int SSFilterSize_w	=	blockSize.width/2;	// SSFilterSize: Single Side Filter Size
		const	int	&height	=	src.rows;
		const	int	&width	=	src.cols;
		const	int	&i		=	currpos.y;
		const	int	&j		=	currpos.x;



		//////////////////////////////////////////////////////////////////////////
		bool	A=true,	// bottom, top, left, right; thus br: bottom-right
			B=true,
			C=true,
			D=true;
		if((i+SSFilterSize_h)>=height){
			A=false;
		}
		if((j+SSFilterSize_w)>=width){
			B=false;
		}
		if((i-SSFilterSize_h-1)<0){
			C=false;
		}
		if((j-SSFilterSize_w-1)<0){
			D=false;
		}


		////////////////////////////////////////////////////////////////////////// ok
		///// get area size
		// width
		double	areaWidth	=	blockSize.width,
				areaHeight	=	blockSize.height;
		if(!D){
			areaWidth	=	j+SSFilterSize_w+1;
		}else if(!B){
			areaWidth	=	width-j+SSFilterSize_w;
		}
		// height
		if(!C){
			areaHeight	=	i+SSFilterSize_h+1;
		}else if(!A){
			areaHeight	=	height-i+SSFilterSize_h;
		}


		//////////////////////////////////////////////////////////////////////////
		///// get value
		// get positions
		int	y_up	=	i+SSFilterSize_h		+1,	// '+1' is the bias term of the integral image 
			y_dn	=	i-SSFilterSize_h-1		+1;
		if(!A){
			y_up	=	height-1				+1;
		}
		int	x_left	=	j-SSFilterSize_w-1		+1,
			x_right	=	j+SSFilterSize_w		+1;
		if(!B){
			x_right	=	width-1					+1;
		}
		// get values
		double	cTR_sum=0,cTR_sqsum=0,
				cTL_sum=0,cTL_sqsum=0,
				cBR_sum=0,cBR_sqsum=0,
				cBL_sum=0,cBL_sqsum=0;
		cTR_sum			=	sum.ptr<double>(y_up)[x_right];
		cTR_sqsum		=	sqsum.ptr<double>(y_up)[x_right];
		if(C&&D){
			cBL_sum		=	sum.ptr<double>(y_dn)[x_left];		
			cBL_sqsum	=	sqsum.ptr<double>(y_dn)[x_left];	
		}
		if(D){
			cTL_sum		=	-sum.ptr<double>(y_up)[x_left];
			cTL_sqsum	=	-sqsum.ptr<double>(y_up)[x_left];
		}
		if(C){
			cBR_sum		=	-sum.ptr<double>(y_dn)[x_right];
			cBR_sqsum	=	-sqsum.ptr<double>(y_dn)[x_right];
		}


		////////////////////////////////////////////////////////////////////////// ok
		///// get mean and sd
		*mean	=cTR_sum		+cTL_sum	+cBR_sum	+cBL_sum;
		*mean	/=areaHeight*areaWidth;
		CV_DbgAssert((*mean)>=0.&&(*mean)<=255.);
		*sd		=cTR_sqsum		+cTL_sqsum	+cBR_sqsum	+cBL_sqsum;	
		*sd		/=areaHeight*areaWidth;
		// compensate error
		if(fabs((*sd)-(*mean)*(*mean))<0.00001){
			*sd=0;
		}else{
			CV_DbgAssert((*sd)>=(*mean)*(*mean));
			*sd		=sqrt(*sd-(*mean)*(*mean));
		}		
		CV_DbgAssert((*sd)>=0.&&(*sd)<=255.);

	return true;
}
Exemplo n.º 12
0
 bool pixkit::enhancement::local::POHE2013(const cv::Mat &src,cv::Mat &dst,const cv::Size blockSize,const cv::Mat &sum,const cv::Mat &sqsum){

	//////////////////////////////////////////////////////////////////////////
	///// Exceptions
	// blockSize
	if(blockSize.height>=src.rows || blockSize.width>=src.cols){
		CV_Error(CV_StsBadArg,"[pixkit::enhancement::local::POHE2013] block size should be smaller than image size. ");
	}
	if(blockSize.height%2==0 || blockSize.width%2==0){
		CV_Error(CV_StsBadArg,"[pixkit::enhancement::local::POHE2013] both block's width and height should be odd.");
	}
	if(blockSize.height==1&&blockSize.width==1){
		CV_Error(CV_StsBadArg,"[pixkit::enhancement::local::POHE2013] blockSize=(1,1) will turn entire image to dead white.");
	}
	// src
	if(src.type()!=CV_8UC1&&src.type()!=CV_8UC3&&src.type()!=CV_32FC1){
		CV_Error(CV_StsBadArg,"[pixkit::enhancement::local::POHE2013] src should be one of CV_8UC1, CV_8UC3, and CV_32FC1.");
	}
	// sum and sqsum
	if(!sum.empty()){
		if(sum.type()!=CV_64FC1){
			CV_Error(CV_StsBadArg,"[pixkit::enhancement::local::POHE2013] both sum and sqsum should be CV_64FC1");
		}
	}
	if(!sqsum.empty()){
		if(sqsum.type()!=CV_64FC1){
			CV_Error(CV_StsBadArg,"[pixkit::enhancement::local::POHE2013] both sum and sqsum should be CV_64FC1");
		}
	}
	
	//////////////////////////////////////////////////////////////////////////
	///// color image
	cv::Mat	_src1x,_src3x;
	if(src.channels()==1){
		_src1x=src;
	}else if(src.channels()==3){
		// create space for _src1x
		if(src.type()==CV_8UC3){
			_src1x.create(src.size(),CV_8UC1);
		}else if(src.type()==CV_32FC3){
			_src1x.create(src.size(),CV_32FC1);
		}else{
			CV_Assert(false);
		}
		// convert color
		cvtColor(src,_src3x,CV_BGR2Lab);
		int	from_to[]={0,0};
		mixChannels(&_src3x,1,&_src1x,1,from_to,1);
	}else{
		CV_Error(CV_StsUnsupportedFormat,"[pixkit::enhancement::local::POHE2013] images should be grayscale or color.");
	}

	//////////////////////////////////////////////////////////////////////////
	// initialization
	cv::Mat	tdst;	// temp dst. To avoid that when src == dst occur.
	tdst.create(_src1x.size(),_src1x.type());
	const int &height=_src1x.rows;
	const int &width=_src1x.cols;

	//////////////////////////////////////////////////////////////////////////
	///// create integral images
	cv::Mat	tsum,tsqsum;
	if(sum.empty()||sqsum.empty()){
		cv::integral(_src1x,tsum,tsqsum,CV_64F);
	}else{
		tsum	=	sum;
		tsqsum	=	sqsum;
	}

	//////////////////////////////////////////////////////////////////////////
	///// process
	for(int i=0;i<height;i++){
		for(int j=0;j<width;j++){
			
			//////////////////////////////////////////////////////////////////////////
			///// get mean and sd
			double	mean,sd;
			calcAreaMean(_src1x,cv::Point(j,i),blockSize,tsum,&mean,tsqsum,&sd);

			//////////////////////////////////////////////////////////////////////////
			// get current src value
			double	current_src_value=0.;
			if(_src1x.type()==CV_8UC1){
				current_src_value	=	_src1x.ptr<uchar>(i)[j];
			}else if(_src1x.type()==CV_32FC1){
				current_src_value	=	_src1x.ptr<float>(i)[j];
			}else{
				assert(false);
			}

			//////////////////////////////////////////////////////////////////////////
			// calc Gaussian's cdf
			double	cdf	=	calcCDF_Gaussian(current_src_value,mean,sd);

			//////////////////////////////////////////////////////////////////////////
			// get output
			if(tdst.type()==CV_8UC1){
				if(current_src_value >= mean-1.885*sd){
					tdst.data[i*width+j]	=	cvRound(cdf*255.);
				}else{
					tdst.data[i*width+j]	=	0;
				}
				CV_DbgAssert(((uchar*)tdst.data)[i*width+j]>=0.&&((uchar*)tdst.data)[i*width+j]<=255.);
			}else if(tdst.type()==CV_32FC1){
				if(current_src_value >= mean-1.885*sd){
					((float*)tdst.data)[i*width+j]	=	cvRound(cdf*255.);
				}else{
					((float*)tdst.data)[i*width+j]	=	0;
				}
				CV_DbgAssert(((float*)tdst.data)[i*width+j]>=0.&&((float*)tdst.data)[i*width+j]<=255.);
			}else{
				CV_Assert(false);
			}
		}
	}

	//////////////////////////////////////////////////////////////////////////
	///// copy to dst
	if(src.channels()==1){
		dst	=	tdst.clone();
	}else if(src.channels()==3){
		int	from_to[]={0,0};
		mixChannels(&tdst,1,&_src3x,1,from_to,1);
		cvtColor(_src3x,dst,CV_Lab2BGR);
	}else{
		CV_Error(CV_StsUnsupportedFormat,"[pixkit::enhancement::local::POHE2013] images should be grayscale or color.");
	}
	
	return true;
}