float FeatureDetector::getNCC(ImageBitstream image, int x, int y, FeatureDescriptor feature)
{
	int row, col;
	int patchSize = FeatureDescriptor::patchSize_;
	int width = image.getWidth();

	unsigned char *I = image.getBitstream();
	unsigned char *P = feature.get();

	// calculate average of image in feature patch
	int pavg = 0, iavg = 0;

	for(row = 0; row < patchSize; row++)
	{
		for(col = 0; col < patchSize; col++)
		{
			pavg += P[row * patchSize + col];

			iavg += I[(y + row - (patchSize - 1)/2) * width + (x + col - (patchSize - 1)/2)];
		}
	}

	pavg = pavg / (patchSize * patchSize);
	iavg = iavg / (patchSize * patchSize);


	// calculate NCC
	int pnorm, inorm;
	int sumII = 0, sumPP = 0, sumIP = 0;
	float ncc;

	for(row = 0; row < patchSize; row++)
	{
		for(col = 0; col < patchSize; col++)
		{
			pnorm = P[row * patchSize + col] - pavg;
			inorm = I[(y + row - (patchSize - 1)/2) * width + (x + col - (patchSize - 1)/2)] - iavg;

			sumIP += pnorm * inorm;
			sumPP += pnorm * pnorm;
			sumII += inorm * inorm;
		}
	}

	ncc = sumIP / (sqrt(sumPP) * sqrt(sumII));

	return ncc;
}
Пример #2
0
Transformation * BowAICK::getTransformation(RGBDFrame * src, RGBDFrame * dst)
{
	struct timeval start, end;
	gettimeofday(&start, NULL);
	Eigen::Matrix4f transformationMat = Eigen::Matrix4f::Identity();
	
	Transformation * transformation = new Transformation();
	transformation->transformationMatrix = transformationMat;
	transformation->src = src;
	transformation->dst = dst;
	transformation->weight = 100;

	if(debugg_BowAICK){printf("BowAICK::getTransformation(%i,%i)\n",src->id,dst->id);}
	IplImage* img_combine;
	int width;
	int height;
	if(debugg_BowAICK){
		IplImage* rgb_img_src 	= cvLoadImage(src->input->rgb_path.c_str(),CV_LOAD_IMAGE_UNCHANGED);
		char * data_src = (char *)rgb_img_src->imageData;
		IplImage* rgb_img_dst 	= cvLoadImage(dst->input->rgb_path.c_str(),CV_LOAD_IMAGE_UNCHANGED);
		char * data_dst = (char *)rgb_img_dst->imageData;
		width = rgb_img_src->width;
		height = rgb_img_src->height;
		img_combine = cvCreateImage(cvSize(2*width,height), IPL_DEPTH_8U, 3);
		char * data = (char *)img_combine->imageData;
		for (int j = 0; j < height; j++){
			for (int i = 0; i < width; i++){
				int ind = 3*(640*j+i);
				data[3 * (j * (2*width) + (width+i)) + 0] = data_dst[ind +0];
				data[3 * (j * (2*width) + (width+i)) + 1] = data_dst[ind +1];
				data[3 * (j * (2*width) + (width+i)) + 2] = data_dst[ind +2];
				data[3 * (j * (2*width) + (i)) + 0] = data_src[ind +2];
				data[3 * (j * (2*width) + (i)) + 1] = data_src[ind +2];
				data[3 * (j * (2*width) + (i)) + 2] = data_src[ind +2];
			}
		}
		cvReleaseImage( &rgb_img_src );
		cvReleaseImage( &rgb_img_dst );
	}
	
	int nr_loop_src = src->keypoints->valid_key_points.size();
	if(nr_loop_src > max_points){nr_loop_src = max_points;}
	int nr_loop_dst = dst->keypoints->valid_key_points.size();
	if(nr_loop_dst > max_points){nr_loop_dst = max_points;}
	


	vector<KeyPoint * > src_keypoints;
	for(int i = 0; i < nr_loop_src; i++){src_keypoints.push_back(src->keypoints->valid_key_points.at(i));}

	vector<KeyPoint * > dst_keypoints;
	for(int i = 0; i < nr_loop_dst; i++){dst_keypoints.push_back(dst->keypoints->valid_key_points.at(i));}
	
	int src_nr_points = src_keypoints.size();
	int dst_nr_points = dst_keypoints.size();
	
	int nr_bow = src->input->calibration->words.size();
	vector<int> * bow = new vector<int>[nr_bow];
	for(int i = 0; i < nr_bow; i++){bow[i] = vector<int>();}
	for(int i = 0; i < dst_keypoints.size(); i++){
		KeyPoint * kp = dst_keypoints.at(i);
		if(kp->cluster_distance_pairs.size()>0){
			int id = kp->cluster_distance_pairs.at(0).first;
			bow[id].push_back(i);
		}
	}

	vector< vector< int > > possible_matches;
	float ** feature_distances = new float*[src_nr_points];
	for(int i = 0; i < src_nr_points; i++){
		possible_matches.push_back(vector< int >());
		KeyPoint * src_kp = src_keypoints.at(i);
		for(int j = 0; j < src_kp->cluster_distance_pairs.size(); j++){
			float d = src_kp->cluster_distance_pairs.at(j).second;
			int id = src_kp->cluster_distance_pairs.at(j).first;
			if(d < bow_threshold){
				vector<int> vec = bow[id];
				for(int k = 0; k < vec.size(); k++){possible_matches.at(i).push_back(vec.at(k));}
			}else{break;}
		}
		FeatureDescriptor * descriptorA = src_kp->descriptor;
		int dst_nr_matches = possible_matches.at(i).size();
		feature_distances[i] = new float[dst_nr_matches];		
		for(int j = 0; j < dst_nr_matches;j++)
		{
			FeatureDescriptor * descriptorB = dst_keypoints.at(possible_matches.at(i).at(j))->descriptor;
			feature_distances[i][j] = feature_scale*(descriptorA->distance(descriptorB));
		}
	}
	
/*
	for(int i = 0; i < src_nr_points;i++){
		FeatureDescriptor * descriptorA = src_keypoints.at(i)->descriptor;
		int dst_nr_matches = possible_matches.at(i).size();
		feature_distances[i] = new float[dst_nr_matches];		
		for(int j = 0; j < dst_nr_matches;j++)
		{
			FeatureDescriptor * descriptorB = dst_keypoints.at(possible_matches.at(i).at(j))->descriptor;
			feature_distances[i][j] = feature_scale*(descriptorA->distance(descriptorB));
		}
	}
*/
	float * pos_src_x 	= new float[src_nr_points];
	float * pos_src_y 	= new float[src_nr_points];
	float * pos_src_z 	= new float[src_nr_points];
	for(int i = 0; i < src_nr_points; i++)
	{
		pos_src_x[i] = src_keypoints.at(i)->point->x;
		pos_src_y[i] = src_keypoints.at(i)->point->y;
		pos_src_z[i] = src_keypoints.at(i)->point->z;
	}	
	
	float * pos_dst_x 	= new float[dst_nr_points];
	float * pos_dst_y 	= new float[dst_nr_points];
	float * pos_dst_z 	= new float[dst_nr_points];
	for(int i = 0; i < dst_nr_points; i++)
	{
		pos_dst_x[i] = dst_keypoints.at(i)->point->x;
		pos_dst_y[i] = dst_keypoints.at(i)->point->y;
		pos_dst_z[i] = dst_keypoints.at(i)->point->z;
	}
	
	for(int iter = 0; iter < nr_iter; iter++)
	{
	
		float alpha = getAlpha(iter);
		//printf("alpha= %f\n",alpha);
		pcl::TransformationFromCorrespondences tfc;
		float threshold = distance_threshold*alpha + (1 - alpha)*feature_threshold;
		transformation->weight = 0;
		int nr_matches = 0;
		
		float mat00 = transformationMat(0,0);
		float mat01 = transformationMat(0,1);
		float mat02 = transformationMat(0,2);
		float mat03 = transformationMat(0,3);
		float mat10 = transformationMat(1,0);
		float mat11 = transformationMat(1,1);
		float mat12 = transformationMat(1,2);
		float mat13 = transformationMat(1,3);
		float mat20 = transformationMat(2,0);
		float mat21 = transformationMat(2,1);
		float mat22 = transformationMat(2,2);
		float mat23 = transformationMat(2,3);
		
		IplImage * img_combine_clone;
		if(debugg_BowAICK){
			img_combine_clone = cvCreateImage(cvSize(img_combine->width, img_combine->height), IPL_DEPTH_8U, 3);
			cvCopy( img_combine, img_combine_clone, NULL );
		}
		
		for(int i = 0; i < src_nr_points;i++)
		{
			float x_tmp = pos_src_x[i];
			float y_tmp = pos_src_y[i];
			float z_tmp = pos_src_z[i];
				
			float x = x_tmp*mat00+y_tmp*mat01+z_tmp*mat02+mat03;
			float y = x_tmp*mat10+y_tmp*mat11+z_tmp*mat12+mat13;
			float z = x_tmp*mat20+y_tmp*mat21+z_tmp*mat22+mat23;

			float dx,dy,dz;
			int dst_nr_matches = possible_matches.at(i).size();
			float best_d = 100000000;
			int best_j = -1;
			for(int jj = 0; jj < dst_nr_matches;jj++)
			{
				int j = possible_matches.at(i).at(jj);
				dx = x-pos_dst_x[j];
				dy = y-pos_dst_y[j];
				dz = z-pos_dst_z[j];

				float d = (1-alpha)*feature_distances[i][jj] + alpha*sqrt(dx*dx + dy*dy + dz*dz);
				if(d < best_d){
					best_d = d;
					best_j = j;
				}
			}
			if(best_d < threshold && best_j != -1){
				KeyPoint * src_kp = src_keypoints.at(i);
				KeyPoint * dst_kp = dst_keypoints.at(best_j);
				if(debugg_BowAICK){
					cvCircle(img_combine_clone,cvPoint(dst_kp->point->w + width	, dst_kp->point->h), 5,cvScalar(0, 255, 0, 0),2, 8, 0);
					cvCircle(img_combine_clone,cvPoint(src_kp->point->w			, src_kp->point->h), 5,cvScalar(0, 255, 0, 0),2, 8, 0);
					cvLine(img_combine_clone,cvPoint(dst_kp->point->w  + width ,dst_kp->point->h),cvPoint(src_kp->point->w,src_kp->point->h),cvScalar(0, 0, 255, 0),1, 8, 0);
				}
				tfc.add(src_kp->point->pos, dst_kp->point->pos);
				if(iter == nr_iter-1){
					transformation->weight++;
					transformation->matches.push_back(make_pair (src_kp, dst_kp));
				}
			}
		}
		
		transformationMat = tfc.getTransformation().matrix();
		transformation->transformationMatrix = transformationMat;
		if(debugg_BowAICK ){
			cvShowImage("combined image", img_combine_clone);
			cvWaitKey(0);
			cvReleaseImage( &img_combine_clone);
		}
	}
	//cout<< "transformation->transformationMatrix\n" <<transformation->transformationMatrix<<endl;
	if(debugg_BowAICK){printf("done\n");cvReleaseImage( &img_combine );}
	
	for(int i = 0; i < src_nr_points;i++){delete[] feature_distances[i];}
	delete[] feature_distances;
	
	delete[] pos_src_x;
	delete[] pos_src_y;
	delete[] pos_src_z;
	
	delete[] pos_dst_x;
	delete[] pos_dst_y;
	delete[] pos_dst_z;
	
	delete[] bow;
	

	gettimeofday(&end, NULL);
	float time = (end.tv_sec*1000000+end.tv_usec-(start.tv_sec*1000000+start.tv_usec))/1000000.0f;
	//printf("BowAICK cost: %f, weight: %f\n",time,transformation->weight);
	//transformation->print();
	//if(transformation->weight > 5){printf("BowAICK cost: %f, weight: %f\n",time,transformation->weight);}
	return transformation;
}
Пример #3
0
Transformation * RansacPCLCopyMatcher::getTransformation(RGBDFrame * src, RGBDFrame * dst)
{
	if(debugg_RansacPCLCopyMatcher){printf("RansacPCLCopyMatcher::getTransformation(%i,%i)\n",src->id,dst->id);}
	
	Transformation * transformation = new Transformation();
	transformation->src = src;
	transformation->dst = dst;
	transformation->weight = 0;
	transformation->transformationMatrix = Eigen::Matrix4f::Identity();

	vector<KeyPoint * > src_keypoints = src->keypoints->valid_key_points;
	vector<KeyPoint * > dst_keypoints = dst->keypoints->valid_key_points;

	int src_nr_points = src_keypoints.size();
	int dst_nr_points = dst_keypoints.size();

	vector<int> ** possibleMatches	= new vector<int>*[src_nr_points];
	for(int i = 0; i < src_nr_points;i++)
	{
		possibleMatches[i]		= new vector<int>();	
		for(int j = 0; j < dst_nr_points;j++)
		{
			FeatureDescriptor * descriptorA = src_keypoints.at(i)->descriptor;
			FeatureDescriptor * descriptorB = dst_keypoints.at(j)->descriptor;
			if(descriptorA->distance(descriptorB) < feature_threshold){possibleMatches[i]->push_back(j);}
		}
		//printf("%i:%i\n",i,possibleMatches[i]->size());
	}

	
	float * pos_src_x = new float[src_nr_points];
	float * pos_src_y = new float[src_nr_points];
	float * pos_src_z = new float[src_nr_points];
	
	float * pos_dst_x = new float[dst_nr_points];
	float * pos_dst_y = new float[dst_nr_points];
	float * pos_dst_z = new float[dst_nr_points];
	
	Eigen::Matrix4f transformationMat = Eigen::Matrix4f::Identity();
	
	for(int i = 0; i < src_nr_points;i++)
	{
		pos_src_x[i] = src_keypoints[i]->point->x;
		pos_src_y[i] = src_keypoints[i]->point->y;
		pos_src_z[i] = src_keypoints[i]->point->z;
	}
	for(int i = 0; i < dst_nr_points;i++)
	{
		pos_dst_x[i] = dst_keypoints[i]->point->x;
		pos_dst_y[i] = dst_keypoints[i]->point->y;
		pos_dst_z[i] = dst_keypoints[i]->point->z;
	}
	
	int nr_best = 0;
	pcl::TransformationFromCorrespondences tfc;
	for(int i = 0; i < nr_iter; i++)
	{
		int src_a,src_b,src_c,dst_a,dst_b,dst_c;
		int counter = 0;
		src_a = rand() % src_nr_points;
		src_b = rand() % src_nr_points;
		src_c = rand() % src_nr_points;
		while(possibleMatches[src_a]->size() == 0 && counter < 500)										{counter++;src_a = rand() % src_nr_points;}
		while(possibleMatches[src_b]->size() == 0 || src_a == src_b  && counter < 500)					{counter++;src_b = rand() % src_nr_points;}
		while(possibleMatches[src_c]->size() == 0 || src_c == src_a || src_c == src_b && counter < 500)	{counter++;src_c = rand() % src_nr_points;}
		if(counter >= 500){continue;}
		dst_a = possibleMatches[src_a]->at(rand()%possibleMatches[src_a]->size());
		dst_b = possibleMatches[src_b]->at(rand()%possibleMatches[src_b]->size());
		dst_c = possibleMatches[src_c]->at(rand()%possibleMatches[src_c]->size());
		
		tfc.reset();
		tfc.add(src_keypoints.at(src_a)->point->pos,dst_keypoints.at(dst_a)->point->pos);
		tfc.add(src_keypoints.at(src_b)->point->pos,dst_keypoints.at(dst_b)->point->pos);
		tfc.add(src_keypoints.at(src_c)->point->pos,dst_keypoints.at(dst_c)->point->pos);
		transformationMat = tfc.getTransformation().matrix();
		
		float mat00 = transformationMat(0,0);
		float mat01 = transformationMat(0,1);
		float mat02 = transformationMat(0,2);
		float mat03 = transformationMat(0,3);
		float mat10 = transformationMat(1,0);
		float mat11 = transformationMat(1,1);
		float mat12 = transformationMat(1,2);
		float mat13 = transformationMat(1,3);
		float mat20 = transformationMat(2,0);
		float mat21 = transformationMat(2,1);
		float mat22 = transformationMat(2,2);
		float mat23 = transformationMat(2,3);
		
		std::vector<int> src_good;
		std::vector<int> dst_good;
		
		for(int src_j = 0; src_j < src_nr_points; src_j++)
		{
			float x = pos_src_x[src_j];
			float y = pos_src_y[src_j];
			float z = pos_src_z[src_j];
			float tmp_x = x*mat00+y*mat01+z*mat02+mat03;
			float tmp_y = x*mat10+y*mat11+z*mat12+mat13;
			float tmp_z = x*mat20+y*mat21+z*mat22+mat23;
			float min = 100;
			int closest = -1;
			for(int k = 0; k < possibleMatches[src_j]->size(); k++){
				int dst_j = possibleMatches[src_j]->at(k);
				
				float dx = pos_dst_x[dst_j] - tmp_x;
				float dy = pos_dst_y[dst_j] - tmp_y;
				float dz = pos_dst_z[dst_j] - tmp_z;
				float dist = sqrt(dx*dx + dy*dy + dz*dz);
				if(dist < min){
					min = dist;
					closest = dst_j;
				}
			}

			if(min < distance_threshold){
				//printf("%i : %i -> %f\n",src_j,closest,min);
				src_good.push_back(src_j);
				dst_good.push_back(closest);
			}
		}
		if(src_good.size() > nr_best){
			nr_best = src_good.size();
			tfc.reset();
			for(int j = 0; j < src_good.size(); j++){
				tfc.add(src_keypoints.at(src_good.at(j))->point->pos,dst_keypoints.at(dst_good.at(j))->point->pos);
			}
			transformation->transformationMatrix = tfc.getTransformation().matrix();
		}

	}
	
	for(int i = 0; i < src_nr_points;i++)
	{
		delete possibleMatches[i];
	}
	delete[] possibleMatches;
	delete[] pos_src_x;
	delete[] pos_src_y;
	delete[] pos_src_z;
	
	delete[] pos_dst_x;
	delete[] pos_dst_y;
	delete[] pos_dst_z;
	return transformation;
}