void VisualizationWorkstationExtensionPlugin::loadNewForegroundImage(const std::string& resultImagePth) { if (_foreground) { _foregroundScale = 1; emit changeForegroundImage(std::weak_ptr<MultiResolutionImage>(), _foregroundScale); _foreground.reset(); } QGroupBox* segmentationGroupBox = _dockWidget->findChild<QGroupBox*>("SegmentationGroupBox"); segmentationGroupBox->setEnabled(false); QGroupBox* visualizationGroupBox = _dockWidget->findChild<QGroupBox*>("VisualizationGroupBox"); visualizationGroupBox->setEnabled(false); if (core::fileExists(resultImagePth)) { MultiResolutionImageReader reader; _foreground.reset(reader.open(resultImagePth)); if (_foreground) { setDefaultVisualizationParameters(_foreground); std::vector<unsigned long long> dimsFG = _foreground->getDimensions(); if (_backgroundDimensions[0] / dimsFG[0] == _backgroundDimensions[1] / dimsFG[1]) { _foregroundScale = _backgroundDimensions[0] / dimsFG[0]; if (_likelihoodCheckBox) { if (_renderingEnabled) { if (_likelihoodCheckBox->isChecked()) { emit changeForegroundImage(_foreground, _foregroundScale); } else { _likelihoodCheckBox->setChecked(true); } } else { if (_likelihoodCheckBox->isChecked()) { _likelihoodCheckBox->setChecked(false); } else { emit changeForegroundImage(std::weak_ptr<MultiResolutionImage>(), _foregroundScale); } } } } QGroupBox* segmentationGroupBox = _dockWidget->findChild<QGroupBox*>("SegmentationGroupBox"); segmentationGroupBox->setEnabled(true); QGroupBox* visualizationGroupBox = _dockWidget->findChild<QGroupBox*>("VisualizationGroupBox"); visualizationGroupBox->setEnabled(true); } } }
int main(int argc, char *argv[]) { try { std::string inputPth, outputPth; unsigned int processedLevel; int component; float lowerThreshold, upperThreshold; po::options_description desc("Options"); desc.add_options() ("help,h", "Displays this message") ("level,l", po::value<unsigned int>(&processedLevel)->default_value(0), "Set the level to be processed") ("component,c", po::value<int>(&component)->default_value(-1), "Color component to select for threshold, if none, threshold all.") ("lower_threshold,ll", po::value<float>(&lowerThreshold)->default_value(std::numeric_limits<float>::min()), "Set the lower threshold") ("upper_threshold,ul", po::value<float>(&upperThreshold)->default_value(std::numeric_limits<float>::max()), "Set the upper threshold") ; po::positional_options_description positionalOptions; positionalOptions.add("input", 1); positionalOptions.add("output", 1); po::options_description posDesc("Positional descriptions"); posDesc.add_options() ("input", po::value<std::string>(&inputPth)->required(), "Path to input") ("output", po::value<std::string>(&outputPth)->default_value("."), "Path to output") ; po::options_description descAndPos("All options"); descAndPos.add(desc).add(posDesc); po::variables_map vm; try { po::store(po::command_line_parser(argc, argv).options(descAndPos) .positional(positionalOptions).run(), vm); if (!vm.count("input")) { cout << "WSIThreshold v1.0" << endl; cout << "Usage: WSIThreshold.exe input output [options]" << endl; } if (vm.count("help")) { std::cout << desc << std::endl; return 0; } po::notify(vm); } catch (boost::program_options::required_option& e) { std::cerr << "ERROR: " << e.what() << std::endl << std::endl; std::cerr << "Use -h or --help for usage information" << std::endl; return 1; } MultiResolutionImageReader reader; MultiResolutionImage* input = reader.open(inputPth); CmdLineProgressMonitor monitor; if (input) { ThresholdWholeSlideFilter fltr; fltr.setInput(input); fltr.setOutput(outputPth); fltr.setProgressMonitor(&monitor); fltr.setLowerThreshold(lowerThreshold); fltr.setUpperThreshold(upperThreshold); fltr.setProcessedLevel(processedLevel); if (!fltr.process()) { std::cerr << "ERROR: Processing failed" << std::endl; } delete input; } else { std::cerr << "ERROR: Invalid input image" << std::endl; } } catch (std::exception& e) { std::cerr << "Unhandled exception: " << e.what() << ", application will now exit" << std::endl; return 2; } return 0; }
int main(int argc, char *argv[]) { try { std::string inputPth; po::options_description desc("Options"); desc.add_options() ("help,h", "Displays this message") ; po::positional_options_description positionalOptions; positionalOptions.add("input", 1); po::options_description posDesc("Positional descriptions"); posDesc.add_options() ("input", po::value<std::string>(&inputPth)->required(), "Path to input") ; po::options_description descAndPos("All options"); descAndPos.add(desc).add(posDesc); po::variables_map vm; try { po::store(po::command_line_parser(argc, argv).options(descAndPos) .positional(positionalOptions).run(), vm); if (!vm.count("input")) { cout << "Camelyon v1.0" << endl; cout << "Usage: Camelyon.exe input [options]" << endl; } if (vm.count("help")) { std::cout << desc << std::endl; return 0; } po::notify(vm); } catch (boost::program_options::required_option& e) { std::cerr << "ERROR: " << e.what() << std::endl << std::endl; std::cerr << "Use -h or --help for usage information" << std::endl; return 1; } MultiResolutionImageReader reader; MultiResolutionImage* input = reader.open(inputPth); CmdLineProgressMonitor monitor; if (input) { // Assume input has a lvl 8 int lowResLvl = 8; vector<unsigned long long, allocator<unsigned long long>> lowResDim = input->getLevelDimensions(8); Patch<uchar> lowResPatch = input->getPatch<uchar>(0, 0, lowResDim[0], lowResDim[1], lowResLvl); Mat lowResMat = patchToMat(lowResPatch); cvtColor(lowResMat, lowResMat, COLOR_BGR2HSV); imshow("HSV", lowResMat); // Convert level 8 image to HSD color model ColorDeconvolutionFilter<uchar> *filter = new ColorDeconvolutionFilter<uchar>(); Patch<double> cxPatch, cyPatch, dPatch; filter->filter(lowResPatch, cxPatch); filter->setOutputStain(1); filter->filter(lowResPatch, cyPatch); filter->setOutputStain(2); filter->filter(lowResPatch, dPatch); Mat cX = patchToMat(cxPatch); Mat cY = patchToMat(cyPatch); Mat d = patchToMat(dPatch); // (temporary check) imshow("cX", cX); imshow("cY", cY); imshow("D", d); waitKey(0); // Assume 512 always fits integrally int tileWidth = 512; int tileHeight = 512; int lowResTileWidth = tileWidth / pow(2, lowResLvl); int lowResTileHeight = tileHeight / pow(2, lowResLvl); vector<unsigned long long, allocator<unsigned long long>> dim = input->getLevelDimensions(0); int numTilesX = dim[0] / tileWidth; int numTilesY = dim[1] / tileHeight; // Iterate over foreground tiles for (int y = 0; y < numTilesY; y++) { for (int x = 0; x < numTilesX; x++) { Rect r(x * lowResTileWidth, y * lowResTileHeight, lowResTileWidth, lowResTileHeight); if (isForeground(&d, r, 0.2, 0.1)) { // Get level 0 for tile Patch<uchar> p = input->getPatch<uchar>(x * tileWidth, y * tileHeight, tileWidth, tileHeight, 0); Mat m = patchToMat(p); // TODO Convert to HSD // Create histogram Mat rgbHist; int histSize = 256; int channels[] = { 0, 1, 2 }; float range[] = { 0, 256 }; const float* ranges[] = { range }; calcHist(&m, 1, channels, Mat(), rgbHist, 1, &histSize, ranges, true, false); cout << "Histo Created for (" << x << "," << y << ")\n"; // TODO Get avg, median, mode, min, max, variance, stddev, etc.. } } } delete filter; // TODO Output results to csv // TODO Train/Test model // TODO Evaluate results delete input; } else { std::cerr << "ERROR: Invalid input image" << std::endl; } } catch (std::exception& e) { std::cerr << "Unhandled exception: " << e.what() << ", application will now exit" << std::endl; return 2; } return 0; }
bool DistanceTransformWholeSlideFilter::process() const { std::vector<unsigned long long> dims = this->_input->getLevelDimensions(this->_processedLevel); double downsample = this->_input->getLevelDownsample(this->_processedLevel); MultiResolutionImageWriter writer; writer.setColorType(pathology::ColorType::Monochrome); writer.setCompression(pathology::Compression::LZW); writer.setDataType(pathology::DataType::UInt32); writer.setInterpolation(pathology::Interpolation::NearestNeighbor); writer.setTileSize(512); std::vector<double> spacing = _input->getSpacing(); if (!spacing.empty()) { spacing[0] *= downsample; spacing[1] *= downsample; writer.setSpacing(spacing); } writer.setProgressMonitor(_monitor); std::string firstPassFile = _outPath; std::string basename = core::extractBaseName(_outPath); core::changeBaseName(firstPassFile, basename + "_firstpass"); unsigned int* buffer_t_x = new unsigned int[512]; unsigned int* buffer_t_y = new unsigned int[512 * dims[0]]; unsigned char* tile = new unsigned char[512 * 512]; unsigned int* out_tile = new unsigned int[512 * 512]; unsigned int maxDist = (dims[0] + dims[1] / 2) + 1; std::fill(out_tile, out_tile + 512 * 512, maxDist); std::fill(buffer_t_x, buffer_t_x + 512, maxDist); std::fill(buffer_t_y, buffer_t_y + 512 * dims[0], maxDist); if (writer.openFile(firstPassFile) != 0) { std::cerr << "ERROR: Could not open file for writing" << std::endl; return false; } writer.writeImageInformation(dims[0], dims[1]); // Forward pass for (unsigned long long t_y = 0; t_y < dims[1]; t_y += 512) { std::fill(buffer_t_x, buffer_t_x + 512, maxDist); for (unsigned long long t_x = 0; t_x < dims[0]; t_x += 512) { this->_input->getRawRegion<unsigned char>(static_cast<unsigned long long>(t_x*downsample), static_cast<unsigned long long>(t_y*downsample), 512, 512, this->_processedLevel, tile); std::fill(out_tile, out_tile + 512 * 512, (dims[0] + dims[1] / 2) + 1); int startX = 0; int startY = 0; if (t_x == 0) { startX = 1; } if (t_y == 0) { startY = 1; } for (int y = startY; y < 512; ++y) { for (int x = startX; x < 512; ++x) { unsigned int curPos = y * 512 + x; unsigned char curVal = tile[curPos]; if (curVal == 1) { out_tile[curPos] = 0; } else { unsigned int upVal; if (y == 0) { upVal = buffer_t_y[t_x + x]; } else { upVal = out_tile[curPos - 512]; } unsigned int leftVal; if (x == 0) { leftVal = buffer_t_x[y]; } else { leftVal = out_tile[curPos - 1]; } unsigned int newDist = std::min(upVal, leftVal) + 1; if (newDist < maxDist) { out_tile[curPos] = newDist; } } if (x == 511) { buffer_t_x[y] = out_tile[y * 512 + x]; } if (y == 511) { buffer_t_y[t_x + x] = out_tile[y * 512 + x]; } } } writer.writeBaseImagePart(reinterpret_cast<void*>(out_tile)); } } std::fill(buffer_t_y, buffer_t_y + 512 * dims[0], maxDist); writer.finishImage(); // Backward pass MultiResolutionImageReader reader = MultiResolutionImageReader(); MultiResolutionImage* firstPass = reader.open(firstPassFile); if (writer.openFile(_outPath) != 0) { std::cerr << "ERROR: Could not open file for writing" << std::endl; return false; } writer.setProgressMonitor(_monitor); writer.writeImageInformation(dims[0], dims[1]); long long start_t_y = std::ceil(dims[1] / 512.)*512 - 512; long long start_t_x = std::ceil(dims[0] / 512.)*512 - 512; for (long long t_y = start_t_y; t_y >= 0; t_y -= 512) { std::fill(buffer_t_x, buffer_t_x + 512, maxDist); for (long long t_x = start_t_x; t_x >= 0; t_x -= 512) { firstPass->getRawRegion<unsigned int>(static_cast<unsigned long long>(t_x*downsample), static_cast<unsigned long long>(t_y*downsample), 512, 512, 0, out_tile); int startX = 511; int startY = 511; for (int y = 511; y >= 0; --y) { for (int x = 511; x >= 0; --x) { unsigned int curPos = y * 512 + x; unsigned int downVal; if (t_y + y + 1 >= dims[1]) { downVal = maxDist; } else if (y == 511) { downVal = buffer_t_y[t_x + x]; } else { downVal = out_tile[curPos + 512]; } unsigned int rightVal; if (t_x + x + 1 >= dims[0]) { rightVal = maxDist; } else if (x == 511) { rightVal = buffer_t_x[y]; } else { rightVal = out_tile[curPos + 1]; } unsigned int newDist = std::min(downVal, rightVal) + 1; if (newDist < out_tile[curPos]) { out_tile[curPos] = newDist; } if (x == 0) { buffer_t_x[y] = out_tile[y * 512 + x]; } if (y == 0) { buffer_t_y[t_x + x] = out_tile[y * 512 + x]; } } } writer.writeBaseImagePartToLocation(reinterpret_cast<void*>(out_tile), t_x, t_y); } } std::fill(buffer_t_y, buffer_t_y + 512 * dims[0], maxDist); writer.finishImage(); delete firstPass; delete[] buffer_t_x; delete[] buffer_t_y; delete[] tile; delete[] out_tile; core::deleteFile(firstPassFile); return true; }
bool NDPARepository::loadFromRepo() { if (!_list || _source.empty()) { return false; } _list->removeAllAnnotations(); _list->removeAllGroups(); std::shared_ptr<MultiResolutionImage> ndpi; if (_ndpiSourceFile.empty()) { std::vector<std::string> ndpaParts; core::split(_source, ndpaParts, ".ndpa"); if (core::fileExists(ndpaParts[0])) { MultiResolutionImageReader reader; ndpi.reset(reader.open(ndpaParts[0])); if (!ndpi) { return false; } } else { return false; } } float offsetX = core::fromstring<float>(ndpi->getProperty("hamamatsu.XOffsetFromSlideCentre")); float offsetY = core::fromstring<float>(ndpi->getProperty("hamamatsu.YOffsetFromSlideCentre")); float mppX = core::fromstring<float>(ndpi->getProperty("openslide.mpp-x")); float mppY = core::fromstring<float>(ndpi->getProperty("openslide.mpp-y")); std::vector<unsigned long long> dims = ndpi->getDimensions(); pugi::xml_document xml_doc; pugi::xml_parse_result tree = xml_doc.load_file(_source.c_str()); pugi::xml_node root = xml_doc.child("annotations"); unsigned int annotation_nr = 0; for (pugi::xml_node it = root.child("ndpviewstate"); it; it = it.next_sibling("ndpviewstate")) { for (pugi::xml_node annotation_xml = it.child("annotation"); annotation_xml; annotation_xml = annotation_xml.next_sibling("annotation")) { if (std::string(annotation_xml.attribute("type").value()) == std::string("freehand")) { std::shared_ptr<Annotation> annotation = std::make_shared<Annotation>(); annotation->setName(std::string(it.child_value("title")) + "_" + core::tostring(annotation_nr)); annotation->setTypeFromString("Polygon"); std::string annotColor = annotation_xml.attribute("color").value(); if (!annotColor.empty()) { annotation->setColor(annotColor); } pugi::xml_node coordinates = annotation_xml.child("pointlist"); for (pugi::xml_node_iterator cit = coordinates.begin(); cit != coordinates.end(); ++cit) { double x = core::fromstring<double>(cit->child_value("x")); double y = core::fromstring<double>(cit->child_value("y")); double corX = ((x - offsetX) / (mppX * 1000)) + (dims[0] / 2.); double corY = ((y - offsetY) / (mppY * 1000)) + (dims[1] / 2.); annotation->addCoordinate(corX, corY); } _list->addAnnotation(annotation); annotation_nr++; } } } return true; }
int main(int argc, char *argv[]) { try { std::string inputPth, outputPth; unsigned int processedLevel; std::string expression; po::options_description desc("Options"); desc.add_options() ("help,h", "Displays this message") ("level,l", po::value<unsigned int>(&processedLevel)->default_value(0), "Set the level to be processed") ("expression,e", po::value<std::string>(&expression)->default_value(""), "Set the arithmetical expression") ; po::positional_options_description positionalOptions; positionalOptions.add("input", 1); positionalOptions.add("output", 1); po::options_description posDesc("Positional descriptions"); posDesc.add_options() ("input", po::value<std::string>(&inputPth)->required(), "Path to input") ("output", po::value<std::string>(&outputPth)->default_value("."), "Path to output") ; po::options_description descAndPos("All options"); descAndPos.add(desc).add(posDesc); po::variables_map vm; try { po::store(po::command_line_parser(argc, argv).options(descAndPos) .positional(positionalOptions).run(), vm); if (!vm.count("input")) { cout << "WSILabelStatistics v" << ASAP_VERSION_STRING << endl; cout << "Usage: WSIConnectedComponents.exe input output [options]" << endl; } if (vm.count("help")) { std::cout << desc << std::endl; return 0; } po::notify(vm); } catch (boost::program_options::required_option& e) { std::cerr << "ERROR: " << e.what() << std::endl << std::endl; std::cerr << "Use -h or --help for usage information" << std::endl; return 1; } MultiResolutionImageReader reader; MultiResolutionImage* input = reader.open(inputPth); CmdLineProgressMonitor monitor; if (input) { ArithmeticWholeSlideFilter fltr; fltr.setInput(input); fltr.setOutput(outputPth); fltr.setProgressMonitor(&monitor); fltr.setExpression(expression); if (!fltr.process()) { std::cerr << "ERROR: Processing failed" << std::endl; } delete input; } else { std::cerr << "ERROR: Invalid input image" << std::endl; } } catch (std::exception& e) { std::cerr << "Unhandled exception: " << e.what() << ", application will now exit" << std::endl; return 2; } return 0; }
void convertImage(std::string fileIn, std::string fileOut, bool svs = false, std::string compression = "LZW", double quality = 70., double spacingX = -1.0, double spacingY = -1.0, unsigned int tileSize = 512) { MultiResolutionImageReader read; MultiResolutionImageWriter* writer; if (svs) { writer = new AperioSVSWriter(); } else { writer = new MultiResolutionImageWriter(); } if (core::fileExists(fileIn)) { MultiResolutionImage* img = read.open(fileIn); if (img) { if (img->valid()) { writer->setTileSize(tileSize); if (compression == string("LZW")) { writer->setCompression(LZW); } else if (compression == string("RAW")) { writer->setCompression(RAW); } else if (compression == string("JPEG")) { writer->setCompression(JPEG); } else if (compression == string("JPEG2000")) { writer->setCompression(JPEG2000); } else { cout << "Invalid compression, setting default LZW as compression" << endl; writer->setCompression(LZW); } if (quality > 100) { cout << "Too high rate, maximum is 100, setting to 100 (for JPEG2000 this is equal to lossless)" << endl; writer->setJPEGQuality(100); } else if (quality <= 0.001) { cout << "Too low rate, minimum is 0.001, setting to 1" << endl; writer->setJPEGQuality(1); } else { writer->setJPEGQuality(quality); } if (spacingX > 0.0 && spacingY > 0.0) { std::vector<double> overrideSpacing; overrideSpacing.push_back(spacingX); overrideSpacing.push_back(spacingY); writer->setOverrideSpacing(overrideSpacing); } CmdLineProgressMonitor* monitor = new CmdLineProgressMonitor(); monitor->setStatus("Processing " + fileIn); writer->setProgressMonitor(monitor); writer->writeImageToFile(img, fileOut); delete monitor; } else { cout << "Input file not valid" << endl; } } else { cout << "Input file not compatible" << endl; } } else { cout << "Input file does not exist" << endl; } }