Skip to content

Commit

Permalink
Various bugfixes for the combined image view, especially when synchro…
Browse files Browse the repository at this point in the history
…nizing images with different dimensions.
  • Loading branch information
AndreasBurger committed Jul 6, 2016
1 parent 858a546 commit fc481bf
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
import org.knime.knip.cellviewer.interfaces.CellViewFactory;
import org.knime.knip.core.awt.ColorLabelingRenderer;
import org.knime.knip.core.awt.Real2GreyRenderer;
import org.knime.knip.core.data.img.DefaultImgMetadata;
import org.knime.knip.core.ui.imgviewer.CombinedImgViewer;
import org.knime.knip.core.ui.imgviewer.events.ImgWithMetadataChgEvent;
import org.knime.knip.core.ui.imgviewer.events.LabelingWithMetadataChgEvent;
Expand All @@ -71,7 +72,11 @@
import org.knime.knip.core.ui.imgviewer.panels.providers.LabelingRU;
import org.knime.knip.core.util.waitingindicator.WaitingIndicatorUtils;

import net.imagej.ImgPlusMetadata;
import net.imglib2.img.Img;
import net.imglib2.img.ImgView;
import net.imglib2.type.numeric.RealType;
import net.imglib2.view.Views;

/**
* TODO Auto-generated
Expand Down Expand Up @@ -111,6 +116,7 @@ public void onReset() {
// Nothing to do here
}

@SuppressWarnings("unchecked")
@Override
public void updateComponent(final List<DataValue> valueToView) {
WaitingIndicatorUtils.setWaiting(m_view, true);
Expand All @@ -120,12 +126,28 @@ public void updateComponent(final List<DataValue> valueToView) {
for (DataValue v : valueToView) {
if (v instanceof ImgPlusValue) {
final ImgPlusValue imgPlusValue = (ImgPlusValue)v;
ImageRU ru = new ImageRU(((RealType)imgPlusValue.getImgPlus().firstElement()).getMinValue());
m_view.addRU(ru);
m_view.publishToPrev(new RendererSelectionChgEvent(new Real2GreyRenderer(
((RealType)imgPlusValue.getImgPlus().firstElement()).getMinValue())));
m_view.publishToPrev(new ImgWithMetadataChgEvent<>(imgPlusValue.getImgPlus(),
imgPlusValue.getMetadata()));

if (imgPlusValue.getMetadata().numDimensions() <= 1) {
Img img2d = imgPlusValue.getImgPlus().getImg();
ImgPlusMetadata meta = imgPlusValue.getMetadata();

img2d = ImgView.wrap(Views.addDimension(img2d, 0, 0), img2d.factory());
meta = new DefaultImgMetadata(2);
ImageRU ru = new ImageRU(((RealType)img2d.firstElement()).getMinValue());
m_view.addRU(ru);
m_view.publishToPrev(new RendererSelectionChgEvent(
new Real2GreyRenderer(((RealType)img2d.firstElement()).getMinValue())));
m_view.publishToPrev(new ImgWithMetadataChgEvent<>(img2d, meta));

} else {
ImageRU ru =
new ImageRU(((RealType)imgPlusValue.getImgPlus().firstElement()).getMinValue());
m_view.addRU(ru);
m_view.publishToPrev(new RendererSelectionChgEvent(new Real2GreyRenderer(
((RealType)imgPlusValue.getImgPlus().firstElement()).getMinValue())));
m_view.publishToPrev(new ImgWithMetadataChgEvent<>(imgPlusValue.getImgPlus(),
imgPlusValue.getMetadata()));
}

} else if (v instanceof LabelingValue) {
final LabelingValue labValue = (LabelingValue)v;
Expand Down Expand Up @@ -189,7 +211,7 @@ public String getCellViewDescription() {
}

@Override
public int getPriority(){
public int getPriority() {
return Integer.MAX_VALUE;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ public void addRU(final RenderUnit ru) {
broadcast(new CombinedRUSynchEventClone(false));
m_ru.setStackedRendering(true);
m_controlPanel.resetCheckboxes();
m_tabbedMenu.setSelectedIndex(0);
}

public void clear() {
Expand Down Expand Up @@ -250,6 +251,8 @@ public void onCombinedRUSynchChange(final CombinedRUSynchEvent e) {
broadcast(new CombinedRUSynchEventClone(e));
if (!m_sync) {
broadcast(new RebroadcastSelectionEvent());
} else {
m_eventServices.get(m_tabbedMenu.getSelectedIndex()).publish(new RebroadcastSelectionEvent());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,12 @@ public <T extends RealType<T>> double[] getNormalizationParameters(final RandomA
final ValuePair<T, T> oldMinMax =
Operations.compute(new MinMaxWithSaturation<T>(m_saturation, element), Views
.iterable(Views.offsetInterval(Views.zeroMin(src), sel.getInterval(Views.zeroMin(src)))));
return new double[]{

double[] retVal = new double[]{
Normalize.normalizationFactor(oldMinMax.a.getRealDouble(), oldMinMax.b.getRealDouble(),
element.getMinValue(), element.getMaxValue()),
oldMinMax.a.getRealDouble()};
return retVal;
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@
import org.knime.knip.core.ui.event.EventService;
import org.knime.knip.core.ui.imgviewer.events.TransparencyPanelValueChgEvent;
import org.knime.knip.core.ui.imgviewer.panels.CombinedRUSynchEvent;
import org.knime.knip.core.util.MiscViews;

import net.imglib2.FinalInterval;
import net.imglib2.Interval;

/**
Expand Down Expand Up @@ -150,10 +152,12 @@ public Image createImage() {
int first = i;
int w = 0, h = 0;
Interval target = null;

if (m_sync) {
target = m_renderUnits.get(i).getInterval();
target = calculateHull();
m_renderUnits.get(i).limitTo(target);
}

Image img = m_renderUnits.get(i).createImage();
w += img.getWidth(null);
h = Math.max(h, img.getHeight(null));
Expand Down Expand Up @@ -190,10 +194,12 @@ public Image createImage() {
//at least one active image

Interval target = null;

if (m_sync) {
target = m_renderUnits.get(i).getInterval();
target = calculateHull();
m_renderUnits.get(i).limitTo(target);
}

Image img = m_renderUnits.get(i).createImage();
joinedImg = m_graphicsConfig.createCompatibleImage(img.getWidth(null), img.getHeight(null),
java.awt.Transparency.TRANSLUCENT);
Expand All @@ -206,9 +212,11 @@ public Image createImage() {
//blend in the other active images
while (i < m_renderUnits.size()) {
if (m_renderUnits.get(i).isActive()) {

if (m_sync) {
m_renderUnits.get(i).limitTo(target);
}

g.drawImage(Transparency.makeColorTransparent(m_renderUnits.get(i).createImage(), Color.WHITE,
m_transparency),
0, 0, null);
Expand All @@ -232,6 +240,21 @@ public Image createImage() {

}

private Interval calculateHull() {
Interval result = new FinalInterval();
for (RenderUnit ru : m_renderUnits) {
if (ru.isActive()) {
Interval target = ru.getInterval();
if (result.numDimensions() > target.numDimensions()) {
result = MiscViews.synchronizeDimensionality(target, result);
} else {
result = MiscViews.synchronizeDimensionality(result, target);
}
}
}
return result;
}

/**
* @return combined HashCode of all {@link RenderUnit}s. By contract that allows to identify images generated by
* {@link #createImage()} including all parameters that have influence on the creation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,16 @@
import org.knime.knip.core.ui.imgviewer.events.ImgAndLabelingChgEvent;
import org.knime.knip.core.ui.imgviewer.events.ImgWithMetadataChgEvent;
import org.knime.knip.core.ui.imgviewer.events.NormalizationParametersChgEvent;
import org.knime.knip.core.ui.imgviewer.events.PlaneSelectionEvent;
import org.knime.knip.core.ui.imgviewer.events.ViewClosedEvent;
import org.knime.knip.core.ui.imgviewer.panels.transfunc.LookupTableChgEvent;
import org.knime.knip.core.util.MiscViews;

import net.imglib2.Interval;
import net.imglib2.RandomAccessibleInterval;
import net.imglib2.display.ColorTable;
import net.imglib2.display.screenimage.awt.AWTScreenImage;
import net.imglib2.outofbounds.OutOfBoundsConstantValueFactory;
import net.imglib2.type.numeric.ARGBType;
import net.imglib2.type.numeric.RealType;
import net.imglib2.view.Views;
Expand Down Expand Up @@ -125,6 +129,9 @@ public int hashCode() {

// event members

/** Caches the current restriction interval */
private Interval m_interval;

