Code Monkey home page Code Monkey logo

Comments (9)

nslay avatar nslay commented on June 15, 2024 1

Aha! I remembered coming across the C/C++ library libvips that can write slide images. There's also BioFormats but that's Java. Maybe I could write an ITKIOVIPS or something like that! But I'm already strapped for time and often not even working on pathology projects (I'm working mostly with radiology images these days).

from itkioopenslide.

zhusihan-python avatar zhusihan-python commented on June 15, 2024 1

Unfortunately, it doesn't look like libvips can write .svs files either. libvips/pyvips#69

I guess the workaround is to write a pyramidal tiff image. See the issue with code for the workaround.

yes sir, vips can not write svs directly. but
this tiny project can convert almost all images format supported by vips to svs in around 500 line cpp code.

from itkioopenslide.

nslay avatar nslay commented on June 15, 2024 1

I don't see the SCIFIOImageIO listed. You could try to force the use of SCIFIImageIO by creating SCIFIImageIO (SCIFIOImageIO::New()) and feeding it to itk::ImageFileWriter::SetImageIO().

from itkioopenslide.

zhusihan-python avatar zhusihan-python commented on June 15, 2024

the ITKIOOpenSlide does not support write to svs format, this is my test result

Parameters:

inputImage = 'E:/data/CMU-1.ndpi'
outputImage = 'E:/data/CMU-1.svs'
shouldFail = false
compress = false
approximateStreaming = false
stream = 0
level = 0
associatedImage = ''
downsample = 0
Error:
itk::ImageFileWriterException (000000DA126FF9C0)
Location: "unknown"
File: E:\projects\ITK\Modules\IO\ImageBase\include\itkImageFileWriter.hxx
Line: 118
Description:  Could not create IO object for writing file E:/data/CMU-1.svs
  Tried to create one of the following:
    JPEGImageIO
    PNGImageIO
    TIFFImageIO
  You probably failed to set a file suffix, or
    set the suffix to an unsupported type.

test code:

#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <sstream>

#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkOpenSlideImageIO.h"
#include "itkImage.h"
#include "itkRGBAPixel.h"
#include "itkMetaDataObject.h"

#include "itkOpenSlideImageIOFactory.h"
#include "itkImageIOFactory.h"

