Ridge Detection causes NPE

imagej
imagej-ops
ridge-detection

#1

Hi @gselzer,

First off, thank you for contributing this op. I have been playing around with using ridge detection as a substitute for iterative thinning and was hoping to use the op. Running it from a Python script is giving me issues though. I am trying to call it as follows:

#@ Img img
#@ Double(label="Maximum threshold:", value=5) rd_max
#@ Double(label="Minimum threshold:", value=75) rd_min
#@ Double(label="Line width:", value=1) rd_width
#@ Integer(label="Max length:", value=3) rd_length

#@ OpService ops

# Detect the ridges as a polyline set
output_lines = ops.run("segment.detectRidges", img, rd_width, rd_min, rd_max, rd_length)

This throws the following traceback which is attached as a text file. As for information on my particular installation, I am running Ubuntu 18.04 and installed a fresh copy of Fiji before running this (ImageJ 2.0.0-rc-68/1.52h). Any ideas as to what I am doing wrong or where this issue is stemming from?

Cheers,
Andy

:microscope: :desktop_computer: :coffee:


Ridge Detection Feedback
#2

Hi @AndyMan,

It appears you did not attach the traceback file? If you could try to send it again I would love to take a look at it!

Best,

Gabe


#3

My apologies @gselzer, seems .txt is not supported for upload. The traceback is:

Started New_.py at Tue Oct 30 15:52:04 EDT 2018
Traceback (most recent call last):
  File "New_.py", line 10, in <module>
	at net.imagej.legacy.convert.ImagePlusToImageDisplayConverter.canConvert(ImagePlusToImageDisplayConverter.java:75)
	at net.imagej.legacy.convert.ImagePlusToImageDisplayConverter.canConvert(ImagePlusToImageDisplayConverter.java:69)
	at net.imagej.legacy.convert.ImagePlusToImageDisplayConverter.canConvert(ImagePlusToImageDisplayConverter.java:81)
	at org.scijava.convert.AbstractConverter.canConvert(AbstractConverter.java:89)
	at org.scijava.convert.AbstractConverter.supports(AbstractConverter.java:144)
	at org.scijava.convert.AbstractConverter.supports(AbstractConverter.java:69)
	at org.scijava.plugin.HandlerService.getHandler(HandlerService.java:60)
	at org.scijava.plugin.HandlerService.supports(HandlerService.java:79)
	at org.scijava.convert.AbstractConvertService.supports(AbstractConvertService.java:97)
	at net.imagej.ops.DefaultOpMatchingService.canConvert(DefaultOpMatchingService.java:602)
	at net.imagej.ops.DefaultOpMatchingService.canAssign(DefaultOpMatchingService.java:587)
	at net.imagej.ops.DefaultOpMatchingService.typesMatch(DefaultOpMatchingService.java:535)
	at net.imagej.ops.DefaultOpMatchingService.typesMatch(DefaultOpMatchingService.java:154)
	at net.imagej.ops.DefaultOpMatchingService.lambda$filterMatches$1(DefaultOpMatchingService.java:138)
	at net.imagej.ops.DefaultOpMatchingService.filterMatches(DefaultOpMatchingService.java:293)
	at net.imagej.ops.DefaultOpMatchingService.filterMatches(DefaultOpMatchingService.java:138)
	at net.imagej.ops.DefaultOpMatchingService.findMatch(DefaultOpMatchingService.java:95)
	at net.imagej.ops.DefaultOpMatchingService.findMatch(DefaultOpMatchingService.java:83)
	at net.imagej.ops.OpEnvironment.module(OpEnvironment.java:268)
	at net.imagej.ops.OpEnvironment.run(OpEnvironment.java:156)
	at net.imagej.ops.map.MapUnaryComputers$IIToIIParallel.compute(MapUnaryComputers.java:101)
	at net.imagej.ops.map.MapUnaryComputers$IIToIIParallel.compute(MapUnaryComputers.java:87)
	at net.imagej.ops.special.chain.UHCFViaUC.compute(UHCFViaUC.java:65)
	at net.imagej.ops.special.hybrid.UnaryHybridCF.calculate(UnaryHybridCF.java:61)
	at net.imagej.ops.special.hybrid.UnaryHybridCF.run(UnaryHybridCF.java:71)
	at net.imagej.ops.special.hybrid.UnaryHybridCF.run(UnaryHybridCF.java:97)
	at org.scijava.command.CommandModule.run(CommandModule.java:199)
	at net.imagej.ops.OpEnvironment.run(OpEnvironment.java:944)
	at net.imagej.ops.OpEnvironment.run(OpEnvironment.java:156)
	at net.imagej.ops.segment.detectRidges.RidgeDetectionMetadata.<init>(RidgeDetectionMetadata.java:84)
	at net.imagej.ops.segment.detectRidges.DefaultDetectRidges.calculate(DefaultDetectRidges.java:221)
	at net.imagej.ops.segment.detectRidges.DefaultDetectRidges.calculate(DefaultDetectRidges.java:58)
	at net.imagej.ops.special.function.UnaryFunctionOp.run(UnaryFunctionOp.java:74)
	at net.imagej.ops.special.function.AbstractUnaryFunctionOp.run(AbstractUnaryFunctionOp.java:58)
	at org.scijava.command.CommandModule.run(CommandModule.java:199)
	at net.imagej.ops.OpEnvironment.run(OpEnvironment.java:944)
	at net.imagej.ops.OpEnvironment.run(OpEnvironment.java:135)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
