コード例 #1
0
ファイル: VXLHelpers.cpp プロジェクト: daviddoria/VXLHelpers
	vnl_matrix<double> ReadImageMatrix(const std::string &Filename)
	{
		vil_image_view<vxl_byte> Image = vil_load(Filename.c_str());
		
		vnl_matrix<double> M(Image.ni(), Image.nj(), 0);
		
		for (unsigned j = 0; j < Image.nj(); j++)
		{
			for (unsigned i = 0; i < Image.ni(); i++)
			{
				M(i,j) = static_cast<double> (Image(i,j));
			}
		}
		
		return M/M.frobenius_norm();
	}
// [ref] ${VXL_HOME}/contrib/mul/fhs/tools/find_matches.cxx
int fhs_find_matches_example(int argc, char *argv[])
{
	vul_arg<vcl_string> image1_path("-i1", "Input image 1");
	vul_arg<vcl_string> image2_path("-i2", "Input image 2");
	vul_arg<vcl_string> output_image1_path("-o1", "Output image 1", "output1.png");
	vul_arg<vcl_string> output_image2_path("-o2", "Output image 1", "output2.png");
	vul_arg<unsigned> level("-L", "Image pyramid level to work on", 2);
	vul_arg<unsigned> nc("-n", "Number of points to select", 10);
	vul_arg<unsigned> w("-w", "Half width of filters", 7);
	vul_arg<double> f("-f", "Relative strength of intensity vs shape", 0.1);

	vul_arg_parse(argc, argv);

	if (image1_path() == "" || image2_path() == "")
	{
		local::print_usage();
		return 0;
	}

	// ============================================
	// Attempt to load in images
	// ============================================

	vimt_image_2d_of<vxl_byte> image1, image2;
	image1.image() = vil_load(image1_path().c_str());
	if (image1.image().size() == 0)
	{
		vcl_cerr << "Unable to read in image from " << image1_path() << vcl_endl;
		return 1;
	}
	image2.image() = vil_load(image2_path().c_str());
	if (image2.image().size() == 0)
	{
		vcl_cerr <<" Unable to read in image from " << image2_path() << vcl_endl;
		return 1;
	}

	// ============================================
	// Build image pyramids and select chosen level
	// ============================================
	vimt_gaussian_pyramid_builder_2d<vxl_byte> pyr_builder;
	vimt_image_pyramid image_pyr1, image_pyr2;
	pyr_builder.build(image_pyr1, image1);
	pyr_builder.build(image_pyr2, image2);

	const vimt_image_2d_of<vxl_byte> &image1_L = static_cast<const vimt_image_2d_of<vxl_byte> &>(image_pyr1(level()));
	const vimt_image_2d_of<vxl_byte> &image2_L = static_cast<const vimt_image_2d_of<vxl_byte> &>(image_pyr2(level()));

	// ====================================================
	// Apply corner operator to image1_L and select corners
	// ====================================================

	vimt_image_2d_of<float> corner_im;
	corner_im.set_world2im(image1_L.world2im());
	vil_corners(image1_L.image(), corner_im.image());

	vcl_vector<unsigned> pi, pj;
	float threshold = 4.0f;
	vil_find_peaks_3x3(pi, pj, corner_im.image(), threshold);

	// Evaluate corner strength at each point (pi[i], pj[i])
	unsigned n = pi.size();
	vcl_vector<float> corner_str(n);
	for (unsigned i = 0 ; i < n; ++i)
		corner_str[i] = corner_im.image()(pi[i], pj[i]);

	// Sort and generate a list of image points and equivalent world points
	vcl_vector<unsigned> index;
	mbl_index_sort(corner_str, index);

	unsigned n_c = vcl_min(nc(),n);
	vcl_vector<vgl_point_2d<int> > im_pts(n_c);
	vcl_vector<vgl_point_2d<double> > w_pts(n_c);
	vimt_transform_2d im2w = image1_L.world2im().inverse();
	for (unsigned i = 0; i < n_c; ++i)
	{
		im_pts[i] = vgl_point_2d<int>(pi[index[n - 1 - i]], pj[index[n - 1 - i]]);
		w_pts[i] = im2w(pi[index[n - 1 - i]], pj[index[n - 1 - i]]);
	}


	// ========================================================
	// Extract patches around each selected point and normalise
	// ========================================================
	vcl_vector<vil_image_view<float> > patch(n_c);
	vcl_vector<vgl_point_2d<double> > patch_ref(n_c);  // Reference point
	int ni = image1.image().ni();
	int nj = image1.image().nj();
	for (unsigned i = 0; i < n_c; ++i)
	{
		// Select region around point, allowing for image edges.
		int ilo = vcl_max(0, int(im_pts[i].x() - w()));
		int ihi = vcl_min(ni - 1, int(im_pts[i].x() + w()));
		int jlo = vcl_max(0, int(im_pts[i].y() - w()));
		int jhi = vcl_min(nj - 1, int(im_pts[i].y() + w()));

		// Compute position of reference point relative to corner
		int kx = im_pts[i].x() - ilo;
		int ky = im_pts[i].y() - jlo;
		patch_ref[i] = vgl_point_2d<double>(kx, ky);
		vil_convert_cast(vil_crop(image1_L.image(), ilo, 1 + ihi - ilo, jlo, 1 + jhi - jlo), patch[i]);
		vil_math_normalise(patch[i]);
	}

	// Construct tree structure for points
	vcl_vector<vcl_pair<int, int> > pairs;
	mbl_minimum_spanning_tree(w_pts, pairs);

	assert(pairs.size() == n_c - 1);

	// Draw tree into image for display purposes
	local::draw_tree(image1.image(), w_pts, pairs);

	if (vil_save(image1.image(), output_image1_path().c_str()))
	{
		vcl_cout << "Saved output image 1 to " << output_image1_path() << vcl_endl;
	}

	// =================================================
	// Construct the arc model from the points and pairs
	// =================================================

	vcl_vector<fhs_arc> arcs(n_c - 1);
	int root_node = pairs[0].first;
	for (unsigned i = 0; i < pairs.size(); ++i)
	{
		int i1 = pairs[i].first;
		int i2 = pairs[i].second;
		vgl_vector_2d<double> dp = w_pts[i2] - w_pts[i1];
		double sd_x = vcl_max(0.1 * ni, 0.2 * dp.length());
		double sd_y = vcl_max(0.1 * nj, 0.2 * dp.length());
		arcs[i] = fhs_arc(i1, i2, dp.x(), dp.y(), sd_x * sd_x, sd_y * sd_y);
	}

	// =================================================
	// Apply filters to image2 (initially to whole image)
	// =================================================
	vcl_vector<vimt_image_2d_of<float> > feature_response(n_c);
	for (unsigned i = 0; i < n_c; ++i)
	{
		// Apply to whole image in first instance
		// Ideally would crop a region around expected position
		vimt_normalised_correlation_2d(image2_L, feature_response[i], patch[i], patch_ref[i], float());

		// Need good values to be small, not large, so apply -ve factor
		vil_math_scale_values(feature_response[i].image(), -f());
	}

	// ======================================================
	// Use fhs_searcher to locate equivalent points on image2
	// ======================================================

	fhs_searcher searcher;
	searcher.set_tree(arcs, root_node);
	searcher.search(feature_response);
	vcl_vector<vgl_point_2d<double> > pts2;
	searcher.best_points(pts2);

	// Draw tree into image for display purposes
	local::draw_tree(image2.image(), pts2, pairs);

	if (vil_save(image2.image(), output_image2_path().c_str()))
	{
		vcl_cout << "Saved output image 2 to " << output_image2_path() << vcl_endl;
	}

	return 0;
}
// [ref] ${VXL_HOME}/contrib/mul/msm/tools/msm_draw_points_on_image.cxx
int msm_draw_points_on_image_example(int argc, char *argv[])
{
	vul_arg<vcl_string> curves_path("-c", "File containing curves");
	vul_arg<vcl_string> pts_path("-p", "File containing points");
	vul_arg<vcl_string> image_path("-i", "Image");
	vul_arg<vcl_string> out_path("-o", "Output path","image+pts.eps");
	vul_arg<vcl_string> line_colour("-lc", "Line colour","yellow");
	vul_arg<vcl_string> pt_colour("-pc", "Point colour","none");
	vul_arg<vcl_string> pt_edge_colour("-pbc", "Point border colour","none");
	vul_arg<double> pt_radius("-pr", "Point radius",2.0);
	vul_arg<double> scale("-s", "Scaling to apply",1.0);

	vul_arg_parse(argc, argv);

	if (pts_path() == "")
	{
		local::print_usage();
		return 0;
	}

	msm_curves curves;
	if (curves_path() != "" && !curves.read_text_file(curves_path()))
		vcl_cerr << "Failed to read in curves from " << curves_path() << vcl_endl;

	msm_points points;
	if (!points.read_text_file(pts_path()))
	{
		vcl_cerr << "Failed to read points from " << pts_path() << vcl_endl;
		return 2;
	}
	vcl_vector<vgl_point_2d<double> > pts;
	points.get_points(pts);

	//================ Attempt to load image ========
	vil_image_view<vxl_byte> image;
	if (image_path() != "")
	{
		image = vil_load(image_path().c_str());
		if (image.size() == 0)
		{
			vcl_cout << "Failed to load image from " << image_path() << vcl_endl;
			return 1;
		}
		vcl_cout << "Image is " << image << vcl_endl;
	}

	if (scale() > 1.001 || scale() < 0.999)
	{
		// Scale image and points
		vil_image_view<vxl_byte> image2;
		image2.deep_copy(image);
		if (scale() < 0.51)
			vil_gauss_filter_2d(image, image2, 1.0, 3);
		vil_resample_bilin(image2, image, int(0.5 + scale() * image.ni()), int(0.5 + scale() * image.nj()));

		points.scale_by(scale());
	}


	// Compute bounding box of points
	vgl_box_2d<double> bbox = points.bounds();
	bbox.scale_about_centroid(1.05);  // Add a border

	// If an image is supplied, use that to define bounding box
	if (image.size() > 0)
	{
		bbox = vgl_box_2d<double>(0, image.ni(), 0,image.nj());
	}

	vgl_point_2d<double> blo = bbox.min_point();

	// Translate all points to allow for shift of origin
	points.translate_by(-blo.x(), -blo.y());

	mbl_eps_writer writer(out_path().c_str(), bbox.width(), bbox.height());

	if (image.size() > 0)
		writer.draw_image(image, 0, 0, 1, 1);

	if (pt_colour() != "none")
	{
		// Draw all the points
		writer.set_colour(pt_colour());
		msm_draw_points_to_eps(writer, points, pt_radius());
	}

	if (pt_edge_colour() != "none")
	{
		// Draw disks around all the points
		writer.set_colour(pt_edge_colour());
		msm_draw_points_to_eps(writer, points, pt_radius(), false);
	}

	if (curves.size() > 0 && line_colour() != "none")
	{
		// Draw all the lines
		writer.set_colour(line_colour());
		msm_draw_shape_to_eps(writer, points, curves);
	}
	writer.close();

	vcl_cout << "Graphics saved to " << out_path() << vcl_endl;

	return 0;
}