blockMatching.cpp source
#include <FAST/Algorithms/BlockMatching/BlockMatching.hpp> #include <FAST/Streamers/ImageFileStreamer.hpp> #include <FAST/Visualization/SimpleWindow.hpp> #include <FAST/Visualization/ImageRenderer/ImageRenderer.hpp> #include <FAST/Visualization/VectorFieldRenderer/VectorFieldRenderer.hpp> #include <FAST/Visualization/VectorFieldRenderer/VectorFieldColorRenderer.hpp> #include <FAST/Tools/CommandLineParser.hpp> #include <FAST/Algorithms/VectorMedianFilter/VectorMedianFilter.hpp> #include <FAST/Exporters/StreamToFileExporter.hpp> #include <FAST/Exporters/ImageFileExporter.hpp> using namespace fast; int main(int argc, char** argv) { CommandLineParser parser("Block matching"); parser.addPositionVariable(1, "path", Config::getTestDataPath() + "/US/Heart/ApicalFourChamber/US-2D_#.mhd", "Path to the recording to stream, e.g. /path/to/frames/frame_#.mhd"); parser.addVariable("block-size", "5", "The size in pixels of the blocks to match. Has to be odd."); parser.addVariable("search-size", "9", "The size in pixels of the grid to search for a match. Has to be odd"); parser.addVariable("intensity-threshold", "75.0f", "Lower intensity of a threshold to search for a block. If a block has lower intensity that this, it will not look for a match."); parser.addVariable("median-filter-size", "7", "Size of vector median filter window to run after block matching. Must be odd and larger than 3."); parser.addVariable("export-to", "", "Specify a path to export the vector field for each frame. E.g. /path/to/somewhere/"); parser.addChoice("export-format", {"mhd"}, "mhd", "Specify export format"); parser.addChoice("matching-metric", {"SAD", "SSD", "NCC"}, "SAD", "Matching metric used for calculating how similar two blocks are."); parser.addOption("display-lines", "Display vector field as lines instead of color overlay"); parser.addOption("disable-compression", "Disable compression when saving as mhd (.zraw)"); parser.parse(argc, argv); auto streamer = ImageFileStreamer::create(parser.get("path"), true, true, 40); auto blockMatching = BlockMatching::create( parser.get<int>("block-size"), parser.get<int>("search-size"), BlockMatching::stringToMetric(parser.get("matching-metric")) )->connect(streamer); blockMatching->setIntensityThreshold(parser.get<float>("intensity-threshold")); blockMatching->enableRuntimeMeasurements(); ProcessObject::pointer source = blockMatching; if(parser.get<int>("median-filter-size") > 0) { auto filter = VectorMedianFilter::create(parser.get<int>("median-filter-size"))->connect(blockMatching); source = filter; } if(!parser.gotValue("export-to")) { streamer->enableLooping(); // Visualize auto renderer = ImageRenderer::create()->connect(streamer); auto window = SimpleWindow2D::create(Color::Black())->connect(renderer); if (parser.getOption("display-lines")) { window->connect(VectorFieldRenderer::create(Color::Red())->connect(source)); } else { auto vectorRenderer = VectorFieldColorRenderer::create(); vectorRenderer->setIntensityWindow(1.0f); vectorRenderer->setIntensityLevel(0.5f); vectorRenderer->connect(source); window->connect(vectorRenderer); } window->run(); } else { // TODO Use StreamToFileExporter instead.. // Export vector fields to disk std::string exportPath = parser.get("export-to"); int timestep = 0; auto dataStream = DataStream(source); while(!dataStream.isDone()) { auto frame = dataStream.getNextFrame<Image>(); std::cout << "Processing frame: " << timestep << " " << frame.get() << std::endl; const std::string path = join(exportPath, "frame_" + std::to_string(timestep) + "." + parser.get("export-format")); auto exporter = ImageFileExporter::create(path); exporter->setInputData(frame); exporter->setCompression(!parser.getOption("disable-compression")); exporter->run(); ++timestep; } } blockMatching->getRuntime()->print(); }