예제 #1
0
 private double getMin(ImageServiceBean bean) {
   if (bean.getMinimumCutBound() == null || bean.getMinimumCutBound().getBound() == null) {
     return bean.getMin().doubleValue();
   }
   return Math.max(
       bean.getMin().doubleValue(), bean.getMinimumCutBound().getBound().doubleValue());
 }
예제 #2
0
 /**
  * Get the logged image value and cache the result.
  *
  * @param bean
  * @return a dataset that can be absolute, if complex, and also be logged according to bean
  *     Package private for testing
  */
 /* package */ Dataset getImageLoggedData(ImageServiceBean bean) {
   Dataset ret = DatasetUtils.convertToDataset(bean.getImageValue());
   if (ret == null) {
     ret = getImageLoggedDataCalc(bean);
     bean.setImageValue(ret);
   }
   return ret;
 }
예제 #3
0
  private void createMaxMin(ImageServiceBean bean) {

    double[] stats = null;
    if (bean.getMin() == null) {
      if (stats == null) stats = getFastStatistics(bean); // do not get unless have to
      bean.setMin(stats[0]);
    }

    if (bean.getMax() == null) {
      if (stats == null) stats = getFastStatistics(bean); // do not get unless have to
      bean.setMax(stats[1]);
    }
  }
예제 #4
0
  /**
   * Get the logged image value.
   *
   * @param bean
   * @return a dataset that can be absolute, if complex, and also be logged according to bean
   *     Package private for testing
   */
  /* package */ Dataset getImageLoggedDataCalc(ImageServiceBean bean) {
    Dataset ret = DatasetUtils.convertToDataset(bean.getImage());

    if (ret.isComplex()) {
      ret = Maths.abs(ret);
    }
    if (bean.isLogColorScale()) {
      double offset = bean.getLogOffset();
      if (!Double.isNaN(offset) && !Double.isInfinite(offset)) {
        ret = Maths.subtract(ret, offset);
      }
      ret = Maths.log10(ret);
    }
    return ret;
  }
예제 #5
0
  /**
   * getImageData(...) provides an image in a given palette data and origin. Faster than getting a
   * resolved image
   *
   * <p>This method should be thread safe.
   */
  public ImageData getImageData(ImageServiceBean bean) {
    ImageOrigin origin = bean.getOrigin();
    if (origin == null) origin = ImageOrigin.TOP_LEFT;

    // orientate the image
    Dataset oImage =
        DatasetUtils.rotate90(DatasetUtils.convertToDataset(bean.getImage()), origin.ordinal());
    Dataset image = oImage;

    if (image instanceof RGBDataset) {
      return SWTImageUtils.createImageData(
          (RGBDataset) image, 0, 255, null, null, null, false, false, false);
    }

    createMaxMin(bean);
    double max = getMax(bean);
    double min = getMin(bean);

    double maxCut = getMaxCut(bean);
    double minCut = getMinCut(bean);

    // now deal with the log if needed
    if (bean.isLogColorScale()) {
      image = DatasetUtils.rotate90(getImageLoggedData(bean), origin.ordinal());
      max = Math.log10(max);
      // note createMaxMin() -> getFastStatistics() -> getImageLogged() which ensures min >= 0
      min = Math.log10(min);
      maxCut = Math.log10(maxCut);
      // no guarantees for minCut though
      minCut = minCut <= 0 ? Double.NEGATIVE_INFINITY : Math.log10(minCut);
    }

    if (oImage.isComplex()) { // handle complex datasets by creating RGB dataset
      Dataset hue = Maths.angle(oImage, true);
      Dataset value = DatasetUtils.rotate90(getImageLoggedData(bean), origin.ordinal());
      double maxmax = Math.max(Math.abs(max), Math.abs(min));
      if (max - min > Math.ulp(maxmax)) {
        value.isubtract(min);
        value.imultiply(1. / (max - min));
      } else {
        value.imultiply(1. / maxmax);
      }
      image = RGBDataset.createFromHSV(hue, null, value);
      return SWTImageUtils.createImageData(image, 0, 255, null, null, null, false, false, false);
    }

    if (bean.getFunctionObject() != null && bean.getFunctionObject() instanceof FunctionContainer) {
      final FunctionContainer fc = (FunctionContainer) bean.getFunctionObject();
      // TODO This does not support masking or cut bounds for zingers and dead pixels.
      return SWTImageUtils.createImageData(
          image,
          min,
          max,
          fc.getRedFunc(),
          fc.getGreenFunc(),
          fc.getBlueFunc(),
          fc.isInverseRed(),
          fc.isInverseGreen(),
          fc.isInverseBlue());
    }

    return SWTImageUtils.createImageData(min, max, minCut, maxCut, image, bean);
  }