java.lang.NullPointerException: java.lang.NullPointerException

	at org.python.core.Py.JavaError(Py.java:552)
	at org.python.core.Py.JavaError(Py.java:543)
	at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:190)
	at org.python.core.PyObject.__call__(PyObject.java:438)
	at org.python.core.PyMethod.instancemethod___call__(PyMethod.java:237)
	at org.python.core.PyMethod.__call__(PyMethod.java:228)
	at org.python.core.PyMethod.__call__(PyMethod.java:218)
	at org.python.pycode._pyx26.f$0(New_.py:10)
	at org.python.pycode._pyx26.call_function(New_.py)
	at org.python.core.PyTableCode.call(PyTableCode.java:171)
	at org.python.core.PyCode.call(PyCode.java:18)
	at org.python.core.Py.runCode(Py.java:1614)
	at org.python.core.__builtin__.eval(__builtin__.java:497)
	at org.python.core.__builtin__.eval(__builtin__.java:501)
	at org.python.util.PythonInterpreter.eval(PythonInterpreter.java:259)
	at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:57)
	at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:31)
	at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
	at org.scijava.script.ScriptModule.run(ScriptModule.java:160)
	at org.scijava.module.ModuleRunner.run(ModuleRunner.java:168)
	at org.scijava.module.ModuleRunner.call(ModuleRunner.java:127)
	at org.scijava.module.ModuleRunner.call(ModuleRunner.java:66)
	at org.scijava.thread.DefaultThreadService$3.call(DefaultThreadService.java:238)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
	at net.imagej.legacy.convert.ImagePlusToImageDisplayConverter.canConvert(ImagePlusToImageDisplayConverter.java:75)
	at net.imagej.legacy.convert.ImagePlusToImageDisplayConverter.canConvert(ImagePlusToImageDisplayConverter.java:69)
	at net.imagej.legacy.convert.ImagePlusToImageDisplayConverter.canConvert(ImagePlusToImageDisplayConverter.java:81)
	at org.scijava.convert.AbstractConverter.canConvert(AbstractConverter.java:89)
	at org.scijava.convert.AbstractConverter.supports(AbstractConverter.java:144)
	at org.scijava.convert.AbstractConverter.supports(AbstractConverter.java:69)
	at org.scijava.plugin.HandlerService.getHandler(HandlerService.java:60)
	at org.scijava.plugin.HandlerService.supports(HandlerService.java:79)
	at org.scijava.convert.AbstractConvertService.supports(AbstractConvertService.java:97)
	at net.imagej.ops.DefaultOpMatchingService.canConvert(DefaultOpMatchingService.java:602)
	at net.imagej.ops.DefaultOpMatchingService.canAssign(DefaultOpMatchingService.java:587)
	at net.imagej.ops.DefaultOpMatchingService.typesMatch(DefaultOpMatchingService.java:535)
	at net.imagej.ops.DefaultOpMatchingService.typesMatch(DefaultOpMatchingService.java:154)
	at net.imagej.ops.DefaultOpMatchingService.lambda$filterMatches$1(DefaultOpMatchingService.java:138)
	at net.imagej.ops.DefaultOpMatchingService.filterMatches(DefaultOpMatchingService.java:293)
	at net.imagej.ops.DefaultOpMatchingService.filterMatches(DefaultOpMatchingService.java:138)
	at net.imagej.ops.DefaultOpMatchingService.findMatch(DefaultOpMatchingService.java:95)
	at net.imagej.ops.DefaultOpMatchingService.findMatch(DefaultOpMatchingService.java:83)
	at net.imagej.ops.OpEnvironment.module(OpEnvironment.java:268)
	at net.imagej.ops.OpEnvironment.run(OpEnvironment.java:156)
	at net.imagej.ops.map.MapUnaryComputers$IIToIIParallel.compute(MapUnaryComputers.java:101)
	at net.imagej.ops.map.MapUnaryComputers$IIToIIParallel.compute(MapUnaryComputers.java:87)
	at net.imagej.ops.special.chain.UHCFViaUC.compute(UHCFViaUC.java:65)
	at net.imagej.ops.special.hybrid.UnaryHybridCF.calculate(UnaryHybridCF.java:61)
	at net.imagej.ops.special.hybrid.UnaryHybridCF.run(UnaryHybridCF.java:71)
	at net.imagej.ops.special.hybrid.UnaryHybridCF.run(UnaryHybridCF.java:97)
	at org.scijava.command.CommandModule.run(CommandModule.java:199)
	at net.imagej.ops.OpEnvironment.run(OpEnvironment.java:944)
	at net.imagej.ops.OpEnvironment.run(OpEnvironment.java:156)
	at net.imagej.ops.segment.detectRidges.RidgeDetectionMetadata.<init>(RidgeDetectionMetadata.java:84)
	at net.imagej.ops.segment.detectRidges.DefaultDetectRidges.calculate(DefaultDetectRidges.java:221)
	at net.imagej.ops.segment.detectRidges.DefaultDetectRidges.calculate(DefaultDetectRidges.java:58)
	at net.imagej.ops.special.function.UnaryFunctionOp.run(UnaryFunctionOp.java:74)
	at net.imagej.ops.special.function.AbstractUnaryFunctionOp.run(AbstractUnaryFunctionOp.java:58)
	at org.scijava.command.CommandModule.run(CommandModule.java:199)
	at net.imagej.ops.OpEnvironment.run(OpEnvironment.java:944)
	at net.imagej.ops.OpEnvironment.run(OpEnvironment.java:135)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:188)
	... 24 more


#4

Hi @AndyMan!

Sorry that it took so long for me to reply back,

I did a little bit of digging, and my first guess is that your issue is stemming from your input image not fitting the requirements of the Op, namely that it is most likely 3 dimensions (see this Contingent). (As of now) segment.detectRidges only works on 2-dimensional images. You can use Views.hyperSlice (or its Ops wrapper) to fix this pretty easily, or find some other way to make a 2-dimensional (grayscale) composite of your image if this is the case. Let me know if this fixes things!

Best,

Gabe