Ejemplo n.º 1
0
template <typename PointInT, typename PointNT, typename PointOutT> void
pcl::GSS3DEstimation<PointInT, PointNT, PointOutT>::calculateGeometricScaleSpace ()
{
  normal_maps_.resize (scales_.size ());
  // TODO Do we need the original normal_map? It's noisy anyway ...
  // The normal map at the largest scale is the given one
//  normal_maps_[0] = PointCloudNPtr ( new PointCloudN (*normals_));


  // Compute the following scale spaces by convolving with a geodesic Gaussian kernel
  float sigma, sigma_squared, dist, gauss_coeff, normalization_factor;
  PointNT result, aux;
  for (size_t scale_i = 0; scale_i < scales_.size (); ++scale_i)
  {
    printf ("Computing for scale %d\n", scales_[scale_i]);
    PointCloudNPtr normal_map (new PointCloudN ());
    normal_map->header = normals_->header;
    normal_map->width = normals_->width;
    normal_map->height = normals_->height;
    normal_map->resize (normals_->size ());

    sigma = scales_[scale_i];
    sigma_squared = sigma * sigma;

    // For all points on the depth image
    for (int x = 0; x < int (normal_map->width); ++x)
      for (int y = 0; y < int (normal_map->height); ++y)
      {
        result.normal_x = result.normal_y = result.normal_z = 0.0f;

        // For all points in the Gaussian window
        for (int win_x = -window_size_/2 * sigma; win_x <= window_size_/2 * sigma; ++win_x)
          for (int win_y = -window_size_/2 * sigma; win_y <= window_size_/2 * sigma; ++win_y)
            // This virtually borders the image with 0-normals
            if ( (x + win_x >= 0) && (x + win_x < int (normal_map->width)) && (y + win_y >= 0) && (y + win_y < int (normal_map->height)))
            {
              dist = computeGeodesicDistance (x, y, x+win_x, y+win_y);
              if (dist == -1.0f) continue;
              gauss_coeff = 1 / (2 * M_PI * sigma_squared) * exp ((-1) * dist*dist / (2 * sigma_squared));
              aux = normals_->at (x + win_x, y + win_y);
              if (pcl_isnan (aux.normal_x)) continue;
              result.normal_x += aux.normal_x * gauss_coeff; result.normal_y += aux.normal_y * gauss_coeff; result.normal_z += aux.normal_z * gauss_coeff;
            }
        // Normalize the resulting normal
        normalization_factor = sqrt (result.normal_x*result.normal_x + result.normal_y*result.normal_y + result.normal_z*result.normal_z);
        result.normal_x /= normalization_factor; result.normal_y /= normalization_factor; result.normal_z /= normalization_factor;
        (*normal_map) (x, y) = result;
      }

    normal_maps_[scale_i] = normal_map;
  }
}
Ejemplo n.º 2
0
// extract patches from database images
bool ObjPatchMatcher::PreparePatchDB(DatasetName db_name) {

	patch_meta.objects.clear();
	cout<<patch_meta.objects.max_size()<<endl;

	DataManagerInterface* db_man = NULL;
	if(db_name == DB_NYU2_RGBD)
		db_man = new NYUDepth2DataMan;
	if(db_name == DB_SALIENCY_RGBD)
		db_man = new RGBDECCV14;

	srand(time(0));
	FileInfos imgfns, dmapfns;
	db_man->GetImageList(imgfns);
	random_shuffle(imgfns.begin(), imgfns.end());
	imgfns.erase(imgfns.begin()+30, imgfns.end());
	db_man->GetDepthmapList(imgfns, dmapfns);
	map<string, vector<VisualObject>> gt_masks;
	db_man->LoadGTMasks(imgfns, gt_masks);

	int gt_obj_cnt = 0;
	gt_obj_masks.clear();

	for(size_t i=0; i<imgfns.size(); i++) {
		// color
		Mat cimg = imread(imgfns[i].filepath);
		Size newsz(400, 400);
		//tools::ToolFactory::compute_downsample_ratio(Size(cimg.cols, cimg.rows), 400, newsz);
		resize(cimg, cimg, newsz);
		// depth
		Mat dmap_float;
		db_man->LoadDepthData(dmapfns[i].filepath, dmap_float);
		resize(dmap_float, dmap_float, newsz);
		dmap_float.convertTo(dmap_float, CV_32F, 1000);
		Mat cmp_mask;
		compare(dmap_float, 800, cmp_mask, CMP_LT);
		dmap_float.setTo(800, cmp_mask);
		compare(dmap_float, 7000, cmp_mask, CMP_GT);
		dmap_float.setTo(7000, cmp_mask);
		dmap_float = (dmap_float-800)/(7000-800);
		
		// get label image
		Mat lable_mask = Mat::zeros(newsz.height, newsz.width, CV_8U);
		Mat label_id_mask = Mat::zeros(newsz.height, newsz.width, CV_32S)-1;
		vector<VisualObject>& gt_objs = gt_masks[imgfns[i].filename];
		for(auto& cur_gt : gt_objs) {
			//if( !valid_cls[cur_gt.category_id] ) continue;
			resize(cur_gt.visual_data.mask, cur_gt.visual_data.mask, newsz);
			label_id_mask.setTo(gt_obj_cnt++, cur_gt.visual_data.mask);
			gt_obj_masks.push_back(cur_gt.visual_data.mask);
			lable_mask.setTo(1, cur_gt.visual_data.mask);
		}

		imshow("color", cimg);
		ImgVisualizer::DrawFloatImg("depth", dmap_float);
		imshow("label", lable_mask*255);
		waitKey(10);

		// do edge detection to locate boundary point quickly
		Mat gray_img, edge_map, gray_img_float;
		cvtColor(cimg, gray_img, CV_BGR2GRAY);
		gray_img.convertTo(gray_img_float, CV_32F, 1.f/255);
		Canny(gray_img, edge_map, 10, 50);
		Mat grad_x, grad_y, grad_mag;
		Sobel(gray_img_float, grad_x, CV_32F, 1, 0);
		Sobel(gray_img_float, grad_y, CV_32F, 0, 1);
		magnitude(grad_x, grad_y, grad_mag);
		Mat pts3d, normal_map;
		if(use_depth) {
			Feature3D feat3d;
			feat3d.ComputeKinect3DMap(dmap_float, pts3d, false);
			feat3d.ComputeNormalMap(pts3d, normal_map);
		}

		// selected patch indicator, avoid very close duplicate patches
		Mat picked_patch_mask = Mat::zeros(lable_mask.rows, lable_mask.cols, CV_8U);

		// extract patches
		for(int r=patch_size.height/2; r<edge_map.rows-patch_size.height/2; r+=3) {
			for(int c=patch_size.width/2; c<edge_map.cols-patch_size.width/2; c+=3) {

				if( edge_map.at<uchar>(r,c) == 0 ) continue;

				// only use perfect boundary points
				Point center_pt(c, r), left_pt(c-1, r), right_pt(c+1, r), top_pt(c, r-1), bottom_pt(c, r+1);
				if(lable_mask.at<uchar>(center_pt) == lable_mask.at<uchar>(left_pt) && 
					lable_mask.at<uchar>(center_pt) == lable_mask.at<uchar>(right_pt) &&
					lable_mask.at<uchar>(center_pt) == lable_mask.at<uchar>(top_pt) &&
					lable_mask.at<uchar>(center_pt) == lable_mask.at<uchar>(bottom_pt) );
					//continue;

				// set picked
				picked_patch_mask.at<uchar>(center_pt) = 1;

				VisualObject cur_patch;
				cur_patch.meta_data.img_path = imgfns[i].filepath;
				Rect box(c-patch_size.width/2, r-patch_size.height/2, patch_size.width, patch_size.height);
				cur_patch.visual_data.bbox = box;

				// find which object is dominant
				map<int, int> obj_label_cnt;
				int max_num = 0;
				cur_patch.meta_data.category_id = -1;
				for(int rr=box.y; rr<box.br().y; rr++) for(int cc=box.x; cc<box.br().x; cc++) {
					int cur_id = label_id_mask.at<int>(rr,cc);
					if(cur_id != -1)
					{
						obj_label_cnt[cur_id]++;
						if(obj_label_cnt[cur_id] > max_num) 
						{ 
							max_num = obj_label_cnt[cur_id];
							cur_patch.meta_data.category_id= cur_id;
						}
					}
				}
				/*vector<ImgWin> boxes; boxes.push_back(box);
				ImgVisualizer::DrawWinsOnImg("", cimg, boxes);
				if(cur_patch.category_id != -1) {
				imshow("mask", gt_obj_masks[cur_patch.category_id]*255);
				waitKey(0);
				}*/
				

				lable_mask(box).convertTo(cur_patch.visual_data.mask, CV_32F);
				// extract feature vector
				gray_img_float(box).copyTo( cur_patch.visual_data.custom_feats["gray"] );
				//grad_mag(box).copyTo( cur_patch.visual_desc.extra_features["gradient"] );
				if(use_depth) {
					normal_map(box).copyTo( cur_patch.visual_data.custom_feats["normal"] );
					dmap_float(box).copyTo( cur_patch.visual_data.custom_feats["depth"] );
					/*ImgVisualizer::DrawFloatImg("depthmask", cur_patch.visual_desc.extra_features["depth"]);
					cout<<"new box"<<endl;
					waitKey(0);*/
				}
				Mat feat;
				ComputePatchFeat(cur_patch.visual_data.custom_feats, feat);
				patch_data.push_back(feat);
				patch_meta.objects.push_back(cur_patch);
			}
				
				//}
			//}
		}
		
		cout<<"finished image: "<<i<<"/"<<imgfns.size()<<endl;
		cout<<"db size: "<<patch_data.rows<<endl;
	}

	cout<<"total patch number: "<<patch_data.rows<<endl;

	if(use_code) {
		// compress to codes
		LSHCoder lsh_coder;
		if( !lsh_coder.LearnOptimalCodes(patch_data, 64, patch_keys) ) {
			return false;
		}
	}

	return true;
}
Ejemplo n.º 3
0
Archivo: kb.c Proyecto: fatman2021/byok
void keyboard_handler(registers_t *r)
{
    unsigned char scancode = inportb(0x60);
    //printf("r->int_no=%d,scancode=0x%x,caps=%d,shift=%d,control=%d,capacity=%d\n",
    //        r->int_no, scancode, caps, shift, control, capacity(q));

    if (scancode & 0x80)
    {
        switch (scancode)
        {
            case SCANCODE_LEFT_SHIFT | 0x80:
            case SCANCODE_RIGHT_SHIFT | 0x80:
                flags.shift = 0;
                return;

            case SCANCODE_LEFT_CTRL | 0x80:
                flags.control = 0;
                return;

            case SCANCODE_LEFT_ALT | 0x80:
                flags.alt = 0;
                return;

            case 0xE0:
                flags.extended = 1;
                return;

            default:
                flags.extended = 0;
                return;
        }
    }

    switch (scancode)
    {
        case SCANCODE_LEFT_SHIFT:
        case SCANCODE_RIGHT_SHIFT:
            flags.shift = 1;
            return;

        case SCANCODE_LEFT_CTRL:
            flags.control = 1;
            return;

        case SCANCODE_LEFT_ALT:
            flags.alt = 1;
            return;

        case SCANCODE_CAPSLOCK:
            flags.capslock = ~flags.capslock;
            return;
    }

    char c;
    if (flags.shift && !flags.capslock)
    {
        c = shift_map(kbd_map, scancode);
    }
    else if (flags.shift && flags.capslock)
    {
        c = normal_map(kbd_map, scancode);
    }
    else if (flags.capslock)
    {
        c = caps_map(kbd_map, scancode);
    }
    else
    {
        c = normal_map(kbd_map, scancode);
    }

    input_t input = { .flags = flags, .scancode = scancode, .keycode = c };
    _putch(input);

    flags.extended = 0;
}
Ejemplo n.º 4
0
bool ObjPatchMatcher::Match(const Mat& cimg, const Mat& dmap_raw, Mat& mask_map) {

	/*
	 * precompute feature maps
	 */
	// gradient
	Mat gray_img, gray_img_float, edge_map;
	cvtColor(cimg, gray_img, CV_BGR2GRAY);
	gray_img.convertTo(gray_img_float, CV_32F, 1.f/255);
	Canny(gray_img, edge_map, 10, 50);
	cv::imshow("edge", edge_map);
	cv::imshow("color", cimg);
	cv::waitKey(10);

	Mat grad_x, grad_y, grad_mag;
	Sobel(gray_img_float, grad_x, CV_32F, 1, 0);
	Sobel(gray_img_float, grad_y, CV_32F, 0, 1);
	magnitude(grad_x, grad_y, grad_mag);

	// depth
	Mat dmap_float, pts3d, normal_map;
	if( use_depth ) {
		Feature3D feat3d;
		dmap_raw.convertTo(dmap_float, CV_32F);
		Mat cmp_mask;
		compare(dmap_float, 800, cmp_mask, CMP_LT);
		dmap_float.setTo(800, cmp_mask);
		compare(dmap_float, 7000, cmp_mask, CMP_GT);
		dmap_float.setTo(7000, cmp_mask);
		dmap_float = (dmap_float-800)/(7000-800);

		feat3d.ComputeKinect3DMap(dmap_float, pts3d, false);
		feat3d.ComputeNormalMap(pts3d, normal_map);
	}

	/*
	 *	start searching
	 */
	// init searcher
	//searcher.Build(patch_data, BruteForce_L2);	// opencv bfmatcher has size limit: maximum 2^31
	LSHCoder lsh_coder;
	if(use_code) {
		lsh_coder.Load();
	}
	
	Mat score_map = Mat::zeros(edge_map.rows, edge_map.cols, CV_32F);
	Mat mask_vote_map = Mat::zeros(cimg.rows, cimg.cols, CV_32F);
	mask_map = Mat::zeros(cimg.rows, cimg.cols, CV_32F);
	Mat mask_count = Mat::zeros(cimg.rows, cimg.cols, CV_32S);	// number of mask overlapped on each pixel
	Mat feat;
	int topK = 40;
	int total_cnt = countNonZero(edge_map);
	vector<VisualObject> query_patches;
	query_patches.reserve(total_cnt);

	cout<<"Start match..."<<endl;
	
	float max_dist = 0;
	int cnt = 0;
	char str[30];
	double start_t = getTickCount();
//#pragma omp parallel for
	for(int r=patch_size.height/2; r<gray_img.rows-patch_size.height/2; r+=3) {
		for(int c=patch_size.width/2; c<gray_img.cols-patch_size.width/2; c+=3) {

			/*int rand_r = rand()%gray_img.rows;
			int rand_c = rand()%gray_img.cols;
			if(rand_r < patch_size.height/2 || rand_r > gray_img.rows-patch_size.height/2 ||
				rand_c < patch_size.width/2 || rand_c > gray_img.cols-patch_size.width/2) continue;*/
			int rand_r = r, rand_c = c;

			if(edge_map.at<uchar>(rand_r, rand_c) > 0) 
			{
				cnt++;
				destroyAllWindows();

				Rect box(rand_c-patch_size.width/2, rand_r-patch_size.height/2, patch_size.width, patch_size.height);
				MatFeatureSet featset;
				gray_img_float(box).copyTo(featset["gray"]);
				//grad_mag(box).copyTo(featset["gradient"]);
				if(use_depth)
				{ 
					normal_map(box).copyTo(featset["normal"]);
					dmap_float(box).copyTo(featset["depth"]);
				}
				ComputePatchFeat(featset, feat);
				vector<DMatch> matches;
				if(use_code) 
				{
					BinaryCodes codes;
					HashKey key_val;
					lsh_coder.ComputeCodes(feat, codes);
					HashingTools<HashKeyType>::CodesToKey(codes, key_val);
					MatchCode(key_val, topK, matches);
				}
				else
				{
					MatchPatch(feat, topK, matches);
				}
				
				if(matches[0].distance < 0 || matches[0].distance > 1000) {
					cout<<"match dist: "<<matches[0].distance<<endl;
					double minv, maxv;
					cout<<norm(feat, patch_data.row(matches[0].trainIdx), NORM_L2)<<endl;
					minMaxLoc(feat, &minv, &maxv);
					cout<<minv<<" "<<maxv<<endl;
					cout<<feat<<endl<<endl;
					minMaxLoc(patch_data.row(matches[0].trainIdx), &minv, &maxv);
					cout<<minv<<" "<<maxv<<endl;
					cout<<patch_data.row(matches[0].trainIdx)<<endl;
					imshow("cimg", cimg);
					waitKey(0);
				}
				vector<vector<Mat>> pixel_mask_vals(patch_size.height, vector<Mat>(patch_size.width, Mat::zeros(1, topK, CV_32F)));
				VisualObject cur_query;
				cur_query.visual_data.bbox = box;
				cur_query.visual_data.mask = Mat::zeros(patch_size.height, patch_size.width, CV_32F);
				for(size_t i=0; i<topK; i++) { 
					score_map.at<float>(rand_r,rand_c) += matches[i].distance;
					cur_query.visual_data.mask += patch_meta.objects[matches[i].trainIdx].visual_data.mask;
					for(int mr=0; mr<patch_size.height; mr++) for(int mc=0; mc<patch_size.width; mc++) {
						pixel_mask_vals[mr][mc].at<float>(i) = 
							patch_meta.objects[matches[i].trainIdx].visual_data.mask.at<float>(mr, mc);
					}
				}
				score_map.at<float>(rand_r,rand_c) /= topK;
				cur_query.visual_data.mask /= topK;			// average returned mask
				
				// compute mask quality
				Scalar mean_, std_;
				/*ofstream out("pixel_mask_std_100.txt", ios::app);
				for(int mr=0; mr<patch_size.height; mr++) for(int mc=0; mc<patch_size.width; mc++) {
				meanStdDev(pixel_mask_vals[mr][mc], mean_, std_);
				out<<std_.val[0]<<" ";
				}
				out<<endl;*/
				meanStdDev(cur_query.visual_data.mask, mean_, std_);
				cur_query.visual_data.scores.push_back(mean_.val[0]);
				cur_query.visual_data.scores.push_back(std_.val[0]);

				Mat align_mask = Mat::zeros(cimg.rows, cimg.cols, CV_8U);
				int gt_mask_id = patch_meta.objects[matches[0].trainIdx].meta_data.category_id;
				if(gt_mask_id != -1) {
					Mat nn_mask = gt_obj_masks[gt_mask_id];
					//imshow("gt mask", nn_mask*255);
					//waitKey(10);
					Rect gt_box = patch_meta.objects[matches[0].trainIdx].visual_data.bbox;
					Rect align_box = AlignBox(box, gt_box, cimg.cols, cimg.rows);
					vector<ImgWin> boxes; boxes.push_back(align_box);
					//ImgVisualizer::DrawWinsOnImg("alignbox", cimg, boxes);
					//waitKey(10);
					Rect target_box = Rect(box.x-(gt_box.x-align_box.x), box.y-(gt_box.y-align_box.y), align_box.width, align_box.height);
					cout<<target_box<<endl;
					nn_mask(align_box).copyTo(align_mask(target_box));
				}
				align_mask.convertTo(align_mask, CV_32F);
				mask_map += align_mask * matches[0].distance;	//*score_map.at<float>(r,c);
				//mask_count(box) = mask_count(box) + 1;

				//cout<<score_map.at<float>(r,c)<<endl;
				max_dist = MAX(max_dist, matches[0].distance);
				query_patches.push_back(cur_query);

				// vote object regions
				/*Point3f line_ori;
				int obj_pt_sign;
				ComputeDominantLine(cur_query.visual_desc.mask, box.tl(), line_ori, obj_pt_sign);
				for(int rr=0; rr<cimg.rows; rr++) for(int cc=0; cc<cimg.cols; cc++) {
				float line_val = line_ori.x*cc+line_ori.y*rr+line_ori.z;
				if((line_val>0?1:-1)==obj_pt_sign) mask_vote_map.at<float>(rr, cc)++;
				}*/

#ifdef VERBOSE

				// current patch
				Mat disp, patch_gray, patch_grad, patch_normal, patch_depth;
				disp = cimg.clone();
				rectangle(disp, box, CV_RGB(255,0,0), 2);
				resize(gray_img(box), patch_gray, Size(50,50));
				resize(grad_mag(box), patch_grad, Size(50,50));
				Mat cur_mask;
				resize(cur_query.visual_desc.mask, cur_mask, Size(50,50));
				if(use_depth) 
				{
					resize(normal_map(box), patch_normal, Size(50,50));

					normalize(dmap_float(box), patch_depth, 1, 0, NORM_MINMAX);
					patch_depth.convertTo(patch_depth, CV_8U, 255);
					//dmap_float(box).convertTo(patch_depth, CV_8U, 255);
					resize(patch_depth, patch_depth, Size(50,50));
				}

				Mat onormal;
				sprintf_s(str, "query_gray_%d.jpg", cnt);
				imshow(str, patch_gray);
				imwrite(str, patch_gray);

				/*sprintf_s(str, "query_grad_%d.jpg", cnt);
				ImgVisualizer::DrawFloatImg(str, patch_grad, onormal, true);
				imwrite(str, onormal);*/
				
				sprintf_s(str, "query_depth_%d.jpg", cnt);
				imshow(str, patch_depth);
				imwrite(str, patch_depth);
				
				sprintf_s(str, "query_normal_%d.jpg", cnt);
				ImgVisualizer::DrawNormals(str, patch_normal, onormal, true);
				imwrite(str, onormal);

				sprintf_s(str, "query_box_%d.jpg", cnt);
				imshow(str, disp);
				imwrite(str, disp);

				//imshow("align mask", align_mask*255);

				cur_mask.convertTo(cur_mask, CV_8U, 255);
				sprintf_s(str, "query_tmask_%d.jpg", cnt);
				imshow(str, cur_mask);
				imwrite(str, cur_mask);

				// show match results
				vector<Mat> res_imgs(topK);
				vector<Mat> res_gradients(topK);
				vector<Mat> res_normals(topK);
				vector<Mat> res_depth(topK);
				vector<Mat> db_boxes(topK);
				vector<Mat> res_masks(topK);
				for(size_t i=0; i<topK; i++) {
					VisualObject& cur_obj = patch_meta.objects[matches[i].trainIdx];
					// mask
					cur_obj.visual_desc.mask.convertTo(res_masks[i], CV_8U, 255);
					// gray
					cur_obj.visual_desc.extra_features["gray"].convertTo(res_imgs[i], CV_8U, 255);
					// gradient
					//ImgVisualizer::DrawFloatImg("", cur_obj.visual_desc.extra_features["gradient"], res_gradients[i], false);
					// 3D
					if(use_depth) 
					{
						// normal
						tools::ImgVisualizer::DrawNormals("", cur_obj.visual_desc.extra_features["normal"], res_normals[i]);
						// depth
						normalize(cur_obj.visual_desc.extra_features["depth"], res_depth[i], 1, 0, NORM_MINMAX);
						res_depth[i].convertTo(res_depth[i], CV_8U, 255);
						//cur_obj.visual_desc.extra_features["depth"].convertTo(res_depth[i], CV_8U, 255);
					}
					// box on image
					db_boxes[i] = imread(patch_meta.objects[matches[i].trainIdx].imgpath);
					resize(db_boxes[i], db_boxes[i], Size(cimg.cols, cimg.rows));
					rectangle(db_boxes[i], patch_meta.objects[matches[i].trainIdx].visual_desc.box, CV_RGB(255,0,0), 2);
				}
				Mat out_img;
				sprintf_s(str, "res_gray_%d.jpg", cnt);
				ImgVisualizer::DrawImgCollection(str, res_imgs, topK, Size(50,50), out_img);
				imwrite(str, out_img);
				
				sprintf_s(str, "res_normal_%d.jpg", cnt);
				ImgVisualizer::DrawImgCollection(str, res_normals, topK, Size(50,50), out_img);
				imwrite(str, out_img);

				sprintf_s(str, "res_depth_%d.jpg", cnt);
				ImgVisualizer::DrawImgCollection(str, res_depth, topK, Size(50,50), out_img);
				imwrite(str, out_img);

				/*sprintf_s(str, "res_gradient_%d.jpg", cnt);
				tools::ImgVisualizer::DrawImgCollection(str, res_gradients, topK, Size(50,50), out_img);
				imwrite(str, out_img);*/

				sprintf_s(str, "res_mask_%d.jpg", cnt);
				tools::ImgVisualizer::DrawImgCollection(str, res_masks, topK, Size(50,50), out_img);
				imwrite(str, out_img);

				sprintf_s(str, "res_box_%d.jpg", cnt);
				tools::ImgVisualizer::DrawImgCollection(str, db_boxes, topK/2, Size(200, 200), out_img);
				imwrite(str, out_img);

				waitKey(0);
#endif

				cout<<total_cnt--<<endl;
			}
		}
	}
	cout<<"match done. Time cost: "<<(getTickCount()-start_t)/getTickFrequency()<<"s."<<endl;

	//score_map(Rect(patch_size.width/2, patch_size.height/2, score_map.cols-patch_size.width/2, score_map.rows-patch_size.height/2)).copyTo(score_map);
	//score_map.setTo(max_dist, 255-edge_map);
	normalize(score_map, score_map, 1, 0, NORM_MINMAX);
	score_map = 1-score_map;
	//tools::ImgVisualizer::DrawFloatImg("bmap", score_map);

	mask_map /= max_dist;
	cout<<max_dist<<endl;
	normalize(mask_map, mask_map, 1, 0, NORM_MINMAX);
	//tools::ImgVisualizer::DrawFloatImg("maskmap", mask_map);

	//normalize(mask_vote_map, mask_vote_map, 1, 0, NORM_MINMAX);
	//ImgVisualizer::DrawFloatImg("vote map", mask_vote_map);
	//waitKey(0);

	return true;

	// pick top weighted points to see if they are inside objects
	// try graph-cut for region proposal
	// among all retrieved mask patch, select most discriminative one and do graph-cut
	sort(query_patches.begin(), query_patches.end(), [](const VisualObject& a, const VisualObject& b) { 
		return a.visual_data.scores[1] > b.visual_data.scores[1]; });
	for(size_t i=0; i<query_patches.size(); i++) {
		Mat disp_img = cimg.clone();
		rectangle(disp_img, query_patches[i].visual_data.bbox, CV_RGB(255,0,0));
		imshow("max std box", disp_img);
		Mat big_mask;
		resize(query_patches[i].visual_data.mask, big_mask, Size(50,50));
		ImgVisualizer::DrawFloatImg("max std mask", big_mask);
		waitKey(0);
		// use mask to do graph-cut
		Mat fg_mask(cimg.rows, cimg.cols, CV_8U);
		fg_mask.setTo(cv::GC_PR_FGD);
		Mat th_mask;
		threshold(query_patches[i].visual_data.mask, th_mask, query_patches[i].visual_data.scores[0], 1, CV_THRESH_BINARY);
		th_mask.convertTo(th_mask, CV_8U);
		fg_mask(query_patches[i].visual_data.bbox).setTo(cv::GC_FGD, th_mask);
		th_mask = 1-th_mask;
		fg_mask(query_patches[i].visual_data.bbox).setTo(cv::GC_BGD, th_mask);
		cv::grabCut(cimg, fg_mask, Rect(0,0,1,1), Mat(), Mat(), 3, cv::GC_INIT_WITH_MASK);
		fg_mask = fg_mask & 1;
		disp_img.setTo(Vec3b(0,0,0));
		cimg.copyTo(disp_img, fg_mask);
		cv::imshow("cut", disp_img);
		cv::waitKey(0);
	}


	float ths[] = {0.9f, 0.8f, 0.7f, 0.6f, 0.5f, 0.4f, 0.3f, 0.2f};
	for(size_t i=0; i<8; i++) {
		Mat th_mask;
		threshold(mask_map, th_mask, ths[i], 1, CV_THRESH_BINARY);
		char str[30];
		sprintf_s(str, "%f", ths[i]);
		ImgVisualizer::DrawFloatImg(str, th_mask);
		waitKey(0);
	}

	return true;
}