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);
    }
  }
}
Пример #2
0
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;
}
Пример #3
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;
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
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;
  }
}