예제 #6
0
  @Override
  public ImageServiceBean createBeanFromPreferences() {

    ImageServiceBean imageServiceBean = new ImageServiceBean();

    if (Platform.getPreferencesService() != null) { // Normally
      IPreferenceStore store =
          new ScopedPreferenceStore(InstanceScope.INSTANCE, "org.dawnsci.plotting");
      imageServiceBean.setOrigin(
          ImageOrigin.forLabel(store.getString(BasePlottingConstants.ORIGIN_PREF)));
      imageServiceBean.setHistogramType(
          HistoType.forLabel(store.getString(BasePlottingConstants.HISTO_PREF)));
      imageServiceBean.setMinimumCutBound(
          HistogramBound.fromString(store.getString(BasePlottingConstants.MIN_CUT)));
      imageServiceBean.setMaximumCutBound(
          HistogramBound.fromString(store.getString(BasePlottingConstants.MAX_CUT)));
      imageServiceBean.setNanBound(
          HistogramBound.fromString(store.getString(BasePlottingConstants.NAN_CUT)));
      imageServiceBean.setLo(store.getDouble(BasePlottingConstants.HISTO_LO));
      imageServiceBean.setHi(store.getDouble(BasePlottingConstants.HISTO_HI));

      try {
        IPaletteService pservice = ServiceLoader.getPaletteService();
        if (pservice != null) {
          final String scheme = store.getString(BasePlottingConstants.COLOUR_SCHEME);

          if (store.getBoolean(BasePlottingConstants.USE_PALETTE_FUNCTIONS)) {
            FunctionContainer container = pservice.getFunctionContainer(scheme);
            if (container != null) {
              imageServiceBean.setFunctionObject(container);
            } else {
              imageServiceBean.setPalette(pservice.getDirectPaletteData(scheme));
            }
          } else {
            // if 8-bit, set direct palette, otherwise set palette functions.
            PaletteData pd;
            try {
              pd = pservice.getDirectPaletteData(scheme);
            } catch (final IllegalArgumentException e) { // scheme does not exist
              final String defaultScheme = pservice.getColorSchemes().iterator().next();
              pd = pservice.getDirectPaletteData(defaultScheme);
              store.setValue(BasePlottingConstants.COLOUR_SCHEME, defaultScheme);
            }
            imageServiceBean.setPalette(pd);
          }
        }
      } catch (Exception e) {
        // Ignored
      }

    } else { // Hard code something

      imageServiceBean.setOrigin(ImageOrigin.TOP_LEFT);
      imageServiceBean.setHistogramType(HistoType.OUTLIER_VALUES);
      imageServiceBean.setMinimumCutBound(HistogramBound.DEFAULT_MINIMUM);
      imageServiceBean.setMaximumCutBound(HistogramBound.DEFAULT_MAXIMUM);
      imageServiceBean.setNanBound(HistogramBound.DEFAULT_NAN);
      imageServiceBean.setLo(00.01);
      imageServiceBean.setHi(99.99);
      imageServiceBean.setPalette(makeJetPalette());
    }

    return imageServiceBean;
  }
예제 #7
0
  /**
   * Fast statistics as a rough guide - this is faster than Dataset.getMin() and getMax() which may
   * cache but slows the opening of images too much. The return array[2] was added in "Updated for
   * Diffraction Tool." commit, but no trace of such usage. However it should not be removed,
   * because it is useful as return array[3].
   *
   * @param bean
   * @return [0] = min [1] = max(=mean*constant) [2] = mean [3] max
   */
  public double[] getFastStatistics(ImageServiceBean bean) {

    Dataset image = getImageLoggedData(bean);

    if (bean.getHistogramType() == HistoType.OUTLIER_VALUES && !bean.isLogColorScale()) {

      double[] ret = null;
      try {
        double[] stats = Stats.outlierValues(image, bean.getLo(), bean.getHi(), -1);
        ret = new double[] {stats[0], stats[1], -1};
      } catch (IllegalArgumentException iae) {
        bean.setLo(10);
        bean.setHi(90);
        double[] stats = Stats.outlierValues(image, bean.getLo(), bean.getHi(), -1);
        ret = new double[] {stats[0], stats[1], -1};
      }

      if (bean.isLogColorScale() && ret != null) {
        ret = new double[] {Math.pow(10, ret[0]), Math.pow(10, ret[1]), -1};
      }

      return ret;
    }

    double min = Double.MAX_VALUE;
    double max = -Double.MAX_VALUE;
    double sum = 0.0;
    int size = 0;

    BooleanDataset mask =
        bean.getMask() != null
            ? (BooleanDataset) DatasetUtils.cast(bean.getMask(), Dataset.BOOL)
            : null;

    // Big loop warning:
    final IndexIterator it = image.getIterator();
    final IndexIterator mit = mask == null ? null : mask.getIterator();
    while (it.hasNext()) {

      final double val = image.getElementDoubleAbs(it.index);
      if (mit != null && mit.hasNext()) {
        if (!mask.getElementBooleanAbs(mit.index)) {
          continue; // Masked!
        }
      }

      if (Double.isNaN(val)) continue;
      if (!bean.isInBounds(val)) continue;

      sum += val;
      if (val < min) min = val;
      if (val > max) max = val;
      size++;
    }

    double retMax = Double.NaN;
    double retExtra = Double.NaN;

    if (bean.getHistogramType() == HistoType.MEDIAN) {

      double median = Double.NaN;
      try {
        median = ((Number) Stats.median(image)).doubleValue(); // SLOW
      } catch (Exception ne) {
        median = ((Number) Stats.median(image.cast(Dataset.INT16))).doubleValue(); // SLOWER
      }
      retMax = 2 * median;
      retExtra = median;

    } else { // Use mean based histo
      double mean = sum / size;
      retMax = (Math.E) * mean; // Not statistical, E seems to be better than 3...
      retExtra = mean;
    }

    if (retMax > max) retMax = max;

    if (bean.isLogColorScale()) {
      return new double[] {Math.pow(10, min), Math.pow(10, retMax), Math.pow(10, retExtra)};
    }

    return new double[] {min, retMax, retExtra, max};
  }
예제 #8
0
 private double getMinCut(ImageServiceBean bean) {
   if (bean.getMinimumCutBound() == null || bean.getMinimumCutBound().getBound() == null) {
     return Double.NEGATIVE_INFINITY;
   }
   return bean.getMinimumCutBound().getBound().doubleValue();
 }