bool ParseValue(const char *p_cValue, std::string &strCommand, std::string &strValue) {
  strCommand.clear();
  strValue.clear();

  if (p_cValue == NULL)
    return false;

  const char *p = strchr(p_cValue, '=');

  if (p == NULL) {
    strCommand = p_cValue;
    return true;
  }

  // is p the beginning or end of the string?
  if (p == p_cValue)
    return false;

  strCommand.assign(p_cValue, (p-p_cValue));
  strValue = p+1;

  return true;
}
int main(int argc, char **argv)
{
  using PixelType = itk::RGBAPixel<unsigned char>;
  using ImageType = itk::Image<PixelType, 2>;
  using ReaderIOType = itk::OpenSlideImageIO;
  using ReaderType = itk::ImageFileReader<ImageType>;
  using WriterType = itk::ImageFileWriter<ImageType>;

  if( argc < 3 ) {
    std::cerr << "Usage: " << argv[0] << " inputImage outputImage [command1 command2 ...]\n";
    return EXIT_FAILURE;
  }

  //const char * const p_cArg0 = argv[0];
  const char * const p_cInputImage = argv[1];
  const char * const p_cOutputImage = argv[2];

  argc -= 3;
  argv += 3;

  bool bShouldFail = false;
  bool bUseCompression = false;
  bool bApproximateStreaming = false;
  unsigned int uiNumStreams = 0; // 0 means no streaming
  int iLevel = 0;
  std::string strAssociatedImageName;
  double dDownsampleFactor = 0.0; // 0 means no down sample

  for (int i = 0; i < argc; ++i) {
    std::string strCommand;
    std::string strValue;

    if (!ParseValue(argv[i], strCommand, strValue)) {
      std::cerr << "Error: Could not parse value '" << argv[i] << "'." << std::endl;
      return EXIT_FAILURE;
    }

    if (strCommand == "shouldFail") {
      bShouldFail = true;
    }
    else if (strCommand == "compress") {
      bUseCompression = true;
    }
    else if (strCommand == "approximateStreaming") {
      bApproximateStreaming = true;
    }
    else if (strCommand == "level") {
      if (strValue.empty()) {
        std::cerr << "Error: Expected level parameter." << std::endl;
        return EXIT_FAILURE;
      }

      char *p = NULL;
      iLevel = strtol(strValue.c_str(), &p, 10);
      if (*p != '\0') {
        std::cerr << "Error: Could not parse level '" << strValue << "'." << std::endl;
        return EXIT_FAILURE;
      }
    }
    else if (strCommand == "associatedImage") {
      if (strValue.empty()) {
        std::cerr << "Error: Expected associated image name." << std::endl;
        return EXIT_FAILURE;
      }

      strAssociatedImageName = strValue;
    }
    else if (strCommand == "downsample") {
      if (strValue.empty()) {
        std::cerr << "Error: Expected downsample factor." << std::endl;
        return EXIT_FAILURE;
      }

      char *p = NULL;
      dDownsampleFactor = strtod(strValue.c_str(), &p);
      if (*p != '\0') {
        std::cerr << "Error: Could not parse downsample factor '" << strValue << "'." << std::endl;
        return EXIT_FAILURE;
      }
    }
    else if (strCommand == "stream") {
      if (strValue.empty()) {
        std::cerr << "Error: Expected number of streams." << std::endl;
        return EXIT_FAILURE;
      }

      char *p = NULL;
      uiNumStreams = strtoul(strValue.c_str(), &p, 10);
      if (*p != '\0') {
        std::cerr << "Error: Could not parse number of streams '" << strValue << "'." << std::endl;
        return EXIT_FAILURE;
      }
    }
    else {
      std::cout << "Error: Unknown command '" << argv[i] << "'." << std::endl;
      return EXIT_FAILURE;
    }
  }

  const int iFailCode = (bShouldFail ? EXIT_SUCCESS : EXIT_FAILURE);
  const int iSuccessCode = (iFailCode == EXIT_FAILURE ? EXIT_SUCCESS : EXIT_FAILURE);

  std::cout << "Parameters:\n" << std::endl;
  std::cout << "inputImage = '" << p_cInputImage << '\'' << std::endl;
  std::cout << "outputImage = '" << p_cOutputImage << '\'' << std::endl;
  std::cout << "shouldFail = " << std::boolalpha << bShouldFail << std::endl;
  std::cout << "compress = " << std::boolalpha << bUseCompression << std::endl;
  std::cout << "approximateStreaming = " << std::boolalpha << bApproximateStreaming << std::endl;
  std::cout << "stream = " << uiNumStreams << std::endl;
  std::cout << "level = " << iLevel << std::endl;
  std::cout << "associatedImage = '" << strAssociatedImageName << '\'' << std::endl;
  std::cout << "downsample = " << dDownsampleFactor << std::endl;

  ReaderIOType::Pointer p_clImageIO = ReaderIOType::New();
  ReaderType::Pointer p_clReader = ReaderType::New();
  WriterType::Pointer p_clWriter = WriterType::New();

  p_clImageIO->SetFileName(p_cInputImage);

  p_clReader->SetImageIO(p_clImageIO);
  p_clReader->SetFileName(p_cInputImage);

  p_clWriter->SetInput(p_clReader->GetOutput());
  p_clWriter->SetFileName(p_cOutputImage);

  try {
    p_clImageIO->ReadImageInformation();
  }
  catch (itk::ExceptionObject &e) {
    std::cerr << "Error: " << e << std::endl;
    return iFailCode;
  }

  if (strAssociatedImageName.size() > 0)
    p_clImageIO->SetAssociatedImageName(strAssociatedImageName);
  else
    p_clImageIO->SetLevel(iLevel);

  if (dDownsampleFactor > 0.0 && !p_clImageIO->SetLevelForDownsampleFactor(dDownsampleFactor))
    return iFailCode;

  if (uiNumStreams > 0) {
    if (!p_clImageIO->CanStreamRead())
      return iFailCode;

    p_clImageIO->UseStreamedReadingOn();
    p_clImageIO->SetApproximateStreaming(bApproximateStreaming);

    itk::ImageIOBase::Pointer p_clWriterIO = itk::ImageIOFactory::CreateImageIO(p_cOutputImage, itk::IOFileModeEnum::WriteMode);
    if (!p_clWriterIO) {
      std::cerr << "Error: Could not create ImageIO for output image '" << p_cOutputImage << "'." << std::endl;
      return iFailCode;
    }

    if (bUseCompression)
      std::cout << "Warning: Compression may disable streaming." << std::endl;

    p_clWriterIO->UseStreamedWritingOn();

    p_clWriter->SetImageIO(p_clWriterIO);
    p_clWriter->SetNumberOfStreamDivisions(uiNumStreams);
  }

  // XXX: Just so you know, this might disable streaming
  p_clWriter->SetUseCompression(bUseCompression);

  try {
    p_clWriter->Update();
  }
  catch (itk::ExceptionObject &e) {
    std::cerr << "Error: " << e << std::endl;
    return iFailCode;
  }

  // Use this to compress output images when updating tests
  //CompressImageFile(p_cOutputImage);

  return iSuccessCode;
}

