//=============================================================================
	// Basically Kabsch's algorithm but also allows the collection of points to be different in scale from each other
	cv::Matx22f AlignShapesWithScale(cv::Mat_<float>& src, cv::Mat_<float> dst)
	{
		int n = src.rows;

		// First we mean normalise both src and dst
		float mean_src_x = cv::mean(src.col(0))[0];
		float mean_src_y = cv::mean(src.col(1))[0];

		float mean_dst_x = cv::mean(dst.col(0))[0];
		float mean_dst_y = cv::mean(dst.col(1))[0];

		cv::Mat_<float> src_mean_normed = src.clone();
		src_mean_normed.col(0) = src_mean_normed.col(0) - mean_src_x;
		src_mean_normed.col(1) = src_mean_normed.col(1) - mean_src_y;

		cv::Mat_<float> dst_mean_normed = dst.clone();
		dst_mean_normed.col(0) = dst_mean_normed.col(0) - mean_dst_x;
		dst_mean_normed.col(1) = dst_mean_normed.col(1) - mean_dst_y;

		// Find the scaling factor of each
		cv::Mat src_sq;
		cv::pow(src_mean_normed, 2, src_sq);

		cv::Mat dst_sq;
		cv::pow(dst_mean_normed, 2, dst_sq);

		float s_src = sqrt(cv::sum(src_sq)[0] / n);
		float s_dst = sqrt(cv::sum(dst_sq)[0] / n);

		src_mean_normed = src_mean_normed / s_src;
		dst_mean_normed = dst_mean_normed / s_dst;

		float s = s_dst / s_src;

		// Get the rotation
		cv::Matx22f R = AlignShapesKabsch2D(src_mean_normed, dst_mean_normed);

		cv::Matx22f	A;
		cv::Mat(s * R).copyTo(A);

		cv::Mat_<float> aligned = (cv::Mat(cv::Mat(A) * src.t())).t();
		cv::Mat_<float> offset = dst - aligned;

		float t_x = cv::mean(offset.col(0))[0];
		float t_y = cv::mean(offset.col(1))[0];

		return A;

	}
/** Orthogonal matching pursuit
* x: input signal, N * 1 
* D: dictionary, N * M 
* L: number of non_zero elements in output
* coeff: coefficent of each atoms in dictionary, M * 1
*/
void OMP(const cv::Mat_<double>& x, const cv::Mat_<double>& D, int L, cv::Mat_<double>& coeff){
    int dim = x.rows;
    int atom_num = D.cols;
    coeff = Mat::zeros(atom_num, 1, CV_64FC1);
    Mat_<double> residual = x.clone();
    Mat_<double> selected_index(L, 1);
    Mat_<double> a;
    for (int i = 0; i < L; i++){
        cout << "here ok 1" << endl;
        Mat_<double> dot_p = D.t() * residual; 
        Point max_index;
        minMaxLoc(abs(dot_p), NULL, NULL, NULL, &max_index);
        int max_row = max_index.y;
        selected_index(i) = max_row;
        Mat_<double> temp(dim, i + 1);
        for (int j = 0; j < i + 1; j++){
            D.col(selected_index(j)).copyTo(temp.col(j));
        }
        Mat_<double> invert_temp;
        invert(temp, invert_temp, CV_SVD);
        a = invert_temp * x;
        residual = x - temp * a;
    }

    for (int i = 0; i < L; i++){
        coeff(selected_index(i)) = a(i);
    }
} 
Example #3
0
	// Extract summary statistics (mean, stdev, min, max) from each dimension of a descriptor, each row is a descriptor
	void ExtractSummaryStatistics(const cv::Mat_<double>& descriptors, cv::Mat_<double>& sum_stats, bool use_mean, bool use_stdev, bool use_max_min)
	{
		// Using four summary statistics at the moment 
		// Means, stds, mins, maxs
		int num_stats = 0;

		if(use_mean)
			num_stats++;

		if(use_stdev)
			num_stats++;

		if(use_max_min)
			num_stats++;

		sum_stats = Mat_<double>(1, descriptors.cols * num_stats, 0.0);
		for(int i = 0; i < descriptors.cols; ++i)
		{
			Scalar mean, stdev;
			cv::meanStdDev(descriptors.col(i), mean, stdev);

			int add = 0;

			if(use_mean)
			{
				sum_stats.at<double>(0, i*num_stats + add) = mean[0];
				add++;
			}

			if(use_stdev)
			{
				sum_stats.at<double>(0, i*num_stats + add) = stdev[0];
				add++;
			}

			if(use_max_min)
			{
				double min, max;
				cv::minMaxIdx(descriptors.col(i), &min, &max);
				sum_stats.at<double>(0, i*num_stats + add) = max - min;
				add++;
			}
		}		
	}
Example #4
0
void cModel::UpDate(cv::Mat_<int>&binary, cv::Rect &bbox, cv::Mat_<float>& shape, int stage)
{	
	int num_point = m_Model.__head.__num_point;
	int w_cols = 2 * num_point;
	int w_rows = binary.cols;	

	cv::Mat_<float> deltashapes = cv::Mat::zeros(1, w_cols, CV_32FC1);

	for (int i = 0; i < w_rows; i++){
		if (binary(0, i) == 1){
			deltashapes += m_Model.__w.row(stage * w_rows + i);
		}
	}

	cv::Mat_<float> deltax = deltashapes.colRange(0, num_point).t();
	deltax *= bbox.width;
	cv::Mat_<float> deltay = deltashapes.colRange(num_point, w_cols).t();
	deltay *= bbox.height;	
		
	shape.col(0) += deltax;
	shape.col(1) += deltay;
}
/**
 * Find 3D rotation and translation with homography (i.e. calibration boards position in the camera cooperate system )
 * @param h**o: [Input] Estimated Homography
 * @param rot: [Output] Rotation result
 * @param trans: [Output] Translation result
 */
void AugmentationEnvironment::H2Rt(const cv::Mat_<double> intrisinc, const cv::Mat_<double>& h**o, cv::Mat_<double>& rot, cv::Mat_<double> &trans)
{
	double coefH;

	cv::Mat_<double> invcam = intrisinc.inv();
	rot = invcam*h**o;

	//scaling rotation matrix to right order = find the coefficient lost while calculating homography
	/**
	 * [Cam]*[Rot]' = [H**o]*coefH
	 *          |fx  0  u0|
	 * [Cam]' = | 0 fy  v0|
	 *          | 0  0   1|
	 *
	 *          |R11 R12 t1|
	 * [Rot]' = |R21 R22 t2|
	 *          |R31 R32 t3|
	 *
	 *           |H11 H12 H13|
	 * [H**o]' = |H21 H22 H23|
	 *           |H31 H32   1|
	 */
	coefH = 2/(cv::norm(rot.col(0)) + cv::norm(rot.col(1)));
	rot = rot * coefH;
	trans = rot.col(2).clone();

	//The their rotation vector in the rotation matrix is produced as the cross product of other two vectors
	cv::Mat tmp = rot.col(2);
	rot.col(0).cross(rot.col(1)).copyTo(tmp);

	//Add here to make rotation matrix a "real" rotation matrix in zhang's method
	/**
	 * rot = UDVt
	 * rot_real = UVt
	 */
	cv::Mat_<double> D,U,Vt;
	cv::SVD::compute(rot,D,U,Vt);
	rot = U*Vt;
}