private LookupTable<T, ARGBType> m_lookupTable = new SimpleTable();

private NormalizationParametersChgEvent m_normalizationParameters = new NormalizationParametersChgEvent(0, false);
Expand All @@ -133,11 +140,13 @@ public int hashCode() {

private RandomAccessibleInterval<T> m_src;

private RandomAccessibleInterval<T> m_unmodSrc;

/** default constructor that creates a renderer selection dependent image {@link RenderUnit}. */
public ImageRU(final double min) {
this(false);

this.m_greyRenderer = new Real2GreyRenderer<T>(0.0);

}

/**
Expand All @@ -148,6 +157,7 @@ public ImageRU(final double min) {
*/
public ImageRU(final boolean enforceGreyScale) {
m_enforceGreyScale = enforceGreyScale;
this.m_greyRenderer = new Real2GreyRenderer<T>(0.0);
}

@SuppressWarnings("unchecked")
Expand All @@ -156,13 +166,14 @@ public Image createImage() {
if (m_lastImage != null && m_hashOfLastRendering == generateHashCode()) {
return m_lastImage;
}

PlaneSelectionEvent pSel = m_planeSelection;
if(m_interval != null && m_planeSelection.numDimensions() != m_interval.numDimensions()) {
pSel = MiscViews.adjustPlaneSelection(m_planeSelection, m_interval);
}
//+ allows normalization - breaks type safety
@SuppressWarnings("rawtypes")
RandomAccessibleInterval convertedSrc = AWTImageProvider.convertIfDouble(m_src);
final double[] normParams =
m_normalizationParameters.getNormalizationParameters(convertedSrc, m_planeSelection);

final double[] normParams = m_normalizationParameters.getNormalizationParameters(convertedSrc, pSel);
//set parameters of the renderer
if (m_renderer instanceof RendererWithNormalization) {
((RendererWithNormalization)m_renderer).setNormalizationParameters(normParams[0], normParams[1]);
Expand All @@ -178,12 +189,12 @@ public Image createImage() {

final AWTScreenImage ret;
if (!m_enforceGreyScale) {
ret = m_renderer.render(Views.zeroMin(convertedSrc), m_planeSelection.getPlaneDimIndex1(),
m_planeSelection.getPlaneDimIndex2(), m_planeSelection.getPlanePos());
ret = m_renderer.render(Views.zeroMin(convertedSrc), pSel.getPlaneDimIndex1(),
pSel.getPlaneDimIndex2(), pSel.getPlanePos());
} else {
m_greyRenderer.setNormalizationParameters(normParams[0], normParams[1]);
ret = m_greyRenderer.render(Views.zeroMin(convertedSrc), m_planeSelection.getPlaneDimIndex1(),
m_planeSelection.getPlaneDimIndex2(), m_planeSelection.getPlanePos());
ret = m_greyRenderer.render(Views.zeroMin(convertedSrc), pSel.getPlaneDimIndex1(),
pSel.getPlaneDimIndex2(), pSel.getPlanePos());
}

m_lastImage = ret.image();
Expand Down Expand Up @@ -213,6 +224,31 @@ public boolean isActive() {
return (m_src != null);
}

@Override
public void limitTo(final Interval interval) {
if (!interval.equals(m_interval)) {
T val = m_src.randomAccess().get().createVariable();
val.setReal(val.getMinValue());
OutOfBoundsConstantValueFactory<T, RandomAccessibleInterval<T>> fac =
new OutOfBoundsConstantValueFactory<>(val);
m_interval = interval;
m_src = Views.interval(MiscViews.synchronizeDimensionality(m_unmodSrc, interval, fac), interval);
m_hashOfLastRendering = -1;
}
}

@Override
public void resetLimit() {
m_interval = null;
m_src = m_unmodSrc;
m_hashOfLastRendering = -1;
}

@Override
public Interval getInterval() {
return m_src;
}

//event handling

/**
Expand Down Expand Up @@ -244,6 +280,7 @@ public void onLookupTableChgEvent(final LookupTableChgEvent<T, ARGBType> event)
@EventListener
public void onImageUpdated(final ImgWithMetadataChgEvent<T> e) {
m_src = e.getRandomAccessibleInterval();
m_unmodSrc = e.getRandomAccessibleInterval();

final int size = e.getImgMetaData().getColorTableCount();
m_colorTables = new ColorTable[size];
Expand All @@ -261,6 +298,7 @@ public void onImageUpdated(final ImgWithMetadataChgEvent<T> e) {
@EventListener
public void onImageUpdated(final ImgAndLabelingChgEvent<T, ?> e) {
m_src = e.getRandomAccessibleInterval();
m_unmodSrc = e.getRandomAccessibleInterval();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,15 @@
import org.knime.knip.core.ui.imgviewer.events.LabelPanelIsHiliteModeEvent;
import org.knime.knip.core.ui.imgviewer.events.LabelPanelVisibleLabelsChgEvent;
import org.knime.knip.core.ui.imgviewer.events.LabelingWithMetadataChgEvent;
import org.knime.knip.core.ui.imgviewer.events.PlaneSelectionEvent;
import org.knime.knip.core.ui.imgviewer.events.RulebasedLabelFilter.Operator;
import org.knime.knip.core.ui.imgviewer.events.ViewClosedEvent;
import org.knime.knip.core.util.MiscViews;

import net.imglib2.Interval;
import net.imglib2.RandomAccessibleInterval;
import net.imglib2.display.screenimage.awt.AWTScreenImage;
import net.imglib2.outofbounds.OutOfBoundsConstantValueFactory;
import net.imglib2.roi.labeling.LabelingType;
import net.imglib2.view.Views;

Expand Down Expand Up @@ -134,6 +137,11 @@ public Image createImage() {
return m_lastImage;
}

PlaneSelectionEvent pSel = m_planeSelection;
if(m_interval != null && m_planeSelection.numDimensions() != m_interval.numDimensions()) {
pSel = MiscViews.adjustPlaneSelection(m_planeSelection, m_interval);
}

if (m_renderer instanceof RendererWithLabels) {
@SuppressWarnings("unchecked")
final RendererWithLabels<L> r = (RendererWithLabels<L>)m_renderer;
Expand All @@ -155,8 +163,8 @@ public Image createImage() {
}

final AWTScreenImage ret =
m_renderer.render(m_src, m_planeSelection.getPlaneDimIndex1(), m_planeSelection.getPlaneDimIndex2(),
m_planeSelection.getPlanePos());
m_renderer.render(m_src, pSel.getPlaneDimIndex1(), pSel.getPlaneDimIndex2(),
pSel.getPlanePos());

m_hashOfLastRendering = generateHashCode();
m_lastImage = ret.image();
Expand All @@ -169,8 +177,11 @@ public void limitTo(final Interval interval) {
if (!interval.equals(m_interval)) {
LabelingType<L> val = m_src.randomAccess().get().createVariable();
val.clear();
OutOfBoundsConstantValueFactory<LabelingType<L>, RandomAccessibleInterval<LabelingType<L>>> fac =
new OutOfBoundsConstantValueFactory<>(val);
m_interval = interval;
m_src = Views.interval(Views.extendValue(m_unmodSrc, val), interval);
m_src = Views.interval(MiscViews.synchronizeDimensionality(m_unmodSrc, interval, fac), interval);
m_hashOfLastRendering = -1;
}
}

Expand Down

0 comments on commit fc481bf

Please sign in to comment.