This looks like a nice image, but the metadata could be totally incorrect or corrupted
If you would take a snapshot of any DICOM archive and check
the image headers for correctness, I would argue that there are quite a few
hidden problems that you might not know about.
Errors in a DICOM header can cause images to be incorrectly
displayed, incorrectly added to the database, or being flatly rejected by the
PACS. By DICOM errors, I don’t mean an incorrect Accession Number of patient
name, or duplicate ID, but rather a violation of the rules defined in the DICOM
standard for a particular field entry.
These instructions for getting started writing plugins for ImageJ2 were developed at the Fiji / ImageJ2 Hackathon in Dresden, Germany, December 2011, using the Eclipse IDE version 3.7 and Sun JDK 1.6 on Ubuntu 11.04. It assumes that you have a working installation of ImageJ2, from http://developer.imagej.net/downloads.
Install Eclipse IDE version 3.7 for Java developers from http://eclipse.org/downloads/, using the appropriate download for your system.
Download imagej-2.0.0-SNAPSHOT-all.jar from http://developer.imagej.net/downloads and save it somewhere handy; I have mine in a directory called JavaLibs.
Run Eclipse and tell it to use JDK 6 as the default JRE for new projects (Window > Preferences > Installed JREs > Add... > Standard VM > Navigate to your JDK install directory
Right click in the Package Explorer > New... > Java Project
Give your project a name, e.g. IJ2-plugins, hit Next
Under the Libraries tab Add External Jars... and navigate to the imagej-2.0.0-SNAPSHOT-all.jar you downloaded in step 3. This gives you access to the IJ2 application programming interface (API). At the time of writing, to get context Javadoc for ImgLib classes you also have to specify the URL of its Javadoc. Click on the triangle to the left of imagej-2.0.0-SNAPSHOT-all.jar, select "Javadoc location:", hit Edit, add the URL:
Configure Ant to do your build using the javac compiler
Copy this code and paste it into your project in a file called build.xml
<project name="Plugins for ImageJ2" default="" basedir="."> <description> ImageJ2 build file </description> <property name="src" location="src" /> <property name="build" location="javacbin" /> <property name="imagej2Plugins" location="/home/mdoube/imagejdev/plugins/" /> <property name="user.name" value="Michael Doube" /> <path id="plugin-classpath"> <fileset dir="/home/mdoube/JavaLibs/"> <include name="imagej-2.0-SNAPSHOT-all.jar" /> </fileset> <pathelement path="${build.dir}" /> </path> <target name="init"> <!-- Create the time stamp --> <tstamp /> <!-- Create the build directory structure used by compile --> <mkdir dir="${build}" /> </target> <target name="compile" depends="" description="compile the source "> <!-- Compile the java code from ${src} into ${build} --> <javac includeantruntime="false" srcdir="${src}" destdir="${build}"> <classpath refid="plugin-classpath"/> </javac> <echo> Building the .jar file. </echo> </target> <target name="compress" depends="" description="generate the distribution"> <jar jarfile="IJ2Plugins.jar"> <fileset dir="${build}" includes="**/*.*" /> <manifest> <attribute name="Built-By" value="${user.name}" /> </manifest> </jar> <copy file="IJ2Plugins.jar" toDir="${imagej2Plugins}" /> </target> <target name="clean" description="clean up"> <!-- Delete the ${build} and ${dist} directory trees --> <delete dir="${build}" /> </target> </project>
double-click on build.xml and edit it so that the fileset dir="" field contains the ij-app jar and the ImageJ2Plugins location is set to your local ImageJ plugins directory
you can also edit the name of the jar that's generated
now right-click on your project in the Package Explorer > Properties > Builders > New > select Ant Builder > Enter a name for your builder
Main tab, under Buildfile: hit Browse Workspace and locate the build.xml you just made, hit OK
Targets tab, After a “Clean”: Set targets, check init, compile, compress, clean
Targets tab, Auto Build: Set targets, check init, compile, compress, clean
Hello World
Writing your first plugin: HelloWorld
Right-click on the src directory of your new project and New > Class
Give your class a name; e.g., HelloWorld (the convention for classes is to be capitalised like that)
Eclipse initialises a new file and puts a little code into it for you.
Edit the first line so it reads: public class HelloWorld implements RunnablePlugin {
Note the squiggly red line under RunnablePlugin indicating a compile error, move your cursor to it and hit Ctrl+1
Eclipse gives you a bunch of autocorrect options, select the top one, Import 'RunnablePlugin' (imagej.ext.plugin) and hit Enter. Eclipse adds a line of code for you at the top of the file: import imagej.ext.plugin.RunnablePlugin;
Now HelloWorld gets a squiggly line, so Ctrl+1 again and select Add Unimplemented Methods. Eclipse adds a bunch of code, which is the run() method needed because we are implementing the RunnablePlugin interface.
We want HelloWorld to show up in the ImageJ menus, so add an annotation above the public class line: @Plugin(menuPath = "Plugins>Hello World")
Ctrl+1 again on the @Plugin squiggly line to autocorrect the missing import.
You can Ctrl+Space and Eclipse will suggest options for autocompletion.
Let's check ImageJ and see if our plugin is available in the menus.
Run ImageJ
You should now see in ImageJ's Plugins menu an item called Hello World
But it doesn't do anything yet because we haven't added any useful code
Add code to your HelloWorld until it matches HelloWorld.java below, using Ctrl+1 and Ctrl+Space to investigate possibilities in the API
Each time you update your code, Ant rebuilds your jar and copies it to your plugins directory
At the moment, you have to restart ImageJ to test your changes
ImageJ 2.0.0, referred to as "ImageJ2" or "IJ2" for short, is currently in development. It is a complete rewrite of ImageJ, but includes ImageJ1 with a compatibility layer, so that old-style plugins and macros can run the same as in IJ1.
Fiji is a distribution of ImageJ (both ImageJ1 and ImageJ2!) for the life sciences. It provides a large number of additional plugins to facilitate analysis of life sciences images, particularly microscopy images.
Java Collection classes are fail-fast which means that if the Collection
will be changed while some thread is traversing over it using iterator,
the iterator.next() will throw a ConcurrentModificationException.
This situation can come in case of multithreaded as well as single threaded environment.
Lets explore this scenario with the following example :
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From the output stack trace, its clear that the exception is coming
when we call iterator next() function. If you are wondering how Iterator
checks for the modification, its implementation is present in
AbstractList class where an int variable modCount is defined that
provides the number of times list size has been changed. This value is
used in every next() call to check for any modifications in a function
checkForComodification().
Now comment the list part and run the program again.
Output will be:
Map Value:3
Map Value:2
Map Value:4
Since we are updating the existing key value in the myMap, its size
has not been changed and we are not getting
ConcurrentModificationException. Note that the output may differ in your
system because HashMap keyset is not ordered like list. If you will
uncomment the statement where I am adding a new key-value in the
HashMap, it will cause ConcurrentModificationException.
To Avoid ConcurrentModificationException in multi-threaded environment:
1.
You can convert the list to an array and then iterate on the array.
This approach works well for small or medium size list but if the list
is large then it will affect the performance a lot.
2. You can
lock the list while iterating by putting it in a synchronized block.
This approach is not recommended because it will cease the benefits of
multithreading.
3. If you are using JDK1.5 or higher then you can
use ConcurrentHashMap and CopyOnWriteArrayList classes. It is the
recommended approach.
To Avoid ConcurrentModificationException in single-threaded environment:
You
can use the iterator remove() function to remove the object from
underlying collection object. But in this case you can remove the same
object and not any other object from the list.
Let us run an example using Concurrent Collection classes:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Eclipse used to need a column mode plugin to be able to select a rectangular selection.
Since Eclipse 3.5, you just need to type Alt+Shift+A: see its News and Noteworthy section. (On OS X it's Option-Command-A.)
Or activate the 'Editor Presentation' action set ( Window > Customize Perspective menu) to get a tool bar button for toggling the block selection mode.
Just create a new BufferedImage with transparency, then paint the other two images (with full or semi-transparency) on it.
This is how it will look like:
Sample code (images are called 'image.png' and 'overlay.png'):
File path =...// base path of the images// load source imagesBufferedImage image =ImageIO.read(newFile(path,"image.png"));BufferedImage overlay =ImageIO.read(newFile(path,"overlay.png"));// create the new image, canvas size is the max. of both image sizesint w =Math.max(image.getWidth(), overlay.getWidth());int h =Math.max(image.getHeight(), overlay.getHeight());BufferedImage combined =newBufferedImage(w, h,BufferedImage.TYPE_INT_ARGB);// paint both images, preserving the alpha channelsGraphics g = combined.getGraphics();
g.drawImage(image,0,0,null);
g.drawImage(overlay,0,0,null);// Save as new imageImageIO.write(combined,"PNG",newFile(path,"combined.png"));