from itkioopenslide.

nslay avatar nslay commented on June 15, 2024

Since openslide itself cannot write slide format images, neither can ITKIOOpenSlide. You're unfortunately limited to only reading slide images.

from itkioopenslide.

zhusihan-python avatar zhusihan-python commented on June 15, 2024

Aha! I remembered coming across the C/C++ library libvips that can write slide images. There's also BioFormats but that's Java. Maybe I could write an ITKIOVIPS or something like that! But I'm already strapped for time and often not even working on pathology projects (I'm working mostly with radiology images these days).

that will be great if there are iovips or iosvs! I have found a repo use libvips to generate svs, but I don't know how to combine it with itk or itk montage.

from itkioopenslide.

nslay avatar nslay commented on June 15, 2024

Unfortunately, it doesn't look like libvips can write .svs files either.
libvips/pyvips#69

I guess the workaround is to write a pyramidal tiff image. See the issue with code for the workaround.

from itkioopenslide.

zhusihan-python avatar zhusihan-python commented on June 15, 2024

Aha! I remembered coming across the C/C++ library libvips that can write slide images. There's also BioFormats but that's Java. Maybe I could write an ITKIOVIPS or something like that! But I'm already strapped for time and often not even working on pathology projects (I'm working mostly with radiology images these days).

i build SCIFIO ImageIO successfully, it did not support write svs format surprisingly
image

from itkioopenslide.

zhusihan-python avatar zhusihan-python commented on June 15, 2024

writeSCIFIO is not set on i guess in the RunTest so the SetImageIO did not trigger
image
then i enable write-scifio by running
SCIFIOTestDriver.exe itkSCIFIOImageIOTest e:/data/CMU-1.ndpi e:/data/CMU-1_trans.svs --write-scifio
get some errors in java code, still can not recognize svs format

reader->GetUseStreaming(): 1
done checking streaming usage

itk::ExceptionObject (0000002173F6EE08)
Location: "unknown"
File: F:\build_io_scifio\src\itkSCIFIOImageIO.cxx
Line: 180
Description: ITK ERROR: SCIFIOImageIO(000001D4EAB1D040): SCIFIOImageIO exited abnormally. Exception in thread "main" loci.formats.UnknownFormatException: Unknown file format: e:/data/CMU-1_trans.svs
        at loci.formats.ImageWriter.getWriter(ImageWriter.java:158)
        at loci.formats.ImageWriter.setId(ImageWriter.java:462)
        at io.scif.itk.SCIFIOITKBridge.write(SCIFIOITKBridge.java:555)
        at io.scif.itk.SCIFIOITKBridge.executeCommand(SCIFIOITKBridge.java:203)
        at io.scif.itk.SCIFIOITKBridge.executeCommand(SCIFIOITKBridge.java:115)
        at io.scif.itk.SCIFIOITKBridge.waitForInput(SCIFIOITKBridge.java:90)
        at io.scif.itk.SCIFIOITKBridge.executeCommand(SCIFIOITKBridge.java:170)
        at io.scif.itk.SCIFIOITKBridge.main(SCIFIOITKBridge.java:774)

from itkioopenslide.

Related Issues (6)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.