From b8d4c02a85b8c89f09b4b5273de48a5907a85ddf Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 30 Apr 2013 10:38:54 -0500 Subject: [PATCH] This is the end of ImgLib1 as we know it Starting with this commit, ImgLib1 will be phased out. To make phasing out easier, the SPIM Registration project at https://github.com/fiji/fiji/tree/master/src-plugins/SPIM_Registration/ will add ImgLib2 wrappers for ImgLib1 data structures. Signed-off-by: Johannes Schindelin --- LICENSE.txt | 339 ++++++++++++ pom.xml | 130 +++++ .../TestRelativeIterationPerformance.java | 500 ++++++++++++++++++ .../componenttree/mser/MserTreeExample.java | 159 ++++++ .../PixelListComponentTreeExample.java | 100 ++++ .../algorithm/edge/EdgelDetectionExample.java | 94 ++++ .../algorithm/gauss3/Gauss3Benchmark.java | 334 ++++++++++++ .../algorithm/gauss3/Gauss3Example.java | 66 +++ .../algorithm/gradient/GradientExample.java | 97 ++++ .../legacy/scalespace/DoGBenchmark.java | 137 +++++ .../localization/GaussianFitTestDrive0.java | 139 +++++ .../localization/GaussianFitTestDrive1.java | 147 +++++ .../pde/AnisotropicDiffusion3DExample.java | 186 +++++++ .../pde/AnisotropicDiffusionExample.java | 95 ++++ ...eronaMalikAnisotropicDiffusionExample.java | 75 +++ .../region/BresenhamLineExample.java | 90 ++++ .../EllipsoidNeighborhoodExample.java | 154 ++++++ .../LocalMaximaBenchmark.java | 169 ++++++ .../localneighborhood/MinFilterExample.java | 81 +++ .../localneighborhood/ShowCoordinates2D.java | 112 ++++ .../imglib2/img/sparse/ExampleQuadtree.java | 88 +++ src/test/java/net/imglib2/view/CopyViews.java | 126 +++++ .../view/MixedTransformConcatenateTest.java | 404 ++++++++++++++ .../view/OpenAndDisplayInterpolated.java | 119 +++++ .../imglib2/view/OpenAndDisplayRotated.java | 82 +++ .../imglib2/view/OpenAndDisplaySliceView.java | 65 +++ .../net/imglib2/view/OpenAndDisplayView.java | 73 +++ .../view/SlicingTransformConcatenateTest.java | 145 +++++ .../TranslationTransformConcatenateTest.java | 153 ++++++ .../tests/CompositeXYProjectorBenchmark.java | 83 +++ ...eXYRandomAccessibleProjectorBenchmark.java | 83 +++ src/test/java/tests/ImgPanel.java | 205 +++++++ src/test/java/tests/LanczosExample.java | 135 +++++ ...ndDisplayAffineTransformedScreenImage.java | 161 ++++++ .../java/tests/OpenAndDisplayScreenImage.java | 78 +++ .../OpenAndDisplayWithCellContainer.java | 62 +++ src/test/java/tests/XYProjectorBenchmark.java | 76 +++ .../XYRandomAccessibleProjectorBenchmark.java | 76 +++ 38 files changed, 5418 insertions(+) create mode 100644 LICENSE.txt create mode 100644 pom.xml create mode 100644 src/test/java/net/imglib2/algorithm/TestRelativeIterationPerformance.java create mode 100644 src/test/java/net/imglib2/algorithm/componenttree/mser/MserTreeExample.java create mode 100644 src/test/java/net/imglib2/algorithm/componenttree/pixellist/PixelListComponentTreeExample.java create mode 100644 src/test/java/net/imglib2/algorithm/edge/EdgelDetectionExample.java create mode 100644 src/test/java/net/imglib2/algorithm/gauss3/Gauss3Benchmark.java create mode 100644 src/test/java/net/imglib2/algorithm/gauss3/Gauss3Example.java create mode 100644 src/test/java/net/imglib2/algorithm/gradient/GradientExample.java create mode 100644 src/test/java/net/imglib2/algorithm/legacy/scalespace/DoGBenchmark.java create mode 100644 src/test/java/net/imglib2/algorithm/localization/GaussianFitTestDrive0.java create mode 100644 src/test/java/net/imglib2/algorithm/localization/GaussianFitTestDrive1.java create mode 100644 src/test/java/net/imglib2/algorithm/pde/AnisotropicDiffusion3DExample.java create mode 100644 src/test/java/net/imglib2/algorithm/pde/AnisotropicDiffusionExample.java create mode 100644 src/test/java/net/imglib2/algorithm/pde/PeronaMalikAnisotropicDiffusionExample.java create mode 100644 src/test/java/net/imglib2/algorithm/region/BresenhamLineExample.java create mode 100644 src/test/java/net/imglib2/algorithm/region/localneighborhood/EllipsoidNeighborhoodExample.java create mode 100644 src/test/java/net/imglib2/algorithm/region/localneighborhood/LocalMaximaBenchmark.java create mode 100644 src/test/java/net/imglib2/algorithm/region/localneighborhood/MinFilterExample.java create mode 100644 src/test/java/net/imglib2/algorithm/region/localneighborhood/ShowCoordinates2D.java create mode 100644 src/test/java/net/imglib2/img/sparse/ExampleQuadtree.java create mode 100644 src/test/java/net/imglib2/view/CopyViews.java create mode 100644 src/test/java/net/imglib2/view/MixedTransformConcatenateTest.java create mode 100644 src/test/java/net/imglib2/view/OpenAndDisplayInterpolated.java create mode 100644 src/test/java/net/imglib2/view/OpenAndDisplayRotated.java create mode 100644 src/test/java/net/imglib2/view/OpenAndDisplaySliceView.java create mode 100644 src/test/java/net/imglib2/view/OpenAndDisplayView.java create mode 100644 src/test/java/net/imglib2/view/SlicingTransformConcatenateTest.java create mode 100644 src/test/java/net/imglib2/view/TranslationTransformConcatenateTest.java create mode 100644 src/test/java/tests/CompositeXYProjectorBenchmark.java create mode 100644 src/test/java/tests/CompositeXYRandomAccessibleProjectorBenchmark.java create mode 100644 src/test/java/tests/ImgPanel.java create mode 100644 src/test/java/tests/LanczosExample.java create mode 100644 src/test/java/tests/OpenAndDisplayAffineTransformedScreenImage.java create mode 100644 src/test/java/tests/OpenAndDisplayScreenImage.java create mode 100644 src/test/java/tests/OpenAndDisplayWithCellContainer.java create mode 100644 src/test/java/tests/XYProjectorBenchmark.java create mode 100644 src/test/java/tests/XYRandomAccessibleProjectorBenchmark.java diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..d511905 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..6cbccec --- /dev/null +++ b/pom.xml @@ -0,0 +1,130 @@ + + + 4.0.0 + + + net.imglib2 + pom-imglib2 + 2.0.0-SNAPSHOT + + + imglib2-tests + + ImgLib2 Tests + Integration tests for ImgLib2. + + + + GPL 2 or later + http://www.gnu.org/licenses/gpl-2.0.txt + repo + + + + + + ${project.groupId} + imglib2 + ${project.version} + test + + + ${project.groupId} + imglib2-algorithms + ${project.version} + test + + + ${project.groupId} + imglib2-algorithms-gpl + ${project.version} + test + + + ${project.groupId} + imglib2-algorithms-legacy + ${project.version} + test + + + ${project.groupId} + imglib2-ij + ${project.version} + test + + + ${project.groupId} + imglib2-io + ${project.version} + test + + + ${project.groupId} + imglib2-realtransform + ${project.version} + test + + + ${imagej.groupId} + ij + ${imagej1.version} + test + + + ${scifio.groupId} + scifio-devel + ${scifio.version} + test + + + jama + jama + 1.0.2 + test + + + junit + junit + 4.9 + test + + + mpicbg + mpicbg + 20111128 + test + + + + + ${basedir}/../.. + + + + + + org.codehaus.mojo + license-maven-plugin + + gpl_v2 + + + + + + + + + imagej.releases + http://maven.imagej.net/content/repositories/releases + + + imagej.snapshots + http://maven.imagej.net/content/repositories/snapshots + + + + diff --git a/src/test/java/net/imglib2/algorithm/TestRelativeIterationPerformance.java b/src/test/java/net/imglib2/algorithm/TestRelativeIterationPerformance.java new file mode 100644 index 0000000..c689b28 --- /dev/null +++ b/src/test/java/net/imglib2/algorithm/TestRelativeIterationPerformance.java @@ -0,0 +1,500 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package net.imglib2.algorithm; + +import ij.ImageJ; + +import java.io.File; + +import net.imglib2.Cursor; +import net.imglib2.ExtendedRandomAccessibleInterval; +import net.imglib2.FinalInterval; +import net.imglib2.Interval; +import net.imglib2.RandomAccess; +import net.imglib2.exception.IncompatibleTypeException; +import net.imglib2.img.Img; +import net.imglib2.img.ImgFactory; +import net.imglib2.img.array.ArrayImgFactory; +import net.imglib2.img.display.imagej.ImageJFunctions; +import net.imglib2.io.ImgIOException; +import net.imglib2.io.ImgOpener; +import net.imglib2.outofbounds.OutOfBounds; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.RealType; +import net.imglib2.type.numeric.real.FloatType; +import net.imglib2.view.Views; + +public class TestRelativeIterationPerformance> implements Benchmark, OutputAlgorithm> { + + private long processingTime; + private final Img input; + private Img output; + + public IterationMethod method = IterationMethod.RANDOM_ACCESS; + + public static enum IterationMethod { + RANDOM_ACCESS, + RANDOM_ACCESS_SPLIT, + RANDOM_ACCESS_NO_EXTEND, + TRANSLATE_VIEW, + TRANSLATE_VIEW_CURSOR, + TRANSLATE_VIEW_SPLIT + } + + /* + * CONSTRUCTOR + */ + + public TestRelativeIterationPerformance(final Img input) { + this.input = input; + try { + output = input.factory().imgFactory(new FloatType()).create( input, new FloatType() ); + } catch (final IncompatibleTypeException e) { + e.printStackTrace(); + } + + } + + /* + * METHODS + */ + + @Override + public boolean checkInput() { + return true; + } + + @Override + public boolean process() { + final long start = System.currentTimeMillis(); + + switch (method) { + case RANDOM_ACCESS: + iterateWithRandoAccessible(); + break; + case RANDOM_ACCESS_SPLIT: + iterateWithRandomAccessibleSplit(); + break; + case TRANSLATE_VIEW: + iterateWithViews(); + break; + case TRANSLATE_VIEW_CURSOR: + iterateWithViewsCursor(); + break; + case TRANSLATE_VIEW_SPLIT: + iterateWithViewsSplit(); + break; + case RANDOM_ACCESS_NO_EXTEND: + iterateWithRandoAccessibleNoOutOfBounds(); + break; + + } + + processingTime = System.currentTimeMillis() - start; + + return true; + } + + private void iterateWithRandoAccessibleNoOutOfBounds() { + final int n = input.numDimensions(); + final long[] min = new long[ n ]; + final long[] max = new long[ n ]; + input.min( min ); + input.max( max ); + for ( int d = 0; d < n; ++d ) + { + min[d] += 1; + max[d] -= 1; + } + final Cursor oc = Views.iterable(Views.interval(output, min, max)).localizingCursor(); + final RandomAccess ra = input.randomAccess(); + float I, In, Ine, Ie, Ise, Is, Isw, Iw, Inw; + + while(oc.hasNext()) { + + oc.fwd(); + + ra.setPosition(oc); + + I = ra.get().getRealFloat(); + ra.bck(1); + In = ra.get().getRealFloat(); + ra.fwd(0); + Ine = ra.get().getRealFloat(); + ra.fwd(1); + Ie = ra.get().getRealFloat(); + ra.fwd(1); + Ise = ra.get().getRealFloat(); + ra.bck(0); + Is = ra.get().getRealFloat(); + ra.bck(0); + Isw = ra.get().getRealFloat(); + ra.bck(1); + Iw = ra.get().getRealFloat(); + ra.bck(1); + Inw = ra.get().getRealFloat(); + + oc.get().set( I - 1/8f * (In+Ine+Ie+Ise+Is+Isw+Iw+Inw)); + } + + } + + private void iterateWithViews() { + + final ExtendedRandomAccessibleInterval> extended = Views.extendMirrorSingle(input); + + final Cursor northCursor = Views.iterable(Views.interval(Views.offset(extended, new long[] {0, -1}), input) ).cursor(); + final Cursor northEastCursor = Views.iterable(Views.interval(Views.offset(extended, new long[] {1, -1}), input) ).cursor(); + final Cursor eastCursor = Views.iterable(Views.interval(Views.offset(extended, new long[] {1, 0}), input) ).cursor(); + final Cursor southEastCursor = Views.iterable(Views.interval(Views.offset(extended, new long[] {1, 1}), input) ).cursor(); + final Cursor southCursor = Views.iterable(Views.interval(Views.offset(extended, new long[] {0, 1}), input) ).cursor(); + final Cursor southWestCursor = Views.iterable(Views.interval(Views.offset(extended, new long[] {-1, 1}), input) ).cursor(); + final Cursor westCursor = Views.iterable(Views.interval(Views.offset(extended, new long[] {-1, 0}), input) ).cursor(); + final Cursor northWestCursor = Views.iterable(Views.interval(Views.offset(extended, new long[] {-1, 1}), input) ).cursor(); + + final Cursor cursor = input.localizingCursor(); + final RandomAccess oc = output.randomAccess(); + + float I, In, Ine, Ie, Ise, Is, Isw, Iw, Inw; + while (cursor.hasNext()) { + + I = cursor.next().getRealFloat(); + In = northCursor.next().getRealFloat(); + Ine = northEastCursor.next().getRealFloat(); + Ie = eastCursor.next().getRealFloat(); + Ise = southEastCursor.next().getRealFloat(); + Is = southCursor.next().getRealFloat(); + Isw = southWestCursor.next().getRealFloat(); + Iw = westCursor.next().getRealFloat(); + Inw = northWestCursor.next().getRealFloat(); + + oc.setPosition(cursor); + oc.get().set( I - 1/8f * (In+Ine+Ie+Ise+Is+Isw+Iw+Inw)); + } + + } + + private void iterateWithViewsCursor() { + + final ExtendedRandomAccessibleInterval> extended = Views.extendMirrorSingle(input); + + final Cursor northCursor = Views.iterable(Views.interval(Views.offset(extended, new long[] {0, -1}), input) ).cursor(); + final Cursor northEastCursor = Views.iterable(Views.interval(Views.offset(extended, new long[] {1, -1}), input) ).cursor(); + final Cursor eastCursor = Views.iterable(Views.interval(Views.offset(extended, new long[] {1, 0}), input) ).cursor(); + final Cursor southEastCursor = Views.iterable(Views.interval(Views.offset(extended, new long[] {1, 1}), input) ).cursor(); + final Cursor southCursor = Views.iterable(Views.interval(Views.offset(extended, new long[] {0, 1}), input) ).cursor(); + final Cursor southWestCursor = Views.iterable(Views.interval(Views.offset(extended, new long[] {-1, 1}), input) ).cursor(); + final Cursor westCursor = Views.iterable(Views.interval(Views.offset(extended, new long[] {-1, 0}), input) ).cursor(); + final Cursor northWestCursor = Views.iterable(Views.interval(Views.offset(extended, new long[] {-1, 1}), input) ).cursor(); + + final Cursor cursor = input.cursor(); + final Cursor oc = output.cursor(); + + float I, In, Ine, Ie, Ise, Is, Isw, Iw, Inw; + while (cursor.hasNext()) { + + I = cursor.next().getRealFloat(); + In = northCursor.next().getRealFloat(); + Ine = northEastCursor.next().getRealFloat(); + Ie = eastCursor.next().getRealFloat(); + Ise = southEastCursor.next().getRealFloat(); + Is = southCursor.next().getRealFloat(); + Isw = southWestCursor.next().getRealFloat(); + Iw = westCursor.next().getRealFloat(); + Inw = northWestCursor.next().getRealFloat(); + + oc.next().set( I - 1/8f * (In+Ine+Ie+Ise+Is+Isw+Iw+Inw)); + } + + } + + private void iterateWithViewsSplit() + { + final int n = input.numDimensions(); + final long[] min = new long[ n ]; + final long[] max = new long[ n ]; + + // process central part + min[ 0 ] = input.min( 0 ) + 1; + max[ 0 ] = input.max( 0 ) - 1; + min[ 1 ] = input.min( 1 ) + 1; + max[ 1 ] = input.max( 1 ) - 1; + iterateWithViewsPartial( new FinalInterval( min, max ) ); + + // process first line + min[ 0 ] = input.min( 0 ); + max[ 0 ] = input.max( 0 ); + min[ 1 ] = input.min( 1 ); + max[ 1 ] = input.min( 1 ) + 1; + iterateWithViewsPartial( new FinalInterval( min, max ) ); + + // process last line + min[ 0 ] = input.min( 0 ); + max[ 0 ] = input.max( 0 ); + min[ 1 ] = input.max( 1 ) - 1; + max[ 1 ] = input.max( 1 ); + iterateWithViewsPartial( new FinalInterval( min, max ) ); + + // process first column + min[ 0 ] = input.min( 0 ); + max[ 0 ] = input.min( 0 ) + 1; + min[ 1 ] = input.min( 1 ) + 1; + max[ 1 ] = input.max( 1 ) - 1; + iterateWithViewsPartial( new FinalInterval( min, max ) ); + + // process last column + min[ 0 ] = input.max( 0 ) - 1; + max[ 0 ] = input.max( 0 ); + min[ 1 ] = input.min( 1 ) + 1; + max[ 1 ] = input.max( 1 ) - 1; + iterateWithViewsPartial( new FinalInterval( min, max ) ); + } + + private void iterateWithViewsPartial( final Interval interval ) { + + final ExtendedRandomAccessibleInterval> extended = Views.extendMirrorSingle(input); + + final Cursor northCursor = Views.iterable(Views.interval(Views.offset(extended, new long[] {0, -1}), interval) ).cursor(); + final Cursor northEastCursor = Views.iterable(Views.interval(Views.offset(extended, new long[] {1, -1}), interval) ).cursor(); + final Cursor eastCursor = Views.iterable(Views.interval(Views.offset(extended, new long[] {1, 0}), interval) ).cursor(); + final Cursor southEastCursor = Views.iterable(Views.interval(Views.offset(extended, new long[] {1, 1}), interval) ).cursor(); + final Cursor southCursor = Views.iterable(Views.interval(Views.offset(extended, new long[] {0, 1}), interval) ).cursor(); + final Cursor southWestCursor = Views.iterable(Views.interval(Views.offset(extended, new long[] {-1, 1}), interval) ).cursor(); + final Cursor westCursor = Views.iterable(Views.interval(Views.offset(extended, new long[] {-1, 0}), interval) ).cursor(); + final Cursor northWestCursor = Views.iterable(Views.interval(Views.offset(extended, new long[] {-1, 1}), interval) ).cursor(); + + final Cursor cursor = Views.iterable(Views.interval( extended, interval )).cursor(); + final Cursor oc = Views.iterable(Views.interval( output, interval )).cursor(); + + float I, In, Ine, Ie, Ise, Is, Isw, Iw, Inw; + while (cursor.hasNext()) { + + I = cursor.next().getRealFloat(); + In = northCursor.next().getRealFloat(); + Ine = northEastCursor.next().getRealFloat(); + Ie = eastCursor.next().getRealFloat(); + Ise = southEastCursor.next().getRealFloat(); + Is = southCursor.next().getRealFloat(); + Isw = southWestCursor.next().getRealFloat(); + Iw = westCursor.next().getRealFloat(); + Inw = northWestCursor.next().getRealFloat(); + + oc.next().set( I - 1/8f * (In+Ine+Ie+Ise+Is+Isw+Iw+Inw)); + } + + } + + private void iterateWithRandomAccessibleSplit() + { + final int n = input.numDimensions(); + final long[] min = new long[ n ]; + final long[] max = new long[ n ]; + + // process central part + min[ 0 ] = input.min( 0 ) + 1; + max[ 0 ] = input.max( 0 ) - 1; + min[ 1 ] = input.min( 1 ) + 1; + max[ 1 ] = input.max( 1 ) - 1; + iterateWithRandomAccessiblePartial( new FinalInterval( min, max ) ); + + // process first line + min[ 0 ] = input.min( 0 ); + max[ 0 ] = input.max( 0 ); + min[ 1 ] = input.min( 1 ); + max[ 1 ] = input.min( 1 ) + 1; + iterateWithRandomAccessiblePartial( new FinalInterval( min, max ) ); + + // process last line + min[ 0 ] = input.min( 0 ); + max[ 0 ] = input.max( 0 ); + min[ 1 ] = input.max( 1 ) - 1; + max[ 1 ] = input.max( 1 ); + iterateWithRandomAccessiblePartial( new FinalInterval( min, max ) ); + + // process first column + min[ 0 ] = input.min( 0 ); + max[ 0 ] = input.min( 0 ) + 1; + min[ 1 ] = input.min( 1 ) + 1; + max[ 1 ] = input.max( 1 ) - 1; + iterateWithRandomAccessiblePartial( new FinalInterval( min, max ) ); + + // process last column + min[ 0 ] = input.max( 0 ) - 1; + max[ 0 ] = input.max( 0 ); + min[ 1 ] = input.min( 1 ) + 1; + max[ 1 ] = input.max( 1 ) - 1; + iterateWithRandomAccessiblePartial( new FinalInterval( min, max ) ); + } + + private void iterateWithRandomAccessiblePartial( final Interval interval ) { + final ExtendedRandomAccessibleInterval> extended = Views.extendMirrorSingle(input); + final Cursor oc = Views.iterable(Views.interval(output, interval)).localizingCursor(); + + final int n = input.numDimensions(); + final long[] min = new long[ n ]; + final long[] max = new long[ n ]; + interval.min( min ); + interval.max( max ); + for ( int d = 0; d < n; ++d ) + { + min[d] -= 1; + max[d] += 1; + } + final Interval raInterval = new FinalInterval( min, max ); + final RandomAccess ra = extended.randomAccess( raInterval ); + float I, In, Ine, Ie, Ise, Is, Isw, Iw, Inw; + + while(oc.hasNext()) { + + oc.fwd(); + + ra.setPosition(oc); + + I = ra.get().getRealFloat(); + ra.bck(1); + In = ra.get().getRealFloat(); + ra.fwd(0); + Ine = ra.get().getRealFloat(); + ra.fwd(1); + Ie = ra.get().getRealFloat(); + ra.fwd(1); + Ise = ra.get().getRealFloat(); + ra.bck(0); + Is = ra.get().getRealFloat(); + ra.bck(0); + Isw = ra.get().getRealFloat(); + ra.bck(1); + Iw = ra.get().getRealFloat(); + ra.bck(1); + Inw = ra.get().getRealFloat(); + + oc.get().set( I - 1/8f * (In+Ine+Ie+Ise+Is+Isw+Iw+Inw)); + } + + } + + private void iterateWithRandoAccessible() { + + final OutOfBounds ra = Views.extendMirrorSingle(input).randomAccess(); + final Cursor cursor = input.localizingCursor(); + final RandomAccess oc = output.randomAccess(); + + float I, In, Ine, Ie, Ise, Is, Isw, Iw, Inw; + + while (cursor.hasNext()) { + + cursor.fwd(); + oc.setPosition(cursor); + ra.setPosition(cursor); + + I = cursor.get().getRealFloat(); + ra.bck(1); + In = ra.get().getRealFloat(); + ra.fwd(0); + Ine = ra.get().getRealFloat(); + ra.fwd(1); + Ie = ra.get().getRealFloat(); + ra.fwd(1); + Ise = ra.get().getRealFloat(); + ra.bck(0); + Is = ra.get().getRealFloat(); + ra.bck(0); + Isw = ra.get().getRealFloat(); + ra.bck(1); + Iw = ra.get().getRealFloat(); + ra.bck(1); + Inw = ra.get().getRealFloat(); + + oc.get().set( I - 1/8f * (In+Ine+Ie+Ise+Is+Isw+Iw+Inw)); + + } + + } + + @Override + public String getErrorMessage() { + return null; + } + + @Override + public Img getResult() { + return output; + } + + @Override + public long getProcessingTime() { + return processingTime; + } + + public static & NativeType< T >> void benchmark( final IterationMethod method, final String msg, final int niter, final Img< T > image ) + { + // Init algo + final TestRelativeIterationPerformance algo = new TestRelativeIterationPerformance(image); + + algo.method = method; + + System.out.println( msg ); + final long start = System.currentTimeMillis(); + for (int i = 0; i < niter; i++) { + algo.process(); + } + final long totalTime = System.currentTimeMillis() - start; + ImageJFunctions.show(algo.getResult()); + System.out.println(String.format("Time taken: %.2f ms/iteration.", (float) totalTime / niter)); + final long width = image.dimension(0); + final long height = image.dimension(1); + System.out.println(String.format("or: %.2f µs/pixel.", 1000f * totalTime / ((float) niter * width * height))); + System.out.println(); + } + + /* + * MAIN METHOD + */ + + public static & NativeType< T >> void main(final String[] args) throws ImgIOException, IncompatibleTypeException { + +// File file = new File( "E:/Users/JeanYves/Desktop/Data/Y.tif"); + final File file = new File( "/home/tobias/Desktop/Y.tif"); + final int niter = 1000; + + // Open file in imglib2 + final ImgFactory< ? > imgFactory = new ArrayImgFactory< T >(); + final Img< T > image = new ImgOpener().openImg( file.getAbsolutePath(), imgFactory ); + + // Display it via ImgLib using ImageJ + new ImageJ(); + ImageJFunctions.show( image ); + + benchmark( IterationMethod.TRANSLATE_VIEW, "With translated views:", niter, image ); + benchmark( IterationMethod.TRANSLATE_VIEW_CURSOR, "With translated views (Cursors only):", niter, image ); + benchmark( IterationMethod.TRANSLATE_VIEW_SPLIT, "With translated views (split into center and borders):", niter, image ); + benchmark( IterationMethod.RANDOM_ACCESS, "With random access:", niter, image ); + benchmark( IterationMethod.RANDOM_ACCESS_SPLIT, "With random access (split into center and borders):", niter, image ); + benchmark( IterationMethod.RANDOM_ACCESS_NO_EXTEND, "With random access, no out of bounds access:", niter, image ); + } + +} diff --git a/src/test/java/net/imglib2/algorithm/componenttree/mser/MserTreeExample.java b/src/test/java/net/imglib2/algorithm/componenttree/mser/MserTreeExample.java new file mode 100644 index 0000000..d273244 --- /dev/null +++ b/src/test/java/net/imglib2/algorithm/componenttree/mser/MserTreeExample.java @@ -0,0 +1,159 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package net.imglib2.algorithm.componenttree.mser; + +import ij.IJ; +import ij.ImageJ; +import ij.ImagePlus; +import ij.ImageStack; +import ij.gui.EllipseRoi; +import ij.gui.Overlay; +import ij.process.ByteProcessor; + +import java.awt.Color; + +import net.imglib2.Localizable; +import net.imglib2.img.ImagePlusAdapter; +import net.imglib2.img.Img; +import net.imglib2.type.numeric.IntegerType; +import net.imglib2.type.numeric.integer.UnsignedByteType; + +/** + * Example of computing and visualizing the {@link MserTree} of an image. + * + * + * @author Tobias Pietzsch + */ +public class MserTreeExample< T extends IntegerType< T > > +{ + final ImagePlus imp; + final Overlay ov; + final ImageStack stack; + final int w; + final int h; + + public MserTreeExample( final ImagePlus imp, final ImageStack stack ) + { + this.imp = imp; + ov = new Overlay(); + imp.setOverlay( ov ); + this.stack = stack; + this.w = imp.getWidth(); + this.h = imp.getHeight(); + } + + /** + * Visualise MSER. Add a 3sigma ellipse overlay to {@link #imp} in the given + * color. Add a slice to {@link #stack} showing binary mask of MSER region. + */ + public void visualise( final Mser< T > mser, final Color color ) + { + final ByteProcessor byteProcessor = new ByteProcessor( w, h ); + final byte[] pixels = ( byte[] )byteProcessor.getPixels(); + for ( final Localizable l : mser ) + { + final int x = l.getIntPosition( 0 ); + final int y = l.getIntPosition( 1 ); + pixels[ y * w + x ] = (byte)(255 & 0xff); + } + final String label = "" + mser.value(); + stack.addSlice( label, byteProcessor ); + + final EllipseRoi ellipse = createEllipse( mser.mean(), mser.cov(), 3 ); + ellipse.setStrokeColor( color ); + ov.add( ellipse ); + } + + /** + * Visualize all MSER in a tree. {@see #visualise(Mser, Color)}. + */ + public void visualise( final MserTree< T > tree, final Color color ) + { + for ( final Mser< T > mser : tree ) + visualise( mser, color ); + } + + /** + * Paint ellipse at nsigmas standard deviations + * of the given 2D Gaussian distribution. + * + * @param mean (x,y) components of mean vector + * @param cov (xx, xy, yy) components of covariance matrix + * @return ImageJ roi + */ + public static EllipseRoi createEllipse( final double[] mean, final double[] cov, final double nsigmas ) + { + final double a = cov[0]; + final double b = cov[1]; + final double c = cov[2]; + final double d = Math.sqrt( a*a + 4*b*b - 2*a*c + c*c ); + final double scale1 = Math.sqrt( 0.5 * ( a+c+d ) ) * nsigmas; + final double scale2 = Math.sqrt( 0.5 * ( a+c-d ) ) * nsigmas; + final double theta = 0.5 * Math.atan2( (2*b), (a-c) ); + final double x = mean[ 0 ]; + final double y = mean[ 1 ]; + final double dx = scale1 * Math.cos( theta ); + final double dy = scale1 * Math.sin( theta ); + final EllipseRoi ellipse = new EllipseRoi( x-dx, y-dy, x+dx, y+dy, scale2 / scale1 ); + return ellipse; + } + + public static void main( final String[] args ) + { + final int delta = 15; + final long minSize = 10; + final long maxSize = 100*100; + final double maxVar = 0.8; + final double minDiversity = 0; + + final Img< UnsignedByteType > img; + try + { + new ImageJ(); + IJ.run("Lena (68K)"); + IJ.run("8-bit"); + img = ImagePlusAdapter.wrapByte( IJ.getImage() ); + } + catch ( final Exception e ) + { + e.printStackTrace(); + return; + } + + final ImagePlus impImg = IJ.getImage(); + final ImageStack stack = new ImageStack( (int) img.dimension( 0 ), (int) img.dimension( 1 ) ); + + final MserTree< UnsignedByteType > treeDarkToBright = MserTree.buildMserTree( img, new UnsignedByteType( delta ), minSize, maxSize, maxVar, minDiversity, true ); + final MserTree< UnsignedByteType > treeBrightToDark = MserTree.buildMserTree( img, new UnsignedByteType( delta ), minSize, maxSize, maxVar, minDiversity, false ); + final MserTreeExample< UnsignedByteType > vis = new MserTreeExample< UnsignedByteType >( impImg, stack ); + vis.visualise( treeDarkToBright, Color.CYAN ); + vis.visualise( treeBrightToDark, Color.MAGENTA ); + + final ImagePlus imp = new ImagePlus("components", stack); + imp.show(); + } +} diff --git a/src/test/java/net/imglib2/algorithm/componenttree/pixellist/PixelListComponentTreeExample.java b/src/test/java/net/imglib2/algorithm/componenttree/pixellist/PixelListComponentTreeExample.java new file mode 100644 index 0000000..be65071 --- /dev/null +++ b/src/test/java/net/imglib2/algorithm/componenttree/pixellist/PixelListComponentTreeExample.java @@ -0,0 +1,100 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package net.imglib2.algorithm.componenttree.pixellist; + +import net.imglib2.Cursor; +import net.imglib2.Localizable; +import net.imglib2.img.Img; +import net.imglib2.img.ImgFactory; +import net.imglib2.img.array.ArrayImgFactory; +import net.imglib2.type.numeric.integer.IntType; + +/** + * Example of computing the {@link PixelListComponentTree} of an image. + * + * + * @author Tobias Pietzsch + */ +public class PixelListComponentTreeExample +{ + public static final int[][] testData = new int[][] { + { 8, 7, 6, 7, 1 }, + { 8, 8, 5, 8, 1 }, + { 2, 3, 4, 3, 2 }, + { 1, 8, 3, 8, 1 }, + { 1, 2, 2, 2, 1 } }; + + static final long[] dimensions = new long[] { testData[ 0 ].length, testData.length }; + + public static void print( PixelListComponentTree< IntType > tree ) + { + for ( PixelListComponent< IntType > component : tree ) + { + System.out.println( component ); + + for ( int r = 0; r < dimensions[1]; ++r ) + { + System.out.print("| "); + for ( int c = 0; c < dimensions[0]; ++c ) + { + boolean set = false; + for ( Localizable l : component ) + if( l.getIntPosition( 0 ) == c && l.getIntPosition( 1 ) == r ) + set = true; + System.out.print( set ? "x " : ". " ); + } + System.out.println("|"); + } + + System.out.println(); + } + } + + public static void main( String[] args ) + { + ImgFactory< IntType > imgFactory = new ArrayImgFactory< IntType >(); + Img< IntType > input = imgFactory.create( dimensions, new IntType() ); + + // fill input image with test data + int[] pos = new int[ 2 ]; + Cursor< IntType > c = input.localizingCursor(); + while ( c.hasNext() ) + { + c.fwd(); + c.localize( pos ); + c.get().set( testData[ pos[ 1 ] ][ pos[ 0 ] ] ); + } + + System.out.println("== dark to bright =="); + PixelListComponentTree< IntType > tree = PixelListComponentTree.buildComponentTree( input, new IntType(), true ); + print( tree ); + + System.out.println("== bright to dark =="); + tree = PixelListComponentTree.buildComponentTree( input, new IntType(), false ); + print( tree ); + } +} diff --git a/src/test/java/net/imglib2/algorithm/edge/EdgelDetectionExample.java b/src/test/java/net/imglib2/algorithm/edge/EdgelDetectionExample.java new file mode 100644 index 0000000..fc5788d --- /dev/null +++ b/src/test/java/net/imglib2/algorithm/edge/EdgelDetectionExample.java @@ -0,0 +1,94 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package net.imglib2.algorithm.edge; + +import ij.IJ; +import ij.ImageJ; +import ij.ImagePlus; +import ij.gui.Line; +import ij.gui.Overlay; + +import java.awt.Color; +import java.util.ArrayList; + +import net.imglib2.img.Img; +import net.imglib2.img.ImgFactory; +import net.imglib2.img.array.ArrayImgFactory; +import net.imglib2.img.display.imagej.ImageJFunctions; +import net.imglib2.io.ImgIOException; +import net.imglib2.io.ImgOpener; +import net.imglib2.type.numeric.real.FloatType; + +public class EdgelDetectionExample +{ + final static public void main( final String[] args ) throws ImgIOException + { + new ImageJ(); + + final ImgFactory< FloatType > imgFactory = new ArrayImgFactory< FloatType >(); + + // load image + final Img< FloatType > img = new ImgOpener().openImg( "/home/tobias/workspace/HisYFP/blob.tif", imgFactory, new FloatType() ); + + // detect edgels + final ArrayList< Edgel > edgels = SubpixelEdgelDetection.getEdgels( img, imgFactory, 2 ); + final ImagePlus imp = ImageJFunctions.show( img ); + imp.setOverlay( paintEdgels( edgels, 0.05 ) ); + + for (int i = 0; i<7; ++i) IJ.run("In"); + } + + public static Overlay paintEdgels( final ArrayList< Edgel > edgels, final double magnitudeScale ) + { + final Overlay ov = new Overlay(); + + for ( final Edgel e : edgels ) + { + final float[] position = e.getPosition(); + final float[] gradient = e.getGradient(); + final float magnitude = e.getMagnitude(); + + final double x0 = position[0] + 0.5 * gradient[1]; + final double y0 = position[1] - 0.5 * gradient[0]; + final double x1 = x0 - gradient[1]; + final double y1 = y0 + gradient[0]; + Line l = new Line( x0 + 0.5, y0 + 0.5, x1 + 0.5, y1 + 0.5 ); + l.setStrokeColor( Color.cyan ); + ov.add( l ); + + final double x2 = position[0]; + final double y2 = position[1]; + final double x3 = x2 + magnitudeScale * magnitude * gradient[0]; + final double y3 = y2 + magnitudeScale * magnitude * gradient[1]; + l = new Line( x2 + 0.5, y2 + 0.5, x3 + 0.5, y3 + 0.5 ); + l.setStrokeColor( Color.green ); + ov.add( l ); + } + + return ov; + } +} diff --git a/src/test/java/net/imglib2/algorithm/gauss3/Gauss3Benchmark.java b/src/test/java/net/imglib2/algorithm/gauss3/Gauss3Benchmark.java new file mode 100644 index 0000000..1e275d4 --- /dev/null +++ b/src/test/java/net/imglib2/algorithm/gauss3/Gauss3Benchmark.java @@ -0,0 +1,334 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package net.imglib2.algorithm.gauss3; + +import java.util.Random; + +import net.imglib2.Point; +import net.imglib2.RandomAccessible; +import net.imglib2.RandomAccessibleInterval; +import net.imglib2.algorithm.gauss.GaussFloat; +import net.imglib2.algorithm.gauss.GaussGeneral; +import net.imglib2.algorithm.gauss.GaussNativeType; +import net.imglib2.converter.readwrite.RealFloatSamplerConverter; +import net.imglib2.converter.readwrite.WriteConvertedRandomAccessibleInterval; +import net.imglib2.exception.IncompatibleTypeException; +import net.imglib2.img.Img; +import net.imglib2.img.ImgFactory; +import net.imglib2.img.array.ArrayImgFactory; +import net.imglib2.img.display.imagej.ImageJFunctions; +import net.imglib2.io.ImgIOException; +import net.imglib2.type.numeric.integer.UnsignedByteType; +import net.imglib2.type.numeric.real.FloatType; +import net.imglib2.util.BenchmarkHelper; +import net.imglib2.util.Util; +import net.imglib2.view.Views; + +/** + * @author Tobias Pietzsch + */ +public class Gauss3Benchmark +{ + + public static void main( final String[] args ) throws ImgIOException + { + final long[] dimensions = new long[] { 1000, 1000 }; +// final long[] dimensions = new long[] { 100, 100, 100 }; + final double sigma = 3; + final int numRuns = 100; + final boolean printIndividualTimes = false; + + System.out.print( String.format( "benchmarking Gaussian convolution (sigma = %.1f) of a ", sigma ) ); + for ( int d = 0; d < dimensions.length; ++d ) + System.out.print( ( d == 0 ? "" : " x " ) + dimensions[ d ] ); + System.out.println( " FloatType image." ); + System.out.println( "showing median runtime over " + numRuns + " trials." ); + System.out.println(); + + benchmarkFloat( dimensions, sigma, printIndividualTimes, numRuns ); + System.out.println( " ================================== " ); + benchmarkNative( dimensions, sigma, printIndividualTimes, numRuns ); + System.out.println( " ================================== " ); + benchmarkGeneric( dimensions, sigma, printIndividualTimes, numRuns ); + System.out.println( " ================================== " ); + benchmarkInFloat( dimensions, sigma, printIndividualTimes, numRuns ); + +// visualise( dimensions, sigma ); + } + + public static < T > void convolve( + final double[] sigmas, final RandomAccessible< T > source, final RandomAccessibleInterval< T > target, + final ConvolverFactory< T, T > convf, final ImgFactory< T > imgf, final T type ) + { + final double[][] halfkernels = Gauss3.halfkernels( sigmas ); + final int numthreads = Runtime.getRuntime().availableProcessors(); + SeparableSymmetricConvolution.convolve( halfkernels, source, target, convf, convf,convf, convf, imgf, type, numthreads ); + } + + public static void benchmarkFloat( final long[] dimensions, final double sigma, final boolean printIndividualTimes, final int numRuns) throws ImgIOException + { + final FloatType type = new FloatType(); + final ArrayImgFactory< FloatType > factory = new ArrayImgFactory< FloatType >(); + final Img< FloatType > img = factory.create( dimensions, type ); + final Img< FloatType > convolved = factory.create( dimensions, type ); + fillRandom( img ); + + final int n = img.numDimensions(); + final double[] sigmas = new double[ n ]; + for ( int d = 0; d < n; ++d ) + sigmas[ d ] = sigma; + + System.out.println( "GaussFloat" ); + final Point min = new Point( n ); + img.min( min ); + BenchmarkHelper.benchmarkAndPrint( numRuns, printIndividualTimes, new Runnable() { + @Override + public void run() + { + new GaussFloat( sigmas, Views.extendMirrorSingle( img ), img, convolved, min, factory ).call(); + } + } ); + + System.out.println( "Gauss3 (should use FloatConvolverRealTypeBuffered)" ); + BenchmarkHelper.benchmarkAndPrint( numRuns, printIndividualTimes, new Runnable() { + @Override + public void run() + { + try + { + Gauss3.gauss( sigmas, Views.extendMirrorSingle( img ), convolved ); + } + catch ( final IncompatibleTypeException e ) + { + e.printStackTrace(); + } + } + } ); + + System.out.println( "SeparableSymmetricConvolution with FloatConvolverRealTypeBuffered" ); + BenchmarkHelper.benchmarkAndPrint( numRuns, printIndividualTimes, new Runnable() { + @Override + public void run() + { + convolve( sigmas, Views.extendMirrorSingle( img ), convolved, FloatConvolverRealTypeBuffered.< FloatType, FloatType >factory(), factory, type ); + } + } ); + + System.out.println( "SeparableSymmetricConvolution with FloatConvolverRealType" ); + BenchmarkHelper.benchmarkAndPrint( numRuns, printIndividualTimes, new Runnable() { + @Override + public void run() + { + convolve( sigmas, Views.extendMirrorSingle( img ), convolved, FloatConvolverRealType.< FloatType, FloatType >factory(), factory, type ); + } + } ); + } + + public static void benchmarkNative( final long[] dimensions, final double sigma, final boolean printIndividualTimes, final int numRuns) throws ImgIOException + { + final FloatType type = new FloatType(); + final ArrayImgFactory< FloatType > factory = new ArrayImgFactory< FloatType >(); + final Img< FloatType > img = factory.create( dimensions, type ); + final Img< FloatType > convolved = factory.create( dimensions, type ); + fillRandom( img ); + + final int n = img.numDimensions(); + final double[] sigmas = new double[ n ]; + for ( int d = 0; d < n; ++d ) + sigmas[ d ] = sigma; + + System.out.println( "GaussNativeType" ); + final Point min = new Point( n ); + img.min( min ); + BenchmarkHelper.benchmarkAndPrint( numRuns, printIndividualTimes, new Runnable() { + @Override + public void run() + { + new GaussNativeType< FloatType >( sigmas, Views.extendMirrorSingle( img ), img, convolved, min, factory, type ).call(); + } + } ); + + System.out.println( "SeparableSymmetricConvolution with ConvolverNativeTypeBuffered" ); + BenchmarkHelper.benchmarkAndPrint( numRuns, printIndividualTimes, new Runnable() { + @Override + public void run() + { + convolve( sigmas, Views.extendMirrorSingle( img ), convolved, ConvolverNativeTypeBuffered.factory( type ), factory, type ); + } + } ); + + System.out.println( "SeparableSymmetricConvolution with ConvolverNativeType" ); + BenchmarkHelper.benchmarkAndPrint( numRuns, printIndividualTimes, new Runnable() { + @Override + public void run() + { + convolve( sigmas, Views.extendMirrorSingle( img ), convolved, ConvolverNativeType.factory( type ), factory, type ); + } + } ); + } + + public static void benchmarkGeneric( final long[] dimensions, final double sigma, final boolean printIndividualTimes, final int numRuns) throws ImgIOException + { + final FloatType type = new FloatType(); + final ArrayImgFactory< FloatType > factory = new ArrayImgFactory< FloatType >(); + final Img< FloatType > img = factory.create( dimensions, type ); + final Img< FloatType > convolved = factory.create( dimensions, type ); + fillRandom( img ); + + final int n = img.numDimensions(); + final double[] sigmas = new double[ n ]; + for ( int d = 0; d < n; ++d ) + sigmas[ d ] = sigma; + + System.out.println( "GaussGeneral" ); + final Point min = new Point( n ); + img.min( min ); + BenchmarkHelper.benchmarkAndPrint( numRuns, printIndividualTimes, new Runnable() { + @Override + public void run() + { + new GaussGeneral< FloatType >( sigmas, Views.extendMirrorSingle( img ), img, convolved, min, factory, type ).call(); + } + } ); + + System.out.println( "SeparableSymmetricConvolution with ConvolverNumericType" ); + BenchmarkHelper.benchmarkAndPrint( numRuns, printIndividualTimes, new Runnable() { + @Override + public void run() + { + convolve( sigmas, Views.extendMirrorSingle( img ), convolved, ConvolverNumericType.factory( type ), factory, type ); + } + } ); + } + + static void fillRandom( final Img< FloatType > img ) + { + final Random random = new Random( 1232324970l ); + for ( final FloatType t : img ) + t.set( random.nextFloat() ); + } + + public static void visualise( final long[] dimensions, final double sigma ) throws ImgIOException + { + final FloatType type = new FloatType(); + final ArrayImgFactory< FloatType > factory = new ArrayImgFactory< FloatType >(); + final Img< FloatType > img = factory.create( dimensions, type ); + fillRandom( img ); + ImageJFunctions.show( img, "source image" ); + + final int s = Util.createGaussianKernel1DDouble( sigma, true ).length; + System.out.println( "kernel size = " + s ); + + final int n = img.numDimensions(); + final double[] sigmas = new double[ n ]; + for ( int d = 0; d < n; ++d ) + sigmas[ d ] = sigma; + + for ( int d = 0; d < n; ++d ) + System.out.print( ( d == 0 ? "" : " x " ) + img.dimension( d ) ); + System.out.println(); + + final Point min = new Point( n ); + img.min( min ); + final Img< FloatType > convolved2 = factory.create( img, new FloatType() ); + new GaussFloat( sigmas, Views.extendMirrorSingle( img ), img, convolved2, min, factory ).call(); + ImageJFunctions.show( convolved2, "GaussFloat" ); + + final Img< FloatType > convolved5 = factory.create( img, new FloatType() ); + convolve( sigmas, Views.extendMirrorSingle( img ), convolved5, ConvolverNumericType.factory( type ), factory, type ); + ImageJFunctions.show( convolved5, "SeparableSymmetricConvolution with ConvolverNumericType" ); + + final Img< FloatType > convolved4 = factory.create( img, new FloatType() ); + convolve( sigmas, Views.extendMirrorSingle( img ), convolved4, ConvolverNativeType.factory( type ), factory, type ); + ImageJFunctions.show( convolved4, "SeparableSymmetricConvolution with ConvolverNativeType" ); + + final Img< FloatType > convolved6 = factory.create( img, new FloatType() ); + convolve( sigmas, Views.extendMirrorSingle( img ), convolved6, ConvolverNativeTypeBuffered.factory( type ), factory, type ); + ImageJFunctions.show( convolved6, "SeparableSymmetricConvolution with ConvolverNativeTypeBuffered" ); + + final Img< FloatType > convolved7 = factory.create( img, new FloatType() ); + convolve( sigmas, Views.extendMirrorSingle( img ), convolved7, FloatConvolverRealType.< FloatType, FloatType >factory(), factory, type ); + ImageJFunctions.show( convolved7, "SeparableSymmetricConvolution with" ); + + final Img< FloatType > convolved3 = factory.create( img, new FloatType() ); + convolve( sigmas, Views.extendMirrorSingle( img ), convolved3, FloatConvolverRealTypeBuffered.< FloatType, FloatType >factory(), factory, type ); + ImageJFunctions.show( convolved3, "SeparableSymmetricConvolution with FloatConvolverRealTypeBuffered" ); + } + + static void fillRandomUnsignedByte( final Img< UnsignedByteType > img ) + { + final Random random = new Random( 1232324970l ); + for ( final UnsignedByteType t : img ) + t.set( random.nextInt( 256 ) ); + } + + public static void benchmarkInFloat( final long[] dimensions, final double sigma, final boolean printIndividualTimes, final int numRuns) throws ImgIOException + { + final UnsignedByteType unsignedByteType = new UnsignedByteType(); + final ArrayImgFactory< UnsignedByteType > factory = new ArrayImgFactory< UnsignedByteType >(); + final Img< UnsignedByteType > img = factory.create( dimensions, unsignedByteType ); + final Img< UnsignedByteType > convolved = factory.create( dimensions, unsignedByteType ); + fillRandomUnsignedByte( img ); + + final int n = img.numDimensions(); + final double[] sigmas = new double[ n ]; + for ( int d = 0; d < n; ++d ) + sigmas[ d ] = sigma; + + final FloatType floatType = new FloatType(); + final ArrayImgFactory< FloatType > floatFactory = new ArrayImgFactory< FloatType >(); + + System.out.println( "convolve UnsignedByteType using Converters on source and target" ); + BenchmarkHelper.benchmarkAndPrint( numRuns, printIndividualTimes, new Runnable() { + @Override + public void run() + { + final ConvolverFactory< FloatType, FloatType > cff = FloatConvolverRealTypeBuffered.< FloatType, FloatType >factory(); + final RandomAccessibleInterval< FloatType > rIn = new WriteConvertedRandomAccessibleInterval< UnsignedByteType, FloatType >( img, new RealFloatSamplerConverter< UnsignedByteType >() ); + final RandomAccessibleInterval< FloatType > rOut = new WriteConvertedRandomAccessibleInterval< UnsignedByteType, FloatType >( convolved, new RealFloatSamplerConverter< UnsignedByteType >() ); + final double[][] halfkernels = Gauss3.halfkernels( sigmas ); + final int numthreads = Runtime.getRuntime().availableProcessors(); + SeparableSymmetricConvolution.convolve( halfkernels, Views.extendMirrorSingle( rIn ), rOut, cff, cff, cff, cff, floatFactory, floatType, numthreads ); + } + } ); + + System.out.println( "convolve UnsignedByteType using multiple ConvolverFactories" ); + BenchmarkHelper.benchmarkAndPrint( numRuns, printIndividualTimes, new Runnable() { + @Override + public void run() + { + final ConvolverFactory< FloatType, FloatType > cff = FloatConvolverRealTypeBuffered.< FloatType, FloatType >factory(); + final ConvolverFactory< FloatType, UnsignedByteType > cfi = FloatConvolverRealTypeBuffered.< FloatType, UnsignedByteType >factory(); + final ConvolverFactory< UnsignedByteType, FloatType > cif = FloatConvolverRealTypeBuffered.< UnsignedByteType, FloatType >factory(); + final ConvolverFactory< UnsignedByteType, UnsignedByteType > cii = FloatConvolverRealTypeBuffered.< UnsignedByteType, UnsignedByteType >factory(); + final double[][] halfkernels = Gauss3.halfkernels( sigmas ); + final int numthreads = Runtime.getRuntime().availableProcessors(); + SeparableSymmetricConvolution.convolve( halfkernels, Views.extendMirrorSingle( img ), convolved, cif, cff, cfi, cii, floatFactory, floatType, numthreads ); + } + } ); + } +} diff --git a/src/test/java/net/imglib2/algorithm/gauss3/Gauss3Example.java b/src/test/java/net/imglib2/algorithm/gauss3/Gauss3Example.java new file mode 100644 index 0000000..35484c2 --- /dev/null +++ b/src/test/java/net/imglib2/algorithm/gauss3/Gauss3Example.java @@ -0,0 +1,66 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package net.imglib2.algorithm.gauss3; + +import net.imglib2.exception.IncompatibleTypeException; +import net.imglib2.img.Img; +import net.imglib2.img.array.ArrayImgFactory; +import net.imglib2.img.array.ArrayImgs; +import net.imglib2.img.display.imagej.ImageJFunctions; +import net.imglib2.io.ImgIOException; +import net.imglib2.io.ImgOpener; +import net.imglib2.type.numeric.real.FloatType; +import net.imglib2.view.Views; + +/** + * Example for using {@link Gauss3}. + * + * @author Tobias Pietzsch + */ +public class Gauss3Example +{ + public static void main( final String[] args ) throws ImgIOException + { + final String fn = "/home/tobias/workspace/data/DrosophilaWing.tif"; + final Img< FloatType > img = new ImgOpener().openImg( fn, new ArrayImgFactory< FloatType >(), new FloatType() ); + + final long[] dims = new long[ img.numDimensions() ]; + img.dimensions( dims ); + final Img< FloatType > convolved = ArrayImgs.floats( dims ); + + try + { + Gauss3.gauss( 3, Views.extendMirrorSingle( img ), convolved ); +// Gauss3.gauss( 5, img, Views.interval( convolved, Intervals.createMinSize( 200, 100, 200, 150 ) ) ); + } + catch ( final IncompatibleTypeException e ) + { + e.printStackTrace(); + } + ImageJFunctions.show( convolved ); + } +} diff --git a/src/test/java/net/imglib2/algorithm/gradient/GradientExample.java b/src/test/java/net/imglib2/algorithm/gradient/GradientExample.java new file mode 100644 index 0000000..ecbcf3d --- /dev/null +++ b/src/test/java/net/imglib2/algorithm/gradient/GradientExample.java @@ -0,0 +1,97 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package net.imglib2.algorithm.gradient; + +import net.imglib2.Interval; +import net.imglib2.img.Img; +import net.imglib2.img.ImgPlus; +import net.imglib2.img.array.ArrayImgFactory; +import net.imglib2.img.display.imagej.ImageJFunctions; +import net.imglib2.io.ImgIOException; +import net.imglib2.io.ImgOpener; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.RealType; +import net.imglib2.type.numeric.real.FloatType; +import net.imglib2.util.Intervals; +import net.imglib2.view.Views; + +public class GradientExample +{ + public static < T extends RealType< T > & NativeType< T > > void doit( final T type ) throws ImgIOException + { + final ImgPlus< T > input = new ImgOpener().openImg( "/home/tobias/workspace/data/img1.tif", new ArrayImgFactory< T >(), type ); + ImageJFunctions.show( input ); + + final int n = input.numDimensions(); + final long[] dim = new long[ n + 1 ]; + for ( int d = 0; d < n; ++d ) + dim[ d ] = input.dimension( d ); + dim[ n ] = n; + final Img< T > gradients = new ArrayImgFactory< T >().create( dim, type ); + + // bounding box for computation of gradients + // we require a border of 1 pixel wrt. to the input image + final Interval gradientComputationInterval = Intervals.expand( input, -1 ); + + // compute partial derivatives of input in all dimension + for ( int d = 0; d < n; ++d ) + PartialDerivative.gradientCentralDifference( input, Views.interval( Views.hyperSlice( gradients, n, d ), gradientComputationInterval ), d ); + + ImageJFunctions.show( gradients ); + +// final int numRuns = 20; +// final boolean printIndividualTimes = true; +// final ArrayList< Long > times = BenchmarkHelper.benchmark( numRuns, new Runnable() { +// @Override +// public void run() +// { +// for ( int i = 0; i < 10; ++i ) +// for ( int d = 0; d < n; ++d ) +// PartialDerivative.gradientCentralDifference( input, Views.interval( Views.hyperSlice( gradients, n, d ), gradientComputationInterval ), d ); +// } +// } ); +// if ( printIndividualTimes ) +// { +// for ( int i = 0; i < numRuns; ++i ) +// System.out.println( "run " + i + ": " + times.get( i ) + " ms" ); +// System.out.println(); +// } +// System.out.println( "median: " + BenchmarkHelper.median( times ) + " ms" ); + } + + public static void main( final String[] args ) + { + try + { + doit( new FloatType() ); + } + catch ( final ImgIOException e ) + { + e.printStackTrace(); + } + } +} diff --git a/src/test/java/net/imglib2/algorithm/legacy/scalespace/DoGBenchmark.java b/src/test/java/net/imglib2/algorithm/legacy/scalespace/DoGBenchmark.java new file mode 100644 index 0000000..ef47333 --- /dev/null +++ b/src/test/java/net/imglib2/algorithm/legacy/scalespace/DoGBenchmark.java @@ -0,0 +1,137 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package net.imglib2.algorithm.legacy.scalespace; + +import net.imglib2.RandomAccessibleInterval; +import net.imglib2.img.ImgPlus; +import net.imglib2.img.array.ArrayImgFactory; +import net.imglib2.io.ImgOpener; +import net.imglib2.outofbounds.OutOfBoundsMirrorFactory; +import net.imglib2.type.numeric.real.FloatType; +import net.imglib2.util.BenchmarkHelper; + +public class DoGBenchmark +{ + private static double computeK( final int stepsPerOctave ) + { + return Math.pow( 2f, 1f / stepsPerOctave ); + } + + private static float computeKWeight( final float k ) + { + return 1.0f / ( k - 1.0f ); + } + + private static float getDiffSigma( final float sigmaA, final float sigmaB ) + { + return ( float ) Math.sqrt( sigmaB * sigmaB - sigmaA * sigmaA ); + } + + private static float[] computeSigmaDiff( final float[] sigma, final float imageSigma ) + { + final float[] sigmaDiff = new float[ 2 ]; + + sigmaDiff[ 0 ] = getDiffSigma( imageSigma, sigma[ 0 ] ); + sigmaDiff[ 1 ] = getDiffSigma( imageSigma, sigma[ 1 ] ); + + return sigmaDiff; + } + + public static void main( final String[] args ) + { + final String filename = "/home/tobias/workspace/data/e002_t00001-a000-c001-i0.tif"; + final int numRuns = 10; + final boolean printIndividualTimes = true; + + final float sigma = 3.597f; + final float minPeakValue = 0.02f; + final float minInitialPeakValue = minPeakValue / 4; + final int stepsPerOctave = 4; + final float imageSigma = 0.5f; + + try + { + final ImgPlus< FloatType > image = new ImgOpener().openImg( filename, new ArrayImgFactory< FloatType >(), new FloatType() ); + final OutOfBoundsMirrorFactory> oobsFactory = new OutOfBoundsMirrorFactory< FloatType, RandomAccessibleInterval >( OutOfBoundsMirrorFactory.Boundary.SINGLE ); + + final float k = (float) computeK( stepsPerOctave ); + final float sigma1 = sigma; + final float sigma2 = sigma * k; + + final float[] sigmaXY = new float[]{ sigma1, sigma2 }; + final float[] sigmaDiffXY = computeSigmaDiff( sigmaXY, imageSigma ); + + final float K_MIN1_INV = computeKWeight(k); + + final double[][] sigmaDiff = new double[ 2 ][ 3 ]; + sigmaDiff[ 0 ][ 0 ] = sigmaDiffXY[ 0 ]; + sigmaDiff[ 0 ][ 1 ] = sigmaDiffXY[ 0 ]; + sigmaDiff[ 1 ][ 0 ] = sigmaDiffXY[ 1 ]; + sigmaDiff[ 1 ][ 1 ] = sigmaDiffXY[ 1 ]; + + // sigmaZ is at least twice the image sigma + if ( image.numDimensions() == 3 ) + { + final float sigma1Z = Math.max( imageSigma * 2, sigma1 / (float)image.calibration( 2 ) ); + final float sigma2Z = sigma1Z * k; + final float[] sigmaZ = new float[]{ sigma1Z, sigma2Z }; + final float[] sigmaDiffZ = computeSigmaDiff( sigmaZ, imageSigma ); + sigmaDiff[ 0 ][ 2 ] = sigmaDiffZ[ 0 ]; + sigmaDiff[ 1 ][ 2 ] = sigmaDiffZ[ 1 ]; + } + + final DifferenceOfGaussianOld dogOld = new DifferenceOfGaussianOld( image.getImg(), image.factory(), oobsFactory, sigmaDiff[0], sigmaDiff[1], minInitialPeakValue, K_MIN1_INV ); + dogOld.setKeepDoGImg( true ); + final DifferenceOfGaussian dogNew = new DifferenceOfGaussian( image.getImg(), image.factory(), oobsFactory, sigmaDiff[0], sigmaDiff[1], minInitialPeakValue, K_MIN1_INV ); + dogNew.setKeepDoGImg( true ); + + System.out.println( "DifferenceOfGaussian old" ); + BenchmarkHelper.benchmarkAndPrint( numRuns, printIndividualTimes, new Runnable() { + @Override + public void run() + { + dogOld.process(); +// System.out.println( "found " + dogOld.getPeaks().size() + " peaks" ); + } + } ); + + System.out.println( "DifferenceOfGaussian new" ); + BenchmarkHelper.benchmarkAndPrint( numRuns, printIndividualTimes, new Runnable() { + @Override + public void run() + { + dogNew.process(); +// System.out.println( "found " + dogNew.getPeaks().size() + " peaks" ); + } + } ); + } + catch ( final Exception e ) + { + e.printStackTrace(); + } + } +} diff --git a/src/test/java/net/imglib2/algorithm/localization/GaussianFitTestDrive0.java b/src/test/java/net/imglib2/algorithm/localization/GaussianFitTestDrive0.java new file mode 100644 index 0000000..2fade86 --- /dev/null +++ b/src/test/java/net/imglib2/algorithm/localization/GaussianFitTestDrive0.java @@ -0,0 +1,139 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ +package net.imglib2.algorithm.localization; + +import ij.ImagePlus; +import ij.gui.EllipseRoi; +import ij.gui.Overlay; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Random; + +import net.imglib2.Localizable; +import net.imglib2.Point; +import net.imglib2.img.array.ArrayImg; +import net.imglib2.img.array.ArrayImgs; +import net.imglib2.img.basictypeaccess.array.ByteArray; +import net.imglib2.img.display.imagej.ImageJFunctions; +import net.imglib2.type.numeric.integer.UnsignedByteType; + +public class GaussianFitTestDrive0 { + + public static void main(String[] args) { + + int width = 100; + int height = 100; + double sigma_noise = 5; + final int nspots = 10; + + System.out.println("Preparing image"); + long[] dimensions = new long[] { width, height }; + ArrayImg img = ArrayImgs.unsignedBytes(dimensions); + + Random rangen = new Random(); + Collection peaks = new HashSet(nspots); + Map groundTruth = new HashMap(nspots); + + for (int i = 0; i < nspots; i++) { + + for (int j = 0; j < nspots; j++) { + + + double A = 100 + 10 * rangen.nextGaussian(); + double x0 = width / (double) nspots * i * 1.02d; + double y0 = width / (double) nspots * j * 1.02d; + double sigma = 2 + 0.5 * rangen.nextGaussian(); + + Localizable peak = new Point((long) x0, (long) y0); + peaks.add(peak); + + double[] params = new double[] {x0, y0, A, 1/sigma/sigma }; + LocalizationUtils.addGaussianSpotToImage(img, params); + groundTruth.put(peak, params); + + } + } + LocalizationUtils.addGaussianNoiseToImage(img, sigma_noise); + + // Show target image + ij.ImageJ.main(args); + final ImagePlus imp = ImageJFunctions.wrap(img, "Target"); + imp.show(); + imp.resetDisplayRange(); + imp.updateAndDraw(); + + final Overlay overlay = new Overlay(); + imp.setOverlay(overlay); + + // Instantiate fitter once +// PeakFitter fitter = new PeakFitter(img, peaks, +// new DummySolver(), new Gaussian(), new MLGaussianEstimator(2d, 2)); + PeakFitter fitter = new PeakFitter(img, peaks, + new LevenbergMarquardtSolver(), new Gaussian(), new MLGaussianEstimator(2d, 2)); + + System.out.println(fitter); + if ( !fitter.checkInput() || !fitter.process()) { + System.err.println("Problem with peak fitting: " + fitter.getErrorMessage()); + return; + } + System.out.println("Peak fitting of " + (nspots*nspots) + " peaks, using " + + fitter.getNumThreads() + " threads, done in " + fitter.getProcessingTime() + " ms."); + + Map results = fitter.getResult(); + + for (Localizable peak : peaks) { + double[] params = results.get(peak); + + double Ar = params[2]; + double x = params[0]; + double y = params[1]; + double s = 1/Math.sqrt(params[3]); + + System.out.println(String.format("- For " + peak + "\n - Found : " + + "A = %6.2f, x0 = %6.2f, y0 = %6.2f, s = %5.2f", + Ar, x, y, s)); + double[] truth = groundTruth.get(peak); + System.out.println(String.format(" - Real values: " + + "A = %6.2f, x0 = %6.2f, y0 = %6.2f, s = %5.2f", + truth[2], truth[0], truth[1], 1 / Math.sqrt(truth[3])) ); + + // Draw ellipse on the target image + double x1, x2, y1, y2, ar; + x1 = x - 2.3548 * s / 2 + 0.5; + x2 = x + 2.3548 * s / 2 + 0.5; + y1 = y + 0.5; + y2 = y + 0.5; + ar = 1; + overlay.add(new EllipseRoi(x1, y1, x2, y2, ar)); + imp.updateAndDraw(); + + } + + } +} diff --git a/src/test/java/net/imglib2/algorithm/localization/GaussianFitTestDrive1.java b/src/test/java/net/imglib2/algorithm/localization/GaussianFitTestDrive1.java new file mode 100644 index 0000000..3fc5e58 --- /dev/null +++ b/src/test/java/net/imglib2/algorithm/localization/GaussianFitTestDrive1.java @@ -0,0 +1,147 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ +package net.imglib2.algorithm.localization; + +import ij.ImagePlus; +import ij.gui.EllipseRoi; +import ij.gui.Overlay; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Random; + +import net.imglib2.Localizable; +import net.imglib2.Point; +import net.imglib2.img.array.ArrayImg; +import net.imglib2.img.array.ArrayImgs; +import net.imglib2.img.basictypeaccess.array.ByteArray; +import net.imglib2.img.display.imagej.ImageJFunctions; +import net.imglib2.type.numeric.integer.UnsignedByteType; + +public class GaussianFitTestDrive1 { + + public static void main(String[] args) { + + int width = 100; + int height = 100; + double sigma_noise = 5; + final int nspots = 10; + + System.out.println("Preparing image"); + long[] dimensions = new long[] { width, height }; + ArrayImg img = ArrayImgs.unsignedBytes(dimensions); + + Random rangen = new Random(); + Collection peaks = new HashSet(nspots); + Map groundTruth = new HashMap(nspots); + + for (int i = 0; i < nspots; i++) { + + for (int j = 0; j < nspots; j++) { + + double A = 100 + 10 * rangen.nextGaussian(); + double x0 = width / (double) nspots * i * 1.02d; + double y0 = width / (double) nspots * j * 1.02d; + double sigma_x = 2 + 0.6 * rangen.nextGaussian(); + double sigma_y = 2 + 0.6 * rangen.nextGaussian(); + + Localizable peak = new Point((long) x0, (long) y0); + peaks.add(peak); + + double[] params = new double[] { x0, y0, A, 1/sigma_x/sigma_x, 1/sigma_y/sigma_y }; + LocalizationUtils.addEllipticGaussianSpotToImage(img, params); + groundTruth.put(peak, params); + + } + } + LocalizationUtils.addGaussianNoiseToImage(img, sigma_noise); + + // Show target image + ij.ImageJ.main(args); + final ImagePlus imp = ImageJFunctions.wrap(img, "Target"); + imp.show(); + imp.resetDisplayRange(); + imp.updateAndDraw(); + + final Overlay overlay = new Overlay(); + imp.setOverlay(overlay); + + // Instantiate fitter once + PeakFitter fitter = new PeakFitter(img, peaks, + new LevenbergMarquardtSolver(), new EllipticGaussianOrtho(), new MLEllipticGaussianEstimator(new double[] { 2d, 2d})); + + System.out.println(fitter); + if ( !fitter.checkInput() || !fitter.process()) { + System.err.println("Problem with peak fitting: " + fitter.getErrorMessage()); + return; + } + + System.out.println("Peak fitting of " + (nspots*nspots) + " peaks, using " + + fitter.getNumThreads() + " threads, done in " + fitter.getProcessingTime() + " ms."); + + Map results = fitter.getResult(); + + for (Localizable peak : peaks) { + double[] params = results.get(peak); + + double Ar = params[2]; + double x = params[0]; + double y = params[1]; + double sx = 1/Math.sqrt(params[3]); + double sy = 1/Math.sqrt(params[4]); + + System.out.println(String.format("- For " + peak + "\n - Found : " + + "A = %6.2f, x0 = %6.2f, y0 = %6.2f, sx = %5.2f, sy = %5.2f", + Ar, x, y, sx, sy)); + double[] truth = groundTruth.get(peak); + System.out.println(String.format(" - Real values: " + + "A = %6.2f, x0 = %6.2f, y0 = %6.2f, sx = %5.2f, sy = %5.2f", + truth[2], truth[0], truth[1], 1 / Math.sqrt(truth[3]), 1 / Math.sqrt(truth[4]) )); + + // Draw ellipse on the target image + double x1, x2, y1, y2, ar; + if (sy < sx) { + x1 = x - 2.3548 * sx / 2 + 0.5; + x2 = x + 2.3548 * sx / 2 + 0.5; + y1 = y + 0.5; + y2 = y + 0.5; + ar = sy / sx; + } else { + x1 = x + 0.5; + x2 = x + 0.5; + y1 = y - 2.3548 * sy / 2 + 0.5; + y2 = y + 2.3548 * sy / 2 + 0.5; + ar = sx / sy; + } + overlay.add(new EllipseRoi(x1, y1, x2, y2, ar)); + imp.updateAndDraw(); + + } + + } +} diff --git a/src/test/java/net/imglib2/algorithm/pde/AnisotropicDiffusion3DExample.java b/src/test/java/net/imglib2/algorithm/pde/AnisotropicDiffusion3DExample.java new file mode 100644 index 0000000..228c0ee --- /dev/null +++ b/src/test/java/net/imglib2/algorithm/pde/AnisotropicDiffusion3DExample.java @@ -0,0 +1,186 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ +package net.imglib2.algorithm.pde; + +import ij.ImageJ; +import ij.ImagePlus; +import ij.gui.ImageWindow; + +import java.io.File; + +import net.imglib2.Point; +import net.imglib2.algorithm.region.BresenhamLine; +import net.imglib2.exception.IncompatibleTypeException; +import net.imglib2.img.Img; +import net.imglib2.img.ImgFactory; +import net.imglib2.img.array.ArrayImgFactory; +import net.imglib2.img.display.imagej.ImageJFunctions; +import net.imglib2.io.ImgIOException; +import net.imglib2.io.ImgOpener; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.RealType; +import net.imglib2.type.numeric.integer.UnsignedByteType; +import net.imglib2.type.numeric.real.FloatType; +import net.imglib2.view.Views; + +public class AnisotropicDiffusion3DExample { + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static void main(String[] args) { + + Img image = createExampleImage(new UnsignedByteType()); + Img copy = image.copy(); + + // Display it via ImgLib using ImageJ + ImageJ.main(args); + + // Compute tensor + + MomentOfInertiaTensor3D tensor = new MomentOfInertiaTensor3D(image, 5); +// long[] dimensions = new long[image.numDimensions()]; +// image.dimensions(dimensions); +// IsotropicDiffusionTensor tensor = new IsotropicDiffusionTensor(dimensions , 1); + + tensor.process(); + Img diffusionTensor = tensor.getResult(); + + ImagePlus imp = ImageJFunctions.wrap(image, "Processed"); + imp.show(); + imp.getWindow().setLocation(100, 500); + + // Instantiate diffusion solver + +// StandardDiffusionScheme3D algo = new StandardDiffusionScheme3D(image, diffusionTensor); + NonNegativityDiffusionScheme3D algo = new NonNegativityDiffusionScheme3D(image, diffusionTensor); + + for (int i = 0; i < 1; i++) { + System.out.println("Iteration "+(i+1)); + // tensor.process(); + // diffusionTensor = tensor.getResult(); + // algo.setDiffusionTensor(diffusionTensor); + + algo.process(); + imp.updateAndDraw(); + } + + ImagePlus inc = ImageJFunctions.wrap(algo.getIncrement(), "Increment"); + inc.show(); + ImageWindow incWin = inc.getWindow(); + incWin.setLocation(500, 500); + inc.setSlice(inc.getStackSize()/2+1); + +// ImageJFunctions.wrapFloat(diffusionTensor, "Diffusion tensor").show(); + for (int i = 0; i < 6; i++) { + ImagePlus diffimp = ImageJFunctions.wrap(Views.hyperSlice(diffusionTensor, 3, i), "DT_"+i); + diffimp.show(); + ImageWindow win = diffimp.getWindow(); + win.setLocation(300 * (3 - ( i % 3) ), 300 * ( i/3 )); + diffimp.setSlice(diffimp.getStackSize()/2+1); + } + ImageJFunctions.show(copy, "Original image"); + } + + @SuppressWarnings("rawtypes") + public static & NativeType< T >> Img openExampleImage(T type) { + File file = new File( "/Users/tinevez/Desktop/Data/StarryNight.tif"); + + ImgFactory< ? > imgFactory = new ArrayImgFactory< T >(); + Img image = null; + try { + image = new ImgOpener().openImg( file.getAbsolutePath(), imgFactory ); + } catch (ImgIOException e) { + e.printStackTrace(); + } catch (IncompatibleTypeException e) { + e.printStackTrace(); + } + + return image; + } + + public static & NativeType< T >> Img createExampleImage(T type) { + + int size = 128; + double[] phis = new double[] { 0 , 45 , 90, 135 , 180 , 225 ,270, 315 }; + double[] thetas = new double[] { 0, 30, 60, 90, 120, 150, 180 }; + + final ImgFactory< T > imgFactory = new ArrayImgFactory(); + Img image = imgFactory.create(new int[] { size, size, size }, type); + + double phi, theta; + Point P1, P2; + long x1, x2, y1, y2, z1, z2; + BresenhamLine line = new BresenhamLine(image); + + for (int j = 0; j < thetas.length; j++) { + + theta = Math.toRadians(thetas[j]); + + for (int i = 0; i < phis.length; i++) { + + phi = Math.toRadians(phis[i]); + + x1 = Math.round (size/2 + size/10 * Math.cos(phi) * Math.sin(theta)); + x2 = Math.round (size/2 + (size/4 - 2) * Math.cos(phi) * Math.sin(theta)); + + y1 = Math.round (size/2 + size/10 * Math.sin(phi) * Math.sin(theta)); + y2 = Math.round (size/2 + (size/4 - 2) * Math.sin(phi) * Math.sin(theta)); + + z1 = Math.round (size/2 + size/10 * Math.cos(theta) ); + z2 = Math.round (size/2 + (size/4 - 2) * Math.cos(theta) ); + + P1 = new Point(x1, y1, z1); + P2 = new Point(x2, y2, z2); + line.reset(P1, P2); + + while (line.hasNext()) { + line.next().setReal(255); + } + + x1 = Math.round (size/2 + (size/4 + 1) * Math.cos(phi) * Math.sin(theta)); + x2 = Math.round (size/2 + (size/2 - 1) * Math.cos(phi) * Math.sin(theta)); + + y1 = Math.round (size/2 + (size/4 + 1) * Math.sin(phi) * Math.sin(theta)); + y2 = Math.round (size/2 + (size/2 - 1) * Math.sin(phi) * Math.sin(theta)); + + z1 = Math.round (size/2 + (size/4 + 1) * Math.cos(theta)); + z2 = Math.round (size/2 + (size/2 - 1) * Math.cos(theta)); + + P1 = new Point(x1, y1, z1); + P2 = new Point(x2, y2, z2); + line.reset(P1, P2); + + while (line.hasNext()) { + line.next().setReal(255); + } + + } + + } + + return image; + } + +} diff --git a/src/test/java/net/imglib2/algorithm/pde/AnisotropicDiffusionExample.java b/src/test/java/net/imglib2/algorithm/pde/AnisotropicDiffusionExample.java new file mode 100644 index 0000000..b19c37a --- /dev/null +++ b/src/test/java/net/imglib2/algorithm/pde/AnisotropicDiffusionExample.java @@ -0,0 +1,95 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ +package net.imglib2.algorithm.pde; + +import ij.ImageJ; +import ij.ImagePlus; + +import java.io.File; + +import net.imglib2.exception.IncompatibleTypeException; +import net.imglib2.img.Img; +import net.imglib2.img.ImgFactory; +import net.imglib2.img.array.ArrayImgFactory; +import net.imglib2.img.display.imagej.ImageJFunctions; +import net.imglib2.io.ImgIOException; +import net.imglib2.io.ImgOpener; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.RealType; +import net.imglib2.type.numeric.real.FloatType; + +public class AnisotropicDiffusionExample { + + public static & NativeType< T >> void main(String[] args) throws ImgIOException, IncompatibleTypeException { + + // Open file in imglib2 + // File file = new File( "E:/Users/JeanYves/Desktop/Data/Y.tif"); + File file = new File( "/Users/tinevez/Desktop/Data/sYn.tif"); +// File file = new File( "/Users/tinevez/Desktop/Data/StarryNight.tif"); +// File file = new File( "/Users/tinevez/Desktop/Data/cross2.tif"); + + ImgFactory< ? > imgFactory = new ArrayImgFactory< T >(); + + Img< T > image = new ImgOpener().openImg( file.getAbsolutePath(), imgFactory ); + Img copy = image.copy(); + + // Display it via ImgLib using ImageJ + new ImageJ(); + + // Compute tensor + + MomentOfInertiaTensor2D tensor = new MomentOfInertiaTensor2D(image, 9); +// CoherenceEnhancingDiffusionTensor2D tensor = new CoherenceEnhancingDiffusionTensor2D(image); + + + tensor.process(); + Img diffusionTensor = tensor.getResult(); + + ImagePlus imp = ImageJFunctions.wrap(image, "source"); + imp.show(); + + // Instantiate diffusion solver + + NonNegativityDiffusionScheme2D algo = new NonNegativityDiffusionScheme2D(image, diffusionTensor); +// StandardDiffusionScheme2D algo = new StandardDiffusionScheme2D(image, diffusionTensor); + + for (int i = 0; i < 20; i++) { + System.out.println("Iteration "+i); +// tensor.process(); +// diffusionTensor = tensor.getResult(); +// algo.setDiffusionTensor(diffusionTensor); + + algo.process(); + imp.getProcessor().setPixels(ImageJFunctions.wrap(image, "result").getProcessor().getPixelsCopy()); + imp.updateAndDraw(); + } + + // ImageJFunctions.show(algo.getIncrement()); + ImageJFunctions.show(diffusionTensor); + ImageJFunctions.show(copy); + } + +} diff --git a/src/test/java/net/imglib2/algorithm/pde/PeronaMalikAnisotropicDiffusionExample.java b/src/test/java/net/imglib2/algorithm/pde/PeronaMalikAnisotropicDiffusionExample.java new file mode 100644 index 0000000..2d67ffe --- /dev/null +++ b/src/test/java/net/imglib2/algorithm/pde/PeronaMalikAnisotropicDiffusionExample.java @@ -0,0 +1,75 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package net.imglib2.algorithm.pde; + +import ij.IJ; +import ij.ImagePlus; + +import java.net.MalformedURLException; +import java.net.URISyntaxException; + +import net.imglib2.exception.IncompatibleTypeException; +import net.imglib2.img.Img; +import net.imglib2.img.display.imagej.ImageJFunctions; +import net.imglib2.io.ImgIOException; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.RealType; + +public class PeronaMalikAnisotropicDiffusionExample { + + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static & NativeType< T >> void main(String[] args) throws InterruptedException, URISyntaxException, MalformedURLException, ImgIOException, IncompatibleTypeException { + + ij.ImageJ.main(args); + ImagePlus imp = IJ.openImage("http://rsb.info.nih.gov/ij/images/boats.gif"); + imp.show(); + + Img source = ImageJFunctions.wrap(imp); + +// PeronaMalikAnisotropicDiffusion algo = new PeronaMalikAnisotropicDiffusion(source, 0.15, 20); + PeronaMalikAnisotropicDiffusion algo = new PeronaMalikAnisotropicDiffusion(source, 0.15, + new PeronaMalikAnisotropicDiffusion.WideRegionEnhancer(20)); + algo.setNumThreads(); + + if (!algo.checkInput()) { + System.out.println("Check input failed! With: "+algo.getErrorMessage()); + return; + } + + + int niter = 20; + for (int i = 0; i < niter; i++) { + System.out.println("Iteration "+(i+1)+" of "+niter+"."); + algo.process(); + imp.updateAndDraw(); + } + + System.out.println("Done in "+algo.getProcessingTime()+" ms."); + + } +} diff --git a/src/test/java/net/imglib2/algorithm/region/BresenhamLineExample.java b/src/test/java/net/imglib2/algorithm/region/BresenhamLineExample.java new file mode 100644 index 0000000..b2a83b6 --- /dev/null +++ b/src/test/java/net/imglib2/algorithm/region/BresenhamLineExample.java @@ -0,0 +1,90 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package net.imglib2.algorithm.region; + +import net.imglib2.Point; +import net.imglib2.img.Img; +import net.imglib2.img.ImgFactory; +import net.imglib2.img.array.ArrayImgFactory; +import net.imglib2.img.display.imagej.ImageJFunctions; +import net.imglib2.type.numeric.integer.UnsignedByteType; + +public class BresenhamLineExample { + + public static void main(String[] args) { + + int size = 256; + double[] angles = new double[] { 0 , 45 , 90, 135 , 180 , 225 , 270, 315 }; + + final ImgFactory< UnsignedByteType > imgFactory = new ArrayImgFactory(); + Img image = imgFactory.create(new int[] { size, size }, new UnsignedByteType()); + + double angle; + Point P1, P2; + long x1, x2, y1, y2; + BresenhamLine line = new BresenhamLine(image); + + for (int i = 0; i < angles.length; i++) { + + angle = Math.toRadians(angles[i]); + + x1 = Math.round (size/2 + size/10 * Math.cos(angle)); + x2 = Math.round (size/2 + (size/4 - 2) * Math.cos(angle)); + + y1 = Math.round (size/2 + size/10 * Math.sin(angle)); + y2 = Math.round (size/2 + (size/4 - 2) * Math.sin(angle)); + + P1 = new Point(x1, y1); + P2 = new Point(x2, y2); + line.reset(P1, P2); + + while (line.hasNext()) { + line.next().set(200); + } + + x1 = Math.round (size/2 + (size/4 + 1) * Math.cos(angle)); + x2 = Math.round (size/2 + (size/2 - 1) * Math.cos(angle)); + + y1 = Math.round (size/2 + (size/4 + 1) * Math.sin(angle)); + y2 = Math.round (size/2 + (size/2 - 1) * Math.sin(angle)); + + P1 = new Point(x1, y1); + P2 = new Point(x2, y2); + line.reset(P1, P2); + + while (line.hasNext()) { + line.next().set(200); + } + + + } + + + ImageJFunctions.show(image); + } + +} diff --git a/src/test/java/net/imglib2/algorithm/region/localneighborhood/EllipsoidNeighborhoodExample.java b/src/test/java/net/imglib2/algorithm/region/localneighborhood/EllipsoidNeighborhoodExample.java new file mode 100644 index 0000000..f2f2abb --- /dev/null +++ b/src/test/java/net/imglib2/algorithm/region/localneighborhood/EllipsoidNeighborhoodExample.java @@ -0,0 +1,154 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package net.imglib2.algorithm.region.localneighborhood; + +import ij.ImageJ; +import net.imglib2.img.Img; +import net.imglib2.img.ImgFactory; +import net.imglib2.img.array.ArrayImgFactory; +import net.imglib2.img.display.imagej.ImageJFunctions; +import net.imglib2.type.numeric.integer.UnsignedByteType; +import net.imglib2.type.numeric.integer.UnsignedShortType; +import net.imglib2.util.Util; + +public class EllipsoidNeighborhoodExample +{ + + private static final int DIM = 100; // also N points + + public static void main( String[] args ) + { + ImageJ.main( args ); + example1(); + example2(); + example3(); + testBounds(); + } + + public static void example2() + { + + final ImgFactory< UnsignedByteType > imgFactory = new ArrayImgFactory< UnsignedByteType >(); + Img< UnsignedByteType > image = imgFactory.create( new int[] { DIM, DIM, DIM }, new UnsignedByteType() ); + + long[] center = new long[ 3 ]; + long[] span = new long[ 3 ]; + + for ( int i = 0; i < DIM; i++ ) + { + + center[ 0 ] = ( long ) ( Math.random() * DIM ); + center[ 1 ] = ( long ) ( Math.random() * DIM ); + center[ 2 ] = ( long ) ( Math.random() * DIM ); + + span[ 0 ] = ( long ) ( Math.random() / 10 * DIM ); + span[ 1 ] = ( long ) ( Math.random() / 10 * DIM ); + span[ 2 ] = ( long ) ( Math.random() / 10 * DIM ); + + EllipsoidNeighborhood< UnsignedByteType, Img< UnsignedByteType >> ellipsoid = new EllipsoidNeighborhood< UnsignedByteType, Img< UnsignedByteType >>( image, center, span ); + + System.out.println( "Center: " + Util.printCoordinates( center ) );// DEBUG + System.out.println( "Span: " + Util.printCoordinates( span ) );// DEBUG + + int val = ( int ) ( Math.random() * 200 ); + for ( UnsignedByteType pixel : ellipsoid ) + { + pixel.set( val ); + // val++; + } + + } + + ImageJFunctions.show( image ); + + } + + public static void example1() + { + final ImgFactory< UnsignedShortType > imgFactory = new ArrayImgFactory< UnsignedShortType >(); + Img< UnsignedShortType > image = imgFactory.create( new int[] { DIM, DIM, DIM }, new UnsignedShortType() ); + + long[] center = new long[] { 50, 50, 50 }; // the middle + long[] span = new long[] { 0, 10, 10 }; + + // Write into the image + EllipsoidNeighborhood< UnsignedShortType, Img< UnsignedShortType >> ellipsoid = new EllipsoidNeighborhood< UnsignedShortType, Img< UnsignedShortType >>( image, center, span ); + + int val = 250; + for ( UnsignedShortType pixel : ellipsoid ) + { + pixel.set( val ); + // val++; + } + + ImageJFunctions.show( image ); + } + + public static void example3() + { + final ImgFactory< UnsignedByteType > imgFactory = new ArrayImgFactory< UnsignedByteType >(); + Img< UnsignedByteType > image = imgFactory.create( new int[] { DIM, DIM, DIM }, new UnsignedByteType() ); + + long[][] centers = new long[][] { { 50, 50, 50 }, { 20, 20, 50 }, { 20, 70, 50 }, { 70, 70, 50 }, { 70, 20, 50 } + + }; + long[][] spans = new long[][] { { 20, 10, 15 }, { 20, 15, 1 }, { 1, 20, 15 }, { 20, 1, 15 }, { 20, 1, 1 } }; + + for ( int i = 0; i < spans.length; i++ ) + { + + EllipsoidNeighborhood< UnsignedByteType, Img< UnsignedByteType >> ellipsoid = new EllipsoidNeighborhood< UnsignedByteType, Img< UnsignedByteType > >( image, centers[i], spans[i] ); + + // Write into the image + int val = 200; + for ( UnsignedByteType pixel : ellipsoid ) + { + pixel.set( val ); + // val++; + } + } + + ImageJFunctions.show( image ); + } + + public static void testBounds() + { + + int sy = 1; + int sz = 7; + + int[] rys = new int[ sz + 1 ]; + + Utils.getXYEllipseBounds( sy, sz, rys ); + + for ( int i = 0; i < rys.length; i++ ) + { + System.out.println( i + ": " + rys[ i ] ); + } + } + +} diff --git a/src/test/java/net/imglib2/algorithm/region/localneighborhood/LocalMaximaBenchmark.java b/src/test/java/net/imglib2/algorithm/region/localneighborhood/LocalMaximaBenchmark.java new file mode 100644 index 0000000..da621d8 --- /dev/null +++ b/src/test/java/net/imglib2/algorithm/region/localneighborhood/LocalMaximaBenchmark.java @@ -0,0 +1,169 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package net.imglib2.algorithm.region.localneighborhood; + +import java.util.Random; + +import net.imglib2.Cursor; +import net.imglib2.RandomAccessibleInterval; +import net.imglib2.algorithm.region.localneighborhood.old.LocalNeighborhood; +import net.imglib2.algorithm.region.localneighborhood.old.LocalNeighborhood2; +import net.imglib2.algorithm.region.localneighborhood.old.LocalNeighborhoodCursor; +import net.imglib2.algorithm.region.localneighborhood.old.LocalNeighborhoodCursor2; +import net.imglib2.img.Img; +import net.imglib2.img.array.ArrayImgs; +import net.imglib2.type.Type; +import net.imglib2.type.numeric.real.FloatType; +import net.imglib2.util.BenchmarkHelper; +import net.imglib2.util.Intervals; +import net.imglib2.view.Views; + +public class LocalMaximaBenchmark +{ + public static < T extends Type< T > & Comparable< T > > int findLocalMaximaNeighborhood( final RandomAccessibleInterval< T > img ) + { + // final ArrayList< Point > maxima = new ArrayList< Point >(); + int nMaxima = 0; + + final Cursor< T > center = Views.iterable( Views.interval( img, Intervals.expand( img, -1 ) ) ).localizingCursor(); + final LocalNeighborhood< T > neighborhood = new LocalNeighborhood< T >( img, center ); + final LocalNeighborhoodCursor< T > nc = neighborhood.cursor(); + A: while ( center.hasNext() ) + { + final T t = center.next(); + nc.updateCenter( center ); + while ( nc.hasNext() ) + { + final T n = nc.next(); + if ( n.compareTo( t ) > 0 ) + continue A; + } + // maxima.add( new Point( center ) ); + ++nMaxima; + } + + return nMaxima; + } + + public static < T extends Type< T > & Comparable< T > > int findLocalMaximaNeighborhood2( final RandomAccessibleInterval< T > img ) + { + // final ArrayList< Point > maxima = new ArrayList< Point >(); + int nMaxima = 0; + + final Cursor< T > center = Views.iterable( Views.interval( img, Intervals.expand( img, -1 ) ) ).localizingCursor(); + final LocalNeighborhood2< T > neighborhood = new LocalNeighborhood2< T >( img, center ); + final LocalNeighborhoodCursor2< T > nc = neighborhood.cursor(); + A: while ( center.hasNext() ) + { + final T t = center.next(); + neighborhood.updateCenter( center ); + nc.reset(); + while ( nc.hasNext() ) + { + final T n = nc.next(); + if ( n.compareTo( t ) > 0 ) + continue A; + } + // maxima.add( new Point( center ) ); + ++nMaxima; + } + return nMaxima; + } + + public static < T extends Type< T > & Comparable< T > > int countLocalMaxima( final RandomAccessibleInterval< T > img, final Shape shape ) + { + int nMaxima = 0; + final RandomAccessibleInterval< T > source = Views.interval( img, Intervals.expand( img, -1 ) ); + final Cursor< T > center = Views.iterable( source ).cursor(); +A: for ( final Neighborhood< T > neighborhood : shape.neighborhoods( source ) ) + { + final T c = center.next(); + for ( final T t : neighborhood ) + if ( t.compareTo( c ) > 0 ) + continue A; + ++nMaxima; + } + return nMaxima; + } + + public static < T extends Type< T > & Comparable< T > > int findLocalMaximaNeighborhood6( final RandomAccessibleInterval< T > img ) + { + final RectangleShape neighborhoods = new RectangleShape( 1, true ); + return countLocalMaxima( img, neighborhoods ); + } + + public static void main( final String[] args ) + { + final int numRuns = 20; + final boolean printIndividualTimes = false; + final long[] dimensions = new long[] { 200, 200, 200 }; + final Img< FloatType > img = ArrayImgs.floats( dimensions ); + final Random random = new Random( 123914924 ); + for ( final FloatType t : img ) + t.set( random.nextFloat() ); + + System.out.println( "findLocalMaximaNeighborhood" ); + System.out.println( "(using old LocalNeighborhoodCursor)" ); + BenchmarkHelper.benchmarkAndPrint( numRuns, printIndividualTimes, new Runnable() + { + @Override + public void run() + { + findLocalMaximaNeighborhood( img ); + } + } ); + + System.out.println( "findLocalMaximaNeighborhood2" ); + System.out.println( "(using LocalNeighborhoodCursor2 by Bene and Tobias)" ); + BenchmarkHelper.benchmarkAndPrint( numRuns, printIndividualTimes, new Runnable() + { + @Override + public void run() + { + findLocalMaximaNeighborhood2( img ); + } + } ); + + System.out.println( "findLocalMaximaNeighborhood6" ); + System.out.println( "(using RectangleShape)" ); + BenchmarkHelper.benchmarkAndPrint( numRuns, printIndividualTimes, new Runnable() + { + @Override + public void run() + { + findLocalMaximaNeighborhood6( img ); + } + } ); + + final int n = findLocalMaximaNeighborhood( img ); + System.out.println( n ); + final int n2 = findLocalMaximaNeighborhood2( img ); + System.out.println( n2 ); + final int n6 = findLocalMaximaNeighborhood6( img ); + System.out.println( n6 ); + } +} diff --git a/src/test/java/net/imglib2/algorithm/region/localneighborhood/MinFilterExample.java b/src/test/java/net/imglib2/algorithm/region/localneighborhood/MinFilterExample.java new file mode 100644 index 0000000..17f5903 --- /dev/null +++ b/src/test/java/net/imglib2/algorithm/region/localneighborhood/MinFilterExample.java @@ -0,0 +1,81 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package net.imglib2.algorithm.region.localneighborhood; + +import net.imglib2.Interval; +import net.imglib2.RandomAccess; +import net.imglib2.RandomAccessibleInterval; +import net.imglib2.img.Img; +import net.imglib2.img.array.ArrayImgFactory; +import net.imglib2.img.display.imagej.ImageJFunctions; +import net.imglib2.io.ImgIOException; +import net.imglib2.io.ImgOpener; +import net.imglib2.type.Type; +import net.imglib2.type.numeric.real.FloatType; +import net.imglib2.util.Intervals; +import net.imglib2.view.Views; + +public class MinFilterExample +{ + + public static < T extends Type< T > & Comparable< T > > + void minFilter( final RandomAccessibleInterval< T > input, final RandomAccessibleInterval< T > output, final Shape shape ) + { + final RandomAccess< T > out = output.randomAccess(); + for ( final Neighborhood< T > neighborhood : shape.neighborhoods( input ) ) + { + out.setPosition( neighborhood ); + final T o = out.get(); + o.set( neighborhood.firstElement() ); + for ( final T i : neighborhood ) + if ( i.compareTo( o ) < 0 ) + o.set( i ); + } + } + + public static void main( final String[] args ) throws ImgIOException + { + final String fn = "/home/tobias/workspace/data/DrosophilaWing.tif"; + final int span = 3; + + final ArrayImgFactory< FloatType > factory = new ArrayImgFactory< FloatType >(); + final FloatType type = new FloatType(); + final Img< FloatType > imgInput = new ImgOpener().openImg( fn, factory, type ); + final Img< FloatType > imgOutput = factory.create( imgInput, type ); + + final Interval computationInterval = Intervals.expand( imgInput, -span ); + final RandomAccessibleInterval< FloatType > input = Views.interval( imgInput, computationInterval ); + final RandomAccessibleInterval< FloatType > output = Views.interval( imgOutput, computationInterval ); + + minFilter( input, output, new RectangleShape( span, false ) ); +// minFilter( input, output, new HyperSphereShape( span ) ); + + ImageJFunctions.show( imgInput, "input" ); + ImageJFunctions.show( imgOutput, "min filtered" ); + } + +} diff --git a/src/test/java/net/imglib2/algorithm/region/localneighborhood/ShowCoordinates2D.java b/src/test/java/net/imglib2/algorithm/region/localneighborhood/ShowCoordinates2D.java new file mode 100644 index 0000000..0dfc6d6 --- /dev/null +++ b/src/test/java/net/imglib2/algorithm/region/localneighborhood/ShowCoordinates2D.java @@ -0,0 +1,112 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package net.imglib2.algorithm.region.localneighborhood; + +import net.imglib2.Cursor; +import net.imglib2.Interval; +import net.imglib2.Localizable; +import net.imglib2.Point; +import net.imglib2.img.Img; +import net.imglib2.img.ImgFactory; +import net.imglib2.img.list.ListImgFactory; +import net.imglib2.type.Type; +import net.imglib2.util.Intervals; +import net.imglib2.view.Views; + +/** + * Helper class to debug neighborhoods. + * + * @author Tobias Pietzsch + */ +public class ShowCoordinates2D +{ + public static class CoordinateType extends Point implements Type< CoordinateType > + { + public CoordinateType( final Localizable l ) + { + super( l ); + } + + public CoordinateType( final int n ) + { + super( n ); + } + + public CoordinateType( final long... position ) + { + super( position ); + } + + @Override + public CoordinateType createVariable() + { + return new CoordinateType( numDimensions() ); + } + + @Override + public CoordinateType copy() + { + return new CoordinateType( this ); + } + + @Override + public void set( final CoordinateType c ) + { + setPosition( c ); + } + } + + public static void main( final String[] args ) + { + final int n = 2; + final long[] dimensions = new long[] { 5, 5 }; + final ImgFactory< CoordinateType > f = new ListImgFactory< CoordinateType >(); + final CoordinateType type = new CoordinateType( n ); + final Img< CoordinateType > img = f.create( dimensions, type ); + final Cursor< CoordinateType > c = img.localizingCursor(); + while ( c.hasNext() ) + c.next().setPosition( c ); + // c.reset(); + // while ( c.hasNext() ) + // System.out.println( c.next() ); + +// final Point center = new Point( 2l, 2l ); +// final LocalNeighborhood2< CoordinateType > neighborhood = new LocalNeighborhood2< CoordinateType >( img, center ); +// final Cursor< CoordinateType > nc = neighborhood.cursor(); +// while ( nc.hasNext() ) +// System.out.println( nc.next() ); + + final Interval span = Intervals.createMinMax( -1, -1, 1, 1 ); + final Cursor< Neighborhood< CoordinateType > > n3 = new RectangleNeighborhoodCursor< CoordinateType >( Views.interval( img, Intervals.expand( img, -1 ) ), span, RectangleNeighborhoodSkipCenter.< CoordinateType >factory() ); + while ( n3.hasNext() ) + { + for ( final CoordinateType t : n3.next() ) + System.out.println( t ); + System.out.println( "-----" ); + } + } +} diff --git a/src/test/java/net/imglib2/img/sparse/ExampleQuadtree.java b/src/test/java/net/imglib2/img/sparse/ExampleQuadtree.java new file mode 100644 index 0000000..fbfadc9 --- /dev/null +++ b/src/test/java/net/imglib2/img/sparse/ExampleQuadtree.java @@ -0,0 +1,88 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package net.imglib2.img.sparse; + +import ij.ImageJ; +import net.imglib2.Cursor; +import net.imglib2.RandomAccess; +import net.imglib2.img.Img; +import net.imglib2.img.ImgFactory; +import net.imglib2.img.array.ArrayImgFactory; +import net.imglib2.img.display.imagej.ImageJFunctions; +import net.imglib2.io.ImgOpener; +import net.imglib2.type.numeric.integer.IntType; + +public class ExampleQuadtree +{ + final static public void main( final String[] args ) + { + new ImageJ(); + + Img< IntType > array = null; + final ImgFactory< IntType > arrayFactory = new ArrayImgFactory< IntType >(); + try + { + final ImgOpener io = new ImgOpener(); + array = io.openImg( "/home/tobias/workspace/data/quadtree.tif", arrayFactory, new IntType() ); + } + catch ( final Exception e ) + { + e.printStackTrace(); + return; + } + + ImageJFunctions.show( array, "array" ); + + final NtreeImgFactory< IntType > ntreeFactory = new NtreeImgFactory< IntType >(); + final Img< IntType > quadtree = ntreeFactory.create( array, new IntType() ); + + // copy to sparse img + final Cursor< IntType > dst = quadtree.localizingCursor(); + final RandomAccess< IntType > src = array.randomAccess(); + while( dst.hasNext() ) + { + dst.fwd(); + src.setPosition( dst ); + dst.get().set( src.get() ); + } + /* + final RandomAccess< IntType > dst = quadtree.randomAccess(); + final Cursor< IntType > src = array.localizingCursor(); + while( src.hasNext() ) + { + src.fwd(); + dst.setPosition( src ); + dst.get().set( src.get() ); + } + */ + + ImageJFunctions.show( quadtree, "quadtree" ); + + System.out.println( "done" ); + } + +} diff --git a/src/test/java/net/imglib2/view/CopyViews.java b/src/test/java/net/imglib2/view/CopyViews.java new file mode 100644 index 0000000..d5bdfca --- /dev/null +++ b/src/test/java/net/imglib2/view/CopyViews.java @@ -0,0 +1,126 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package net.imglib2.view; + +import ij.ImageJ; +import net.imglib2.RandomAccess; +import net.imglib2.RandomAccessible; +import net.imglib2.RandomAccessibleInterval; +import net.imglib2.img.Img; +import net.imglib2.img.ImgFactory; +import net.imglib2.img.array.ArrayImgFactory; +import net.imglib2.img.display.imagej.ImageJFunctions; +import net.imglib2.io.ImgOpener; +import net.imglib2.type.Type; +import net.imglib2.type.numeric.real.FloatType; + +/** + * TODO + * + */ +public class CopyViews +{ + public static < T extends Type< T > > void copy( RandomAccessible< T > src, RandomAccessibleInterval< T > dst ) + { + final RandomAccessibleIntervalCursor< T > dstCursor = new RandomAccessibleIntervalCursor< T >( dst ); + final RandomAccess< T > srcAccess = src.randomAccess( dst ); + while ( dstCursor.hasNext() ) + { + dstCursor.fwd(); + srcAccess.setPosition( dstCursor ); + dstCursor.get().set( srcAccess.get() ); + } + } + + public static < T extends Type< T > > void copySrc( RandomAccessibleInterval< T > src, RandomAccessible< T > dst ) + { + final RandomAccessibleIntervalCursor< T > srcCursor = new RandomAccessibleIntervalCursor< T >( src ); + final RandomAccess< T > dstAccess = dst.randomAccess( src ); + while ( srcCursor.hasNext() ) + { + srcCursor.fwd(); + dstAccess.setPosition( srcCursor ); + dstAccess.get().set( srcCursor.get() ); + } + } + + final static public void main( final String[] args ) + { + new ImageJ(); + ImgFactory< FloatType > imgFactory = new ArrayImgFactory< FloatType >(); + + Img< FloatType > inputImg = null; + try + { + final ImgOpener io = new ImgOpener(); + inputImg = io.openImg( "/home/tobias/workspace/data/wingclip.tif", imgFactory, new FloatType() ); + //inputImg = io.openImg( ImgIOUtils.cacheId( "http://www.wv.inf.tu-dresden.de/~tobias/wingclip.tif" ), imgFactory, new FloatType() ); + } + catch ( Exception e ) + { + e.printStackTrace(); + return; + } + + final long w = inputImg.dimension( 0 ); + final long h = inputImg.dimension( 1 ); + + final long[] dim = new long[] { w * 2, h * 2 }; + Img< FloatType > outputImg = imgFactory.create( dim, new FloatType() ); + + copy( inputImg, Views.superIntervalView( outputImg, new long[] {0,0}, new long[] {w,h} ) ); + copy( Views.flippedView( inputImg, 0 ), Views.superIntervalView( outputImg, new long[] {w,0}, new long[] {w,h} ) ); + copy( Views.flippedView( inputImg, 1 ), Views.superIntervalView( outputImg, new long[] {0,h}, new long[] {w,h} ) ); + copy( Views.flippedView( Views.flippedView( inputImg, 1 ), 0 ), Views.superIntervalView( outputImg, new long[] {w,h}, new long[] {w,h} ) ); + + ImageJFunctions.show( outputImg ); + +// final long w = inputImg.dimension( 0 ); +// final long h = inputImg.dimension( 1 ); +// +// final long[] dim = new long[] { w * 5, h * 5 }; +// Img< FloatType > outputImg = imgFactory.create( dim, new FloatType() ); +// +// copySrc( +// Views.interval( inputImg, new long[] {50,0}, new long[] {100, 100} ), +// Views.offsetInterval( outputImg, new long[] {2 * w, 2 * h}, new long[] {1, 1} ) ); +// copySrc( Views.rotate( +// Views.interval( inputImg, new long[] {50,0}, new long[] {100, 100} ), +// 0, 1 ), Views.offsetInterval( outputImg, new long[] {2 * w, 2 * h}, new long[] {1, 1} ) ); +// copySrc( Views.rotate( +// Views.interval( inputImg, new long[] {50,0}, new long[] {100, 100} ), +// 1, 0 ), Views.offsetInterval( outputImg, new long[] {2 * w, 2 * h}, new long[] {1, 1} ) ); + +// final ARGBScreenImage screenImage = new ARGBScreenImage( ( int )outputImg.dimension( 0 ), ( int )outputImg.dimension( 1 ) ); +// final XYProjector< FloatType, ARGBType > projector = new XYProjector< FloatType, ARGBType >( outputImg, screenImage, new RealARGBConverter< FloatType >( 0, 255 ) ); +// projector.map(); +// +// final ColorProcessor cp = new ColorProcessor( screenImage.image() ); +// final ImagePlus imp = new ImagePlus( "argbScreenProjection", cp ); +// imp.show(); + } +} diff --git a/src/test/java/net/imglib2/view/MixedTransformConcatenateTest.java b/src/test/java/net/imglib2/view/MixedTransformConcatenateTest.java new file mode 100644 index 0000000..34da90d --- /dev/null +++ b/src/test/java/net/imglib2/view/MixedTransformConcatenateTest.java @@ -0,0 +1,404 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package net.imglib2.view; + +import static org.junit.Assert.assertTrue; +import Jama.Matrix; +import net.imglib2.transform.integer.Mixed; +import net.imglib2.transform.integer.MixedTransform; +import net.imglib2.transform.integer.SlicingTransform; +import net.imglib2.transform.integer.TranslationTransform; + +import org.junit.Before; +import org.junit.Test; + +/** + * TODO + * + */ +public class MixedTransformConcatenateTest +{ + public static boolean testConcatenation( final MixedTransform t1, final Mixed t2 ) + { + if (t1.numSourceDimensions() != t2.numTargetDimensions() ) + { + System.out.println("incompatible dimensions"); + return false; + } + + final MixedTransform t1t2 = t1.concatenate( t2 ); + + final Matrix mt1 = new Matrix( t1.getMatrix() ); + final Matrix mt2 = new Matrix( t2.getMatrix() ); + final Matrix mt1t2 = new Matrix( t1t2.getMatrix() ); + + if ( mt1.times( mt2 ).minus( mt1t2 ).normF() > 0.1 ) { + System.out.println("======================="); + System.out.println("t1: " + t1.numSourceDimensions() + " -> " + t1.numTargetDimensions() + " (n -> m)" ); + System.out.println("t2: " + t2.numSourceDimensions() + " -> " + t2.numTargetDimensions() + " (n -> m)" ); + System.out.println("t1t2: " + t1t2.numSourceDimensions() + " -> " + t1t2.numTargetDimensions() + " (n -> m)" ); + + System.out.print( "t1 = " ); + mt1.print( 1, 0 ); + System.out.print( "t2 = " ); + mt2.print( 1, 0 ); + System.out.print( "t1t2 = " ); + mt1t2.print( 1, 0 ); + System.out.print( "t1 x t2 = " ); + mt1.times( mt2 ).print( 1, 0 ); + + System.out.println( "wrong result" ); + System.out.println("======================="); + return false; + } + + return true; + } + + public static boolean testPreConcatenation( final Mixed t1, final MixedTransform t2 ) + { + if (t1.numSourceDimensions() != t2.numTargetDimensions() ) + { + System.out.println("incompatible dimensions"); + return false; + } + + final MixedTransform t1t2 = t2.preConcatenate( t1 ); + + final Matrix mt1 = new Matrix( t1.getMatrix() ); + final Matrix mt2 = new Matrix( t2.getMatrix() ); + final Matrix mt1t2 = new Matrix( t1t2.getMatrix() ); + + if ( mt1.times( mt2 ).minus( mt1t2 ).normF() > 0.1 ) { + System.out.println("======================="); + System.out.println("t1: " + t1.numSourceDimensions() + " -> " + t1.numTargetDimensions() + " (n -> m)" ); + System.out.println("t2: " + t2.numSourceDimensions() + " -> " + t2.numTargetDimensions() + " (n -> m)" ); + System.out.println("t1t2: " + t1t2.numSourceDimensions() + " -> " + t1t2.numTargetDimensions() + " (n -> m)" ); + + System.out.print( "t1 = " ); + mt1.print( 1, 0 ); + System.out.print( "t2 = " ); + mt2.print( 1, 0 ); + System.out.print( "t1t2 = " ); + mt1t2.print( 1, 0 ); + System.out.print( "t1 x t2 = " ); + mt1.times( mt2 ).print( 1, 0 ); + + System.out.println( "wrong result" ); + System.out.println("======================="); + return false; + } + + return true; + } + + MixedTransform tr1; + MixedTransform tr2; + MixedTransform tr3; + MixedTransform perm1; + MixedTransform rot1; + MixedTransform proj1; + MixedTransform proj2; + MixedTransform comp1; + MixedTransform slice1; + TranslationTransform translation1; + SlicingTransform slicing1; + + @Before + public void setUp() + { + tr1 = new MixedTransform( 3, 3 ); + long[] translation = new long[] {3, 4, 5}; + tr1.setTranslation( translation ); + + tr2 = new MixedTransform( 3, 3 ); + translation = new long[] {7, 8, 9}; + tr2.setTranslation( translation ); + + perm1 = new MixedTransform( 3, 3 ); + boolean[] zero = new boolean[] {false, false, false}; + boolean[] inv = new boolean[] {false, false, false}; + int[] component = new int[] {0, 2, 1}; + perm1.setComponentZero( zero ); + perm1.setComponentMapping( component ); + perm1.setComponentInversion( inv ); + + rot1 = new MixedTransform( 3, 3 ); + zero = new boolean[] {false, false, false}; + inv = new boolean[] {false, true, false}; + component = new int[] {1, 0, 2}; + rot1.setComponentZero( zero ); + rot1.setComponentMapping( component ); + rot1.setComponentInversion( inv ); + + proj1 = new MixedTransform( 3, 2 ); + + proj2 = new MixedTransform( 2, 3 ); + + slice1 = new MixedTransform( 2, 3 ); + slice1.setTranslation( new long[] { 233, 0, 0 } ); + slice1.setComponentMapping( new int[] { 0, 0, 1 } ); + slice1.setComponentZero( new boolean[] { true, false, false } ); + + tr3 = new MixedTransform( 2, 2 ); + tr3.setTranslation( new long[] { 10, 10 } ); + + comp1 = rot1.concatenate( tr2 ); + + translation1 = new TranslationTransform( new long[] {2011, 3, 24} ); + + slicing1 = new SlicingTransform( 2, 3 ); + slicing1.setComponentMapping( new int[] { 0, 1, 0 } ); + slicing1.setComponentZero( new boolean[] { false, false, true } ); + slicing1.setTranslation( new long[] { 0, 0, 100 } ); + } + + @Test + public void concatenateSlice1Tr3() + { + assertTrue( testConcatenation( slice1, tr3 ) ); + } + + @Test + public void preconcatenateSlice1Tr3() + { + assertTrue( testPreConcatenation( slice1, tr3 ) ); + } + + @Test + public void concatenateProj1Tr1() + { + assertTrue( testConcatenation( proj1, tr1 ) ); + } + + @Test + public void preconcatenateProj1Tr1() + { + assertTrue( testPreConcatenation( proj1, tr1 ) ); + } + + @Test + public void concatenateTr11Tr2() + { + assertTrue( testConcatenation( tr1, tr2 ) ); + } + + @Test + public void preconcatenateTr1Tr2() + { + assertTrue( testPreConcatenation( tr1, tr2 ) ); + } + + @Test + public void concatenateTr1Perm1() + { + assertTrue( testConcatenation( tr1, perm1 ) ); + } + + @Test + public void preconcatenateTr1Perm1() + { + assertTrue( testPreConcatenation( tr1, perm1 ) ); + } + + @Test + public void concatenateTr1Rot1() + { + assertTrue( testConcatenation( tr1, rot1 ) ); + } + + @Test + public void preconcatenateTr1Rot1() + { + assertTrue( testPreConcatenation( tr1, rot1 ) ); + } + + @Test + public void concatenateRot1Tr1() + { + assertTrue( testConcatenation( rot1, tr1 ) ); + } + + @Test + public void preconcatenateRot1Tr1() + { + assertTrue( testPreConcatenation( rot1, tr1 ) ); + } + + @Test + public void concatenateProj1Proj2() + { + assertTrue( testConcatenation( proj1, proj2 ) ); + } + + @Test + public void preconcatenateProj1Proj2() + { + assertTrue( testPreConcatenation( proj1, proj2 ) ); + } + + @Test + public void concatenateProj2Proj1() + { + assertTrue( testConcatenation( proj2, proj1 ) ); + } + + @Test + public void preconcatenateProj2Proj1() + { + assertTrue( testPreConcatenation( proj2, proj1 ) ); + } + + @Test + public void concatenateComp1Tr1() + { + assertTrue( testConcatenation( comp1, tr1 ) ); + } + + @Test + public void preconcatenateComp1Tr1() + { + assertTrue( testPreConcatenation( comp1, tr1 ) ); + } + + @Test + public void concatenateTr1Comp1() + { + assertTrue( testConcatenation( tr1, comp1 ) ); + } + + @Test + public void preconcatenateTr1Comp1() + { + assertTrue( testPreConcatenation( tr1, comp1 ) ); + } + + @Test + public void concatenateComp1Rot1() + { + assertTrue( testConcatenation( comp1, rot1 ) ); + } + + @Test + public void preconcatenateComp1Rot1() + { + assertTrue( testPreConcatenation( comp1, rot1 ) ); + } + + @Test + public void concatenateRot1Comp1() + { + assertTrue( testConcatenation( rot1, comp1 ) ); + } + + @Test + public void preconcatenateRot1Comp1() + { + assertTrue( testPreConcatenation( rot1, comp1 ) ); + } + + @Test + public void concatenateProj1Comp1() + { + assertTrue( testConcatenation( proj1, comp1 ) ); + } + + @Test + public void preconcatenateProj1Comp1() + { + assertTrue( testPreConcatenation( proj1, comp1 ) ); + } + + @Test + public void concatenateComp1Proj2() + { + assertTrue( testConcatenation( comp1, proj2 ) ); + } + + @Test + public void preconcatenateComp1Proj2() + { + assertTrue( testPreConcatenation( comp1, proj2 ) ); + } + + @Test + public void concatenateComp1Translation1() + { + assertTrue( testConcatenation( comp1, translation1 ) ); + } + + @Test + public void preconcatenateTranslation1Comp1() + { + assertTrue( testPreConcatenation( translation1, comp1 ) ); + } + + @Test + public void concatenateComp1Slicing1() + { + assertTrue( testConcatenation( comp1, slicing1 ) ); + } + + public static void main( final String[] args ) + { + final MixedTransformConcatenateTest test = new MixedTransformConcatenateTest(); + test.setUp(); + + final Matrix m_tr1 = new Matrix( test.tr1.getMatrix() ); + final Matrix m_tr2 = new Matrix( test.tr2.getMatrix() ); + final Matrix m_perm1 = new Matrix( test.perm1.getMatrix() ); + final Matrix m_rot1 = new Matrix( test.rot1.getMatrix() ); + final Matrix m_proj1 = new Matrix( test.proj1.getMatrix() ); + final Matrix m_proj2 = new Matrix( test.proj2.getMatrix() ); + final Matrix m_comp1 = new Matrix( test.comp1.getMatrix() ); + final Matrix m_slicing1 = new Matrix( test.slicing1.getMatrix() ); + + System.out.print( "tr1 = " ); + m_tr1.print( 1, 0 ); + + System.out.print( "tr2 = " ); + m_tr2.print( 1, 0 ); + + System.out.print( "perm1 = " ); + m_perm1.print( 1, 0 ); + + System.out.print( "rot1 = " ); + m_rot1.print( 1, 0 ); + + System.out.print( "proj1 = " ); + m_proj1.print( 1, 0 ); + + System.out.print( "proj2 = " ); + m_proj2.print( 1, 0 ); + + System.out.print( "comp1 = " ); + m_comp1.print( 1, 0 ); + + System.out.print( "m_slicing1 = " ); + m_slicing1.print( 1, 0 ); + } +} diff --git a/src/test/java/net/imglib2/view/OpenAndDisplayInterpolated.java b/src/test/java/net/imglib2/view/OpenAndDisplayInterpolated.java new file mode 100644 index 0000000..da9e0db --- /dev/null +++ b/src/test/java/net/imglib2/view/OpenAndDisplayInterpolated.java @@ -0,0 +1,119 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package net.imglib2.view; + +import ij.ImageJ; +import ij.ImagePlus; +import net.imglib2.Cursor; +import net.imglib2.IterableInterval; +import net.imglib2.RandomAccessible; +import net.imglib2.RealRandomAccess; +import net.imglib2.img.Img; +import net.imglib2.img.ImgFactory; +import net.imglib2.img.array.ArrayImgFactory; +import net.imglib2.img.display.imagej.ImageJFunctions; +import net.imglib2.interpolation.InterpolatorFactory; +import net.imglib2.interpolation.randomaccess.NLinearInterpolatorFactory; +import net.imglib2.interpolation.randomaccess.NearestNeighborInterpolatorFactory; +import net.imglib2.io.ImgOpener; +import net.imglib2.type.numeric.NumericType; +import net.imglib2.type.numeric.real.FloatType; + +/** + * TODO + * + */ +public class OpenAndDisplayInterpolated +{ + public static > void copyInterpolatedGeneric( RandomAccessible< T > from, IterableInterval< T > to, double[] offset, double scale, InterpolatorFactory< T, RandomAccessible< T > > interpolatorFactory ) + { + final int n = to.numDimensions(); + final double[] fromPosition = new double[ n ]; + Cursor< T > cursor = to.localizingCursor(); + RealRandomAccess< T > interpolator = interpolatorFactory.create( from ); + while ( cursor.hasNext() ) + { + final T t = cursor.next(); + for ( int d = 0; d < n; ++d ) + { + fromPosition[ d ] = scale * cursor.getDoublePosition( d ) + offset[ d ]; + } + interpolator.setPosition( fromPosition ); + t.set( interpolator.get() ); + } + } + + final static public void main( final String[] args ) + { + new ImageJ(); + + ImgFactory< FloatType > imgFactory = new ArrayImgFactory< FloatType >(); + Img< FloatType > img = null; + try + { + final ImgOpener io = new ImgOpener(); + img = io.openImg( "/home/tobias/workspace/data/DrosophilaWing.tif", imgFactory, new FloatType() ); + } + catch ( Exception e ) + { + e.printStackTrace(); + return; + } + + Img< FloatType > interpolatedImg = imgFactory.create( new long[] {200, 200}, new FloatType () ); + + double[] offset; + double scale; + InterpolatorFactory< FloatType, RandomAccessible< FloatType > > interpolatorFactory; + + offset = new double[] {50, 10}; + scale = 1.0; + interpolatorFactory = new NLinearInterpolatorFactory< FloatType >(); + final ImagePlus imp = ImageJFunctions.show( interpolatedImg ); + imp.getImageStack().getProcessor( 0 ).setMinAndMax( 0, 255 ); + for ( int i=0; i<2000; ++i ) { + copyInterpolatedGeneric( img, interpolatedImg, offset, scale, interpolatorFactory ); + imp.getImageStack().getProcessor( 0 ); // update the internal img data in the underlying ImageJVirtualStack + imp.updateAndDraw(); + offset[0] += 0.2; + offset[0] += 0.04; + scale *= 0.999; + } + + offset = new double[] {50, 10}; + scale = 1.0; + interpolatorFactory = new NearestNeighborInterpolatorFactory< FloatType >(); + for ( int i=0; i<2000; ++i ) { + copyInterpolatedGeneric( img, interpolatedImg, offset, scale, interpolatorFactory ); + imp.getImageStack().getProcessor( 0 ); // update the internal img data in the underlying ImageJVirtualStack + imp.updateAndDraw(); + offset[0] += 0.2; + offset[0] += 0.04; + scale *= 0.999; + } + } +} diff --git a/src/test/java/net/imglib2/view/OpenAndDisplayRotated.java b/src/test/java/net/imglib2/view/OpenAndDisplayRotated.java new file mode 100644 index 0000000..0e68fbd --- /dev/null +++ b/src/test/java/net/imglib2/view/OpenAndDisplayRotated.java @@ -0,0 +1,82 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package net.imglib2.view; + +import ij.ImageJ; +import ij.ImagePlus; +import ij.process.ColorProcessor; +import net.imglib2.RandomAccessibleInterval; +import net.imglib2.display.ARGBScreenImage; +import net.imglib2.display.RealARGBConverter; +import net.imglib2.display.XYProjector; +import net.imglib2.img.array.ArrayImgFactory; +import net.imglib2.io.ImgIOException; +import net.imglib2.io.ImgOpener; +import net.imglib2.type.numeric.ARGBType; +import net.imglib2.type.numeric.real.FloatType; + +/** + * TODO + * + */ +public class OpenAndDisplayRotated +{ + final static public void main( final String[] args ) + throws ImgIOException +{ + new ImageJ(); + + final ImgOpener io = new ImgOpener(); + RandomAccessibleInterval< FloatType > img = Views.rotatedView( + io.openImg( "/home/tobias/workspace/data/73_float.tif", new ArrayImgFactory(), new FloatType()), + 0, 1 ); + + final ARGBScreenImage screenImage = new ARGBScreenImage( ( int )img.dimension( 0 ), ( int )img.dimension( 1 ) ); + final XYProjector< FloatType, ARGBType > projector = new XYProjector< FloatType, ARGBType >( img, screenImage, new RealARGBConverter< FloatType >( 0, 127 ) ); + + final ColorProcessor cp = new ColorProcessor( screenImage.image() ); + final ImagePlus imp = new ImagePlus( "argbScreenProjection", cp ); + imp.show(); + + // ImageJFunctions.show( img ); + + for ( int k = 0; k < 3; ++k ) + for ( int i = 0; i < img.dimension( 2 ); ++i ) + { + projector.setPosition( i, 2 ); + projector.map(); + final ColorProcessor cpa = new ColorProcessor( screenImage.image() ); + imp.setProcessor( cpa ); + imp.updateAndDraw(); + } + + projector.map(); + + projector.setPosition( 40, 2 ); + projector.map(); +} +} diff --git a/src/test/java/net/imglib2/view/OpenAndDisplaySliceView.java b/src/test/java/net/imglib2/view/OpenAndDisplaySliceView.java new file mode 100644 index 0000000..38e8bbc --- /dev/null +++ b/src/test/java/net/imglib2/view/OpenAndDisplaySliceView.java @@ -0,0 +1,65 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package net.imglib2.view; + +import ij.ImageJ; +import net.imglib2.RandomAccessibleInterval; +import net.imglib2.img.Img; +import net.imglib2.img.ImgFactory; +import net.imglib2.img.array.ArrayImgFactory; +import net.imglib2.img.display.imagej.ImageJFunctions; +import net.imglib2.io.ImgOpener; +import net.imglib2.type.numeric.real.FloatType; + +/** + * TODO + * + */ +public class OpenAndDisplaySliceView +{ + final static public void main( final String[] args ) + { + new ImageJ(); + + Img< FloatType > img = null; + try + { + final ImgFactory< FloatType > imgFactory = new ArrayImgFactory< FloatType >(); + final ImgOpener io = new ImgOpener(); + img = io.openImg( "/home/tobias/workspace/data/73_float.tif", imgFactory, new FloatType() ); + } + catch ( final Exception e ) + { + e.printStackTrace(); + return; + } + + final RandomAccessibleInterval< FloatType > view = Views.hyperSlice( img, 2, 10 ); + + ImageJFunctions.show( view ); + } +} diff --git a/src/test/java/net/imglib2/view/OpenAndDisplayView.java b/src/test/java/net/imglib2/view/OpenAndDisplayView.java new file mode 100644 index 0000000..522d787 --- /dev/null +++ b/src/test/java/net/imglib2/view/OpenAndDisplayView.java @@ -0,0 +1,73 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package net.imglib2.view; + +import ij.ImageJ; +import net.imglib2.RandomAccessible; +import net.imglib2.RandomAccessibleInterval; +import net.imglib2.img.Img; +import net.imglib2.img.ImgFactory; +import net.imglib2.img.array.ArrayImgFactory; +import net.imglib2.img.display.imagej.ImageJFunctions; +import net.imglib2.io.ImgOpener; +import net.imglib2.type.numeric.real.FloatType; + +/** + * TODO + * + */ +public class OpenAndDisplayView +{ + final static public void main( final String[] args ) + { + new ImageJ(); + + Img< FloatType > img = null; + try + { + ImgFactory< FloatType > imgFactory = new ArrayImgFactory< FloatType >(); + final ImgOpener io = new ImgOpener(); + img = io.openImg( "/home/tobias/workspace/data/wingclip.tif", imgFactory, new FloatType() ); + } + catch ( Exception e ) + { + e.printStackTrace(); + return; + } + + + RandomAccessible< FloatType > view1 = Views.extendMirrorSingle( img ); + RandomAccessibleInterval< FloatType > view2 = Views.offsetInterval( view1, new long[] {-20, -20}, new long[] {157, 157} ); + RandomAccessible< FloatType > view3 = Views.extendPeriodic( view2 ); + RandomAccessibleInterval< FloatType > view4 = Views.offsetInterval( view3, new long[] {-100, -100}, new long[] {357, 357} ); + RandomAccessibleInterval< FloatType > view5 = Views.offsetInterval( view4, new long[] {120, 120}, new long[] {117, 117} ); + + RandomAccessibleInterval< FloatType > finalView = view5; + + ImageJFunctions.show( finalView ); + } +} diff --git a/src/test/java/net/imglib2/view/SlicingTransformConcatenateTest.java b/src/test/java/net/imglib2/view/SlicingTransformConcatenateTest.java new file mode 100644 index 0000000..c8756a0 --- /dev/null +++ b/src/test/java/net/imglib2/view/SlicingTransformConcatenateTest.java @@ -0,0 +1,145 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package net.imglib2.view; + +import static org.junit.Assert.assertTrue; +import Jama.Matrix; +import net.imglib2.transform.integer.Slicing; +import net.imglib2.transform.integer.SlicingTransform; + +import org.junit.Before; +import org.junit.Test; + +/** + * TODO + * + */ +public class SlicingTransformConcatenateTest +{ + public static boolean testConcatenation( final SlicingTransform t1, final Slicing t2 ) + { + if (t1.numSourceDimensions() != t2.numTargetDimensions() ) + { + System.out.println("incompatible dimensions"); + return false; + } + + final SlicingTransform t1t2 = t1.concatenate( t2 ); + + final Matrix mt1 = new Matrix( t1.getMatrix() ); + final Matrix mt2 = new Matrix( t2.getMatrix() ); + final Matrix mt1t2 = new Matrix( t1t2.getMatrix() ); + + if ( mt1.times( mt2 ).minus( mt1t2 ).normF() > 0.1 ) { + System.out.println("======================="); + System.out.println("t1: " + t1.numSourceDimensions() + " -> " + t1.numTargetDimensions() + " (n -> m)" ); + System.out.println("t2: " + t2.numSourceDimensions() + " -> " + t2.numTargetDimensions() + " (n -> m)" ); + System.out.println("t1t2: " + t1t2.numSourceDimensions() + " -> " + t1t2.numTargetDimensions() + " (n -> m)" ); + + System.out.print( "t1 = " ); + mt1.print( 1, 0 ); + System.out.print( "t2 = " ); + mt2.print( 1, 0 ); + System.out.print( "t1t2 = " ); + mt1t2.print( 1, 0 ); + System.out.print( "t1 x t2 = " ); + mt1.times( mt2 ).print( 1, 0 ); + + System.out.println( "wrong result" ); + System.out.println("======================="); + return false; + } + + return true; + } + + public static boolean testPreConcatenation( final Slicing t1, final SlicingTransform t2 ) + { + if (t1.numSourceDimensions() != t2.numTargetDimensions() ) + { + System.out.println("incompatible dimensions"); + return false; + } + + final SlicingTransform t1t2 = t2.preConcatenate( t1 ); + + final Matrix mt1 = new Matrix( t1.getMatrix() ); + final Matrix mt2 = new Matrix( t2.getMatrix() ); + final Matrix mt1t2 = new Matrix( t1t2.getMatrix() ); + + if ( mt1.times( mt2 ).minus( mt1t2 ).normF() > 0.1 ) { + System.out.println("======================="); + System.out.println("t1: " + t1.numSourceDimensions() + " -> " + t1.numTargetDimensions() + " (n -> m)" ); + System.out.println("t2: " + t2.numSourceDimensions() + " -> " + t2.numTargetDimensions() + " (n -> m)" ); + System.out.println("t1t2: " + t1t2.numSourceDimensions() + " -> " + t1t2.numTargetDimensions() + " (n -> m)" ); + + System.out.print( "t1 = " ); + mt1.print( 1, 0 ); + System.out.print( "t2 = " ); + mt2.print( 1, 0 ); + System.out.print( "t1t2 = " ); + mt1t2.print( 1, 0 ); + System.out.print( "t1 x t2 = " ); + mt1.times( mt2 ).print( 1, 0 ); + + System.out.println( "wrong result" ); + System.out.println("======================="); + return false; + } + + return true; + } + + SlicingTransform sl1; + SlicingTransform sl2; + + @Before + public void setUp() + { + sl1 = new SlicingTransform( 2, 3 ); + sl1.setComponentMapping( new int[] { 0, 1, -9 } ); + sl1.setComponentZero( new boolean[] { false, false, true } ); + sl1.setTranslation( new long[] { 0, 0, 100 } ); + + sl2 = new SlicingTransform( 3, 4 ); + sl2.setComponentMapping( new int[] { -9, 0, 1, 2} ); + sl2.setComponentZero( new boolean[] { true, false, false, false } ); + sl2.setTranslation( new long[] { 1287, 0, 0, 0 } ); + } + + @Test + public void concatenateTr1Tr2() + { + assertTrue( testConcatenation( sl2, sl1 ) ); + } + + @Test + public void preconcatenateTr1Tr2() + { + assertTrue( testPreConcatenation( sl2, sl1 ) ); + } +} diff --git a/src/test/java/net/imglib2/view/TranslationTransformConcatenateTest.java b/src/test/java/net/imglib2/view/TranslationTransformConcatenateTest.java new file mode 100644 index 0000000..262871b --- /dev/null +++ b/src/test/java/net/imglib2/view/TranslationTransformConcatenateTest.java @@ -0,0 +1,153 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package net.imglib2.view; + +import static org.junit.Assert.assertTrue; +import Jama.Matrix; +import net.imglib2.transform.integer.Translation; +import net.imglib2.transform.integer.TranslationTransform; + +import org.junit.Before; +import org.junit.Test; + +/** + * TODO + * + */ +public class TranslationTransformConcatenateTest +{ + public static boolean testConcatenation( TranslationTransform t1, Translation t2 ) + { + if (t1.numSourceDimensions() != t2.numTargetDimensions() ) + { + System.out.println("incompatible dimensions"); + return false; + } + + TranslationTransform t1t2 = t1.concatenate( t2 ); + + Matrix mt1 = new Matrix( t1.getMatrix() ); + Matrix mt2 = new Matrix( t2.getMatrix() ); + Matrix mt1t2 = new Matrix( t1t2.getMatrix() ); + + if ( mt1.times( mt2 ).minus( mt1t2 ).normF() > 0.1 ) { + System.out.println("======================="); + System.out.println("t1: " + t1.numSourceDimensions() + " -> " + t1.numTargetDimensions() + " (n -> m)" ); + System.out.println("t2: " + t2.numSourceDimensions() + " -> " + t2.numTargetDimensions() + " (n -> m)" ); + System.out.println("t1t2: " + t1t2.numSourceDimensions() + " -> " + t1t2.numTargetDimensions() + " (n -> m)" ); + + System.out.print( "t1 = " ); + mt1.print( 1, 0 ); + System.out.print( "t2 = " ); + mt2.print( 1, 0 ); + System.out.print( "t1t2 = " ); + mt1t2.print( 1, 0 ); + System.out.print( "t1 x t2 = " ); + mt1.times( mt2 ).print( 1, 0 ); + + System.out.println( "wrong result" ); + System.out.println("======================="); + return false; + } + + return true; + } + + public static boolean testPreConcatenation( Translation t1, TranslationTransform t2 ) + { + if (t1.numSourceDimensions() != t2.numTargetDimensions() ) + { + System.out.println("incompatible dimensions"); + return false; + } + + TranslationTransform t1t2 = t2.preConcatenate( t1 ); + + Matrix mt1 = new Matrix( t1.getMatrix() ); + Matrix mt2 = new Matrix( t2.getMatrix() ); + Matrix mt1t2 = new Matrix( t1t2.getMatrix() ); + + if ( mt1.times( mt2 ).minus( mt1t2 ).normF() > 0.1 ) { + System.out.println("======================="); + System.out.println("t1: " + t1.numSourceDimensions() + " -> " + t1.numTargetDimensions() + " (n -> m)" ); + System.out.println("t2: " + t2.numSourceDimensions() + " -> " + t2.numTargetDimensions() + " (n -> m)" ); + System.out.println("t1t2: " + t1t2.numSourceDimensions() + " -> " + t1t2.numTargetDimensions() + " (n -> m)" ); + + System.out.print( "t1 = " ); + mt1.print( 1, 0 ); + System.out.print( "t2 = " ); + mt2.print( 1, 0 ); + System.out.print( "t1t2 = " ); + mt1t2.print( 1, 0 ); + System.out.print( "t1 x t2 = " ); + mt1.times( mt2 ).print( 1, 0 ); + + System.out.println( "wrong result" ); + System.out.println("======================="); + return false; + } + + return true; + } + + TranslationTransform tr1; + TranslationTransform tr2; + + @Before + public void setUp() + { + tr1 = new TranslationTransform( 3 ); + long[] translation = new long[] {3, 4, 5}; + tr1.setTranslation( translation ); + + tr2 = new TranslationTransform( new long[] {7, 8, 9} ); + } + + @Test + public void concatenateTr1Tr2() + { + assertTrue( testConcatenation( tr1, tr2 ) ); + } + + @Test + public void preconcatenateTr1Tr2() + { + assertTrue( testPreConcatenation( tr1, tr2 ) ); + } + + @Test + public void concatenateTr2Tr1() + { + assertTrue( testConcatenation( tr2, tr1 ) ); + } + + @Test + public void preconcatenateTr2Tr1() + { + assertTrue( testPreConcatenation( tr2, tr1 ) ); + } +} diff --git a/src/test/java/tests/CompositeXYProjectorBenchmark.java b/src/test/java/tests/CompositeXYProjectorBenchmark.java new file mode 100644 index 0000000..fbd19eb --- /dev/null +++ b/src/test/java/tests/CompositeXYProjectorBenchmark.java @@ -0,0 +1,83 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package tests; + +import ij.ImageJ; +import net.imglib2.display.ChannelARGBConverter; +import net.imglib2.display.CompositeXYProjector; +import net.imglib2.exception.IncompatibleTypeException; +import net.imglib2.img.Img; +import net.imglib2.img.array.ArrayImgFactory; +import net.imglib2.img.display.imagej.ImageJFunctions; +import net.imglib2.io.ImgIOException; +import net.imglib2.io.ImgOpener; +import net.imglib2.type.numeric.ARGBType; +import net.imglib2.type.numeric.integer.UnsignedByteType; + +public class CompositeXYProjectorBenchmark +{ + final Img< UnsignedByteType > img; + + final Img< ARGBType > argbImg; + + public CompositeXYProjectorBenchmark( final String filename ) throws ImgIOException, IncompatibleTypeException + { + // open with ImgOpener using an ArrayImgFactory + final ArrayImgFactory< UnsignedByteType > factory = new ArrayImgFactory< UnsignedByteType >(); + img = new ImgOpener().openImg( filename, factory, new UnsignedByteType() ); + final long[] dim = new long[ img.numDimensions() - 1 ]; + for ( int d = 0; d < dim.length; ++d ) + dim[ d ] = img.dimension( d ); + argbImg = new ArrayImgFactory< ARGBType >().create( dim, new ARGBType() ); + convert( img, argbImg ); + + ImageJFunctions.show( argbImg ); + } + + public void convert( final Img< UnsignedByteType > in, final Img< ARGBType > out ) + { + final CompositeXYProjector< UnsignedByteType > projector = new CompositeXYProjector< UnsignedByteType >( in, out, ChannelARGBConverter.converterListRGBA, 2 ); + projector.setComposite( true ); +// projector.setComposite( 0, false ); +// projector.setComposite( 1, true ); +// projector.setComposite( 2, false ); + for ( int iteration = 0; iteration < 10; ++iteration ) + { + final long start = System.currentTimeMillis(); + for ( int i = 0; i < 10; ++i ) + projector.map(); + final long end = System.currentTimeMillis(); + System.out.println( ( end - start ) + " ms (iteration " + iteration + ")" ); + } + } + + public static void main( final String[] args ) throws IncompatibleTypeException, ImgIOException + { + new ImageJ(); + new CompositeXYProjectorBenchmark( "/home/tobias/Desktop/test.png" ); + } +} diff --git a/src/test/java/tests/CompositeXYRandomAccessibleProjectorBenchmark.java b/src/test/java/tests/CompositeXYRandomAccessibleProjectorBenchmark.java new file mode 100644 index 0000000..de374f1 --- /dev/null +++ b/src/test/java/tests/CompositeXYRandomAccessibleProjectorBenchmark.java @@ -0,0 +1,83 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package tests; + +import ij.ImageJ; +import net.imglib2.display.ChannelARGBConverter; +import net.imglib2.display.CompositeXYRandomAccessibleProjector; +import net.imglib2.exception.IncompatibleTypeException; +import net.imglib2.img.Img; +import net.imglib2.img.array.ArrayImgFactory; +import net.imglib2.img.display.imagej.ImageJFunctions; +import net.imglib2.io.ImgIOException; +import net.imglib2.io.ImgOpener; +import net.imglib2.type.numeric.ARGBType; +import net.imglib2.type.numeric.integer.UnsignedByteType; + +public class CompositeXYRandomAccessibleProjectorBenchmark +{ + final Img< UnsignedByteType > img; + + final Img< ARGBType > argbImg; + + public CompositeXYRandomAccessibleProjectorBenchmark( final String filename ) throws ImgIOException, IncompatibleTypeException + { + // open with ImgOpener using an ArrayImgFactory + final ArrayImgFactory< UnsignedByteType > factory = new ArrayImgFactory< UnsignedByteType >(); + img = new ImgOpener().openImg( filename, factory, new UnsignedByteType() ); + final long[] dim = new long[ img.numDimensions() - 1 ]; + for ( int d = 0; d < dim.length; ++d ) + dim[ d ] = img.dimension( d ); + argbImg = new ArrayImgFactory< ARGBType >().create( dim, new ARGBType() ); + convert( img, argbImg ); + + ImageJFunctions.show( argbImg ); + } + + public void convert( final Img< UnsignedByteType > in, final Img< ARGBType > out ) + { + final CompositeXYRandomAccessibleProjector< UnsignedByteType > projector = new CompositeXYRandomAccessibleProjector< UnsignedByteType >( in, out, ChannelARGBConverter.converterListRGBA, 2 ); + projector.setComposite( true ); +// projector.setComposite( 0, false ); +// projector.setComposite( 1, true ); +// projector.setComposite( 2, false ); + for ( int iteration = 0; iteration < 10; ++iteration ) + { + final long start = System.currentTimeMillis(); + for ( int i = 0; i < 10; ++i ) + projector.map(); + final long end = System.currentTimeMillis(); + System.out.println( ( end - start ) + " ms (iteration " + iteration + ")" ); + } + } + + public static void main( final String[] args ) throws IncompatibleTypeException, ImgIOException + { + new ImageJ(); + new CompositeXYRandomAccessibleProjectorBenchmark( "/home/tobias/Desktop/test.png" ); + } +} diff --git a/src/test/java/tests/ImgPanel.java b/src/test/java/tests/ImgPanel.java new file mode 100644 index 0000000..21b87e4 --- /dev/null +++ b/src/test/java/tests/ImgPanel.java @@ -0,0 +1,205 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package tests; + +import java.awt.Adjustable; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Toolkit; +import java.awt.Window; +import java.awt.event.AdjustmentEvent; +import java.awt.event.AdjustmentListener; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.BoxLayout; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JScrollBar; +import javax.swing.border.TitledBorder; + +import net.imglib2.display.ARGBScreenImage; +import net.imglib2.display.RealARGBConverter; +import net.imglib2.display.XYProjector; +import net.imglib2.exception.IncompatibleTypeException; +import net.imglib2.img.Img; +import net.imglib2.img.ImgPlus; +import net.imglib2.io.ImgIOException; +import net.imglib2.io.ImgIOUtils; +import net.imglib2.io.ImgOpener; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.ARGBType; +import net.imglib2.type.numeric.RealType; +import ome.scifio.common.StatusEvent; +import ome.scifio.common.StatusListener; + +/** + * A simple UI that demonstrates display of {@link Img}s. + * + * @author Curtis Rueden + */ +public class ImgPanel extends JPanel { + + public class ImgData & NativeType> { + + public String name; + public ImgPlus imgPlus; + public ImgPanel owner; + public int width, height; + public ARGBScreenImage screenImage; + public RealARGBConverter converter; + public XYProjector projector; + + public ImgData(final String name, final ImgPlus imgPlus, + final ImgPanel owner) + { + this.name = name; + this.imgPlus = imgPlus; + this.owner = owner; + width = (int) imgPlus.dimension(0); + height = (int) imgPlus.dimension(1); + screenImage = new ARGBScreenImage(width, height); + final int min = 0, max = 255; + converter = new RealARGBConverter(min, max); + projector = + new XYProjector(imgPlus, screenImage, converter); + projector.map(); + } + } + + public class SliderPanel extends JPanel { + + public SliderPanel(final ImgData imgData) { + setBorder(new TitledBorder(imgData.name)); + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + // add one slider per dimension beyond the first two + for (int d = 2; d < imgData.imgPlus.numDimensions(); d++) { + final int dimLength = (int) imgData.imgPlus.dimension(d); + final JScrollBar bar = + new JScrollBar(Adjustable.HORIZONTAL, 0, 1, 0, dimLength); + final int dim = d; + bar.addAdjustmentListener(new AdjustmentListener() { + + @Override + public void adjustmentValueChanged(final AdjustmentEvent e) { + final int value = bar.getValue(); + imgData.projector.setPosition(value, dim); + imgData.projector.map(); + imgData.owner.repaint(); + } + }); + add(bar); + } + } + } + + protected List> images = new ArrayList>(); + protected int maxWidth = 0, maxHeight = 0; + + public ImgPanel() { + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + add(new JPanel() { // image canvas + + @Override + public void paint(final Graphics g) { + for (final ImgData imgData : images) { + final Image image = imgData.screenImage.image(); + g.drawImage(image, 0, 0, this); + } + } + + @Override + public Dimension getPreferredSize() { + return new Dimension(maxWidth, maxHeight); + } + }); + } + + public & NativeType> void addImage( + final String name, final ImgPlus img) + { + final ImgData imgData = new ImgData(name, img, this); + images.add(imgData); + if (imgData.width > maxWidth) maxWidth = imgData.width; + if (imgData.height > maxHeight) maxHeight = imgData.height; + add(new SliderPanel(imgData)); + } + + public static final & NativeType> void main( + final String[] args) + { + final String[] urls = { + "http://loci.wisc.edu/files/software/ome-tiff/z-series.zip" + }; + final JFrame frame = new JFrame("ImgPanel Test Frame"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + final ImgPanel imgPanel = new ImgPanel(); + for (final String url : urls) { + final ImgPlus img = loadImage(url); + imgPanel.addImage(url, img); + } + frame.setContentPane(imgPanel); + frame.pack(); + center(frame); + frame.setVisible(true); + } + + private static & NativeType> ImgPlus loadImage( + final String url) + { + try { + System.out.println("Downloading " + url); + final String id = ImgIOUtils.cacheId(url); + System.out.println("Opening " + id); + final ImgOpener imgOpener = new ImgOpener(); + imgOpener.addStatusListener(new StatusListener() { + @Override + public void statusUpdated(StatusEvent e) { + System.out.println(e.getStatusMessage()); + } + }); + return imgOpener.openImg(id); + } + catch (final IncompatibleTypeException e) { + e.printStackTrace(); + } + catch (final ImgIOException e) { + e.printStackTrace(); + } + return null; + } + + private static void center(final Window win) { + final Dimension size = win.getSize(); + final Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); + final int w = (screen.width - size.width) / 2; + final int h = (screen.height - size.height) / 2; + win.setLocation(w, h); + } + +} diff --git a/src/test/java/tests/LanczosExample.java b/src/test/java/tests/LanczosExample.java new file mode 100644 index 0000000..5d24579 --- /dev/null +++ b/src/test/java/tests/LanczosExample.java @@ -0,0 +1,135 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package tests; + +import ij.IJ; +import ij.ImageJ; +import ij.ImagePlus; +import ij.process.ColorProcessor; +import mpicbg.util.Timer; +import net.imglib2.RandomAccessible; +import net.imglib2.display.ARGBScreenImage; +import net.imglib2.display.RealARGBConverter; +import net.imglib2.display.XYRandomAccessibleProjector; +import net.imglib2.img.Img; +import net.imglib2.img.ImgPlus; +import net.imglib2.img.array.ArrayImgFactory; +import net.imglib2.interpolation.Interpolant; +import net.imglib2.interpolation.InterpolatorFactory; +import net.imglib2.interpolation.randomaccess.LanczosInterpolatorFactory; +import net.imglib2.io.ImgIOException; +import net.imglib2.io.ImgOpener; +import net.imglib2.realtransform.AffineGet; +import net.imglib2.realtransform.AffineRandomAccessible; +import net.imglib2.realtransform.AffineTransform3D; +import net.imglib2.type.numeric.ARGBType; +import net.imglib2.type.numeric.integer.UnsignedShortType; +import net.imglib2.view.Views; + +/** + * TODO + * + */ +public class LanczosExample +{ + final static public void main( final String[] args ) + throws ImgIOException + { + new ImageJ(); + + final ImgOpener io = new ImgOpener(); + //final RandomAccessibleInterval< UnsignedShortType > img = io.openImg( "/home/saalfeld/phd/light-microscopy/presentation/saalfeld-05-05-4-DPX-05_L1_Sum.lsm", new ArrayImgFactory< UnsignedShortType >(), new UnsignedShortType()); + final ImgPlus< UnsignedShortType > imgPlus = io.openImg( "/home/saalfeld/Desktop/l1-cns.tif", new ArrayImgFactory< UnsignedShortType >(), new UnsignedShortType()); + final Img< UnsignedShortType > img = imgPlus.getImg(); + + final double[][] matrix = new double[][]{ + { 0.5, 0, 0, img.dimension( 0 ) * 0.25 }, + { 0, 0.5 * imgPlus.calibration( 1 ) / imgPlus.calibration( 0 ), 0, img.dimension( 1 ) * 0.25 }, + { 0, 0, 0.5 * imgPlus.calibration( 0 ) / imgPlus.calibration( 0 ), 0 } + }; +// final AffineTransform affine = new AffineTransform( new Matrix( matrix ) ); + final AffineTransform3D affine = new AffineTransform3D(); + affine.set( matrix[ 0 ][ 0 ], matrix[ 0 ][ 1 ], matrix[ 0 ][ 2 ], matrix[ 0 ][ 3 ], matrix[ 1 ][ 0 ], matrix[ 1 ][ 1 ], matrix[ 1 ][ 2 ], matrix[ 1 ][ 3 ], matrix[ 2 ][ 0 ], matrix[ 2 ][ 1 ], matrix[ 2 ][ 2 ], matrix[ 2 ][ 3 ] ); + +// final InterpolatorFactory< UnsignedShortType, RandomAccessible< UnsignedShortType > > interpolatorFactory = new NearestNeighborInterpolatorFactory< UnsignedShortType >(); +// final InterpolatorFactory< UnsignedShortType, RandomAccessible< UnsignedShortType > > interpolatorFactory = new NLinearInterpolatorFactory< UnsignedShortType >(); + final InterpolatorFactory< UnsignedShortType, RandomAccessible< UnsignedShortType > > interpolatorFactory = new LanczosInterpolatorFactory< UnsignedShortType >(); + + final RandomAccessible< UnsignedShortType > extendedImg = Views.extendValue( img, new UnsignedShortType() ); + final Interpolant< UnsignedShortType, RandomAccessible< UnsignedShortType > > interpolant = new Interpolant< UnsignedShortType, RandomAccessible< UnsignedShortType > >( extendedImg, interpolatorFactory ); + final AffineRandomAccessible< UnsignedShortType, AffineGet > mapping = new AffineRandomAccessible< UnsignedShortType, AffineGet >( interpolant, affine ); + + final ARGBScreenImage screenImage = new ARGBScreenImage( ( int )img.dimension( 0 ), ( int )img.dimension( 1 ) ); + final XYRandomAccessibleProjector< UnsignedShortType, ARGBType > projector = new XYRandomAccessibleProjector< UnsignedShortType, ARGBType >( mapping, screenImage, new RealARGBConverter< UnsignedShortType >( 0, 4095 ) ); + + final ColorProcessor cp = new ColorProcessor( screenImage.image() ); + final ImagePlus imp = new ImagePlus( "argbScreenProjection", cp ); + imp.show(); + + final Timer timer = new Timer(); + + projector.setPosition( img.dimension( 2 ) / 2, 2 ); + + final AffineTransform3D forward = new AffineTransform3D(); + final AffineTransform3D rotation = new AffineTransform3D(); + final AffineTransform3D scale = new AffineTransform3D(); + scale.set( + 4, 0, 0, 0, + 0, 4, 0, 0, + 0, 0, 4, 0 ); + + for ( int k = 0; k < 3; ++k ) + { + timer.start(); + for ( int i = 45; i < 48; ++i ) + { + rotation.rotate( 1, Math.PI / 360 ); + forward.set( + 1.0, 0, 0, -img.dimension( 0 ) / 2.0, + 0, 1.0, 0, -img.dimension( 1 ) / 2.0, + 0, 0, 1.0, -img.dimension( 2 ) / 2.0 ); + forward.preConcatenate( scale ); + forward.preConcatenate( rotation ); + forward.set( + forward.get( 0, 0 ), forward.get( 0, 1 ), forward.get( 0, 2 ), forward.get( 0, 3 ) + img.dimension( 0 ) / 2.0, + forward.get( 1, 0 ), forward.get( 1, 1 ), forward.get( 1, 2 ), forward.get( 1, 3 ) + img.dimension( 1 ) / 2.0, + forward.get( 2, 0 ), forward.get( 2, 1 ), forward.get( 2, 2 ), forward.get( 2, 3 ) + img.dimension( 2 ) / 2.0 ); + + affine.set( forward.inverse() ); + + projector.map(); + + imp.setImage( screenImage.image() ); + } + IJ.log( "loop " + ( k + 1 ) + ": " + timer.stop() ); + } + + final ColorProcessor cpa = new ColorProcessor( screenImage.image() ); + imp.setProcessor( cpa ); + imp.updateAndDraw(); + } +} diff --git a/src/test/java/tests/OpenAndDisplayAffineTransformedScreenImage.java b/src/test/java/tests/OpenAndDisplayAffineTransformedScreenImage.java new file mode 100644 index 0000000..cca11db --- /dev/null +++ b/src/test/java/tests/OpenAndDisplayAffineTransformedScreenImage.java @@ -0,0 +1,161 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package tests; + +import ij.IJ; +import ij.ImageJ; +import ij.ImagePlus; +import ij.process.ColorProcessor; +import mpicbg.util.Timer; +import net.imglib2.RandomAccessible; +import net.imglib2.display.ARGBScreenImage; +import net.imglib2.display.RealARGBConverter; +import net.imglib2.display.XYRandomAccessibleProjector; +import net.imglib2.img.Img; +import net.imglib2.img.ImgPlus; +import net.imglib2.img.array.ArrayImgFactory; +import net.imglib2.interpolation.Interpolant; +import net.imglib2.interpolation.randomaccess.NearestNeighborInterpolatorFactory; +import net.imglib2.io.ImgIOException; +import net.imglib2.io.ImgOpener; +import net.imglib2.realtransform.AffineGet; +import net.imglib2.realtransform.AffineRandomAccessible; +import net.imglib2.realtransform.AffineTransform3D; +import net.imglib2.type.numeric.ARGBType; +import net.imglib2.type.numeric.integer.UnsignedShortType; +import net.imglib2.view.Views; + +/** + * TODO + * + */ +public class OpenAndDisplayAffineTransformedScreenImage +{ + final static public void main( final String[] args ) + throws ImgIOException + { + new ImageJ(); + + final ImgOpener io = new ImgOpener(); + //final RandomAccessibleInterval< UnsignedShortType > img = io.openImg( "/home/saalfeld/phd/light-microscopy/presentation/saalfeld-05-05-4-DPX-05_L1_Sum.lsm", new ArrayImgFactory< UnsignedShortType >(), new UnsignedShortType()); + final ImgPlus< UnsignedShortType > imgPlus = io.openImg( "/home/saalfeld/phd/light-microscopy/presentation/saalfeld-05-05-4-DPX-05_L1_Sum.0.tif", new ArrayImgFactory< UnsignedShortType >(), new UnsignedShortType()); + final Img< UnsignedShortType > img = imgPlus.getImg(); + + final double[][] matrix = new double[][]{ + { 0.5, 0, 0, img.dimension( 0 ) * 0.25 }, + { 0, 0.5 * imgPlus.calibration( 1 ) / imgPlus.calibration( 0 ), 0, img.dimension( 1 ) * 0.25 }, + { 0, 0, 0.5 * imgPlus.calibration( 0 ) / imgPlus.calibration( 0 ), 0 } + }; +// final AffineTransform affine = new AffineTransform( new Matrix( matrix ) ); + final AffineTransform3D affine = new AffineTransform3D(); + affine.set( matrix[ 0 ][ 0 ], matrix[ 0 ][ 1 ], matrix[ 0 ][ 2 ], matrix[ 0 ][ 3 ], matrix[ 1 ][ 0 ], matrix[ 1 ][ 1 ], matrix[ 1 ][ 2 ], matrix[ 1 ][ 3 ], matrix[ 2 ][ 0 ], matrix[ 2 ][ 1 ], matrix[ 2 ][ 2 ], matrix[ 2 ][ 3 ] ); + + final NearestNeighborInterpolatorFactory< UnsignedShortType > interpolatorFactory = new NearestNeighborInterpolatorFactory< UnsignedShortType >(); +// final InterpolatorFactory< UnsignedShortType, RandomAccessible< UnsignedShortType> > interpolatorFactory = new NLinearInterpolatorFactory< UnsignedShortType >(); + + final RandomAccessible< UnsignedShortType > extendedImg = Views.extendValue( img, new UnsignedShortType() ); + //final RandomAccessible< UnsignedShortType > channel = Views.hyperSlice( img, 2, 0 ); + //final Interpolant< UnsignedShortType, RandomAccessible< UnsignedShortType > > interpolant = new Interpolant< UnsignedShortType, RandomAccessible< UnsignedShortType > >( channel, interpolatorFactory ); + final Interpolant< UnsignedShortType, RandomAccessible< UnsignedShortType > > interpolant = new Interpolant< UnsignedShortType, RandomAccessible< UnsignedShortType > >( extendedImg, interpolatorFactory ); +// final RealTransformRandomAccessible< UnsignedShortType, AffineTransform3D > mapping = new RealTransformRandomAccessible< UnsignedShortType, AffineTransform3D >( interpolant, affine ); +// final AffineRealRandomAccessible< UnsignedShortType, Affine > mapping = new AffineRealRandomAccessible< UnsignedShortType, Affine >( interpolant, affine ); + final AffineRandomAccessible< UnsignedShortType, AffineGet > mapping = new AffineRandomAccessible< UnsignedShortType, AffineGet >( interpolant, affine ); +// final ConstantAffineRandomAccessible< UnsignedShortType, AffineTransform3D > mapping = new ConstantAffineRandomAccessible< UnsignedShortType, AffineTransform3D >( interpolant, affine ); +// final RandomAccessibleOnRealRandomAccessible< UnsignedShortType > transformedPixels = new RandomAccessibleOnRealRandomAccessible< UnsignedShortType >( mapping ); + + final ColorProcessor cp = new ColorProcessor( ( int )img.dimension( 0 ), ( int )img.dimension( 1 ) ); + final ARGBScreenImage screenImage = new ARGBScreenImage( cp.getWidth(), cp.getHeight(), ( int[] )cp.getPixels() ); +// final XYProjector< UnsignedShortType, ARGBType > projector = new XYProjector< UnsignedShortType, ARGBType >( mapping, screenImage, new RealARGBConverter< UnsignedShortType >( 0, 4095 ) ); +// final XYProjector< UnsignedShortType, ARGBType > projector = new XYProjector< UnsignedShortType, ARGBType >( transformedPixels, screenImage, new RealARGBConverter< UnsignedShortType >( 0, 4095 ) ); + final XYRandomAccessibleProjector< UnsignedShortType, ARGBType > projector = new XYRandomAccessibleProjector< UnsignedShortType, ARGBType >( mapping, screenImage, new RealARGBConverter< UnsignedShortType >( 0, 4095 ) ); +// final XYRandomAccessibleProjector< UnsignedShortType, ARGBType > projector = new XYRandomAccessibleProjector< UnsignedShortType, ARGBType >( transformedPixels, screenImage, new RealARGBConverter< UnsignedShortType >( 0, 4095 ) ); + + final ImagePlus imp = new ImagePlus( "argbScreenProjection", cp ); + imp.show(); + + final Timer timer = new Timer(); + + for ( int k = 0; k < 0; ++k ) + { + timer.start(); +// final long last = img.dimension( 3 ) * 2 - 2; + final long last = img.dimension( 2 ) * 2 - 2; + for ( int i = 0; i < last; ++i ) + { + projector.setPosition( i, 2 ); + projector.map(); + imp.updateAndDraw(); + } + IJ.log( "loop " + ( k + 1 ) + ": " + timer.stop() ); + } + + projector.setPosition( img.dimension( 2 ) / 2, 2 ); + + final AffineTransform3D forward = new AffineTransform3D(); + final AffineTransform3D rotation = new AffineTransform3D(); + final AffineTransform3D scale = new AffineTransform3D(); + scale.set( + 2, 0, 0, 0, + 0, 2, 0, 0, + 0, 0, 2, 0 ); + + for ( int k = 0; k < 3; ++k ) + { + timer.start(); + for ( int i = 0; i < 360; ++i ) + { + rotation.rotate( 1, Math.PI / 360 ); + forward.set( + 1.0, 0, 0, -img.dimension( 0 ) / 2.0, + 0, 1.0, 0, -img.dimension( 1 ) / 2.0, + 0, 0, 1.0, -img.dimension( 2 ) / 2.0 ); + forward.preConcatenate( scale ); + forward.preConcatenate( rotation ); + forward.set( + forward.get( 0, 0 ), forward.get( 0, 1 ), forward.get( 0, 2 ), forward.get( 0, 3 ) + img.dimension( 0 ) / 2.0, + forward.get( 1, 0 ), forward.get( 1, 1 ), forward.get( 1, 2 ), forward.get( 1, 3 ) + img.dimension( 1 ) / 2.0, + forward.get( 2, 0 ), forward.get( 2, 1 ), forward.get( 2, 2 ), forward.get( 2, 3 ) + img.dimension( 2 ) / 2.0 ); + + affine.set( forward.inverse() ); + +// final ConstantAffineRandomAccessible< UnsignedShortType, AffineTransform3D > mapping1 = new ConstantAffineRandomAccessible< UnsignedShortType, AffineTransform3D >( interpolant, affine ); +// final XYRandomAccessibleProjector< UnsignedShortType, ARGBType > projector1 = new XYRandomAccessibleProjector< UnsignedShortType, ARGBType >( mapping1, screenImage, new RealARGBConverter< UnsignedShortType >( 0, 4095 ) ); +// projector1.setPosition( img.dimension( 2 ) / 2, 2 ); +// + //System.out.println( affine ); + + projector.map(); + imp.updateAndDraw(); + } + IJ.log( "loop " + ( k + 1 ) + ": " + timer.stop() ); + } + + final ColorProcessor cpa = new ColorProcessor( screenImage.image() ); + imp.setProcessor( cpa ); + imp.updateAndDraw(); + } +} diff --git a/src/test/java/tests/OpenAndDisplayScreenImage.java b/src/test/java/tests/OpenAndDisplayScreenImage.java new file mode 100644 index 0000000..a1e9269 --- /dev/null +++ b/src/test/java/tests/OpenAndDisplayScreenImage.java @@ -0,0 +1,78 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package tests; + +import ij.ImageJ; +import ij.ImagePlus; +import ij.process.ColorProcessor; +import net.imglib2.RandomAccessibleInterval; +import net.imglib2.display.ARGBScreenImage; +import net.imglib2.display.RealARGBConverter; +import net.imglib2.display.XYProjector; +import net.imglib2.img.array.ArrayImgFactory; +import net.imglib2.io.ImgIOException; +import net.imglib2.io.ImgOpener; +import net.imglib2.type.numeric.ARGBType; +import net.imglib2.type.numeric.real.FloatType; + +/** + * TODO + * + */ +public class OpenAndDisplayScreenImage +{ + final static public void main( final String[] args ) + throws ImgIOException + { + new ImageJ(); + + final ImgOpener io = new ImgOpener(); + RandomAccessibleInterval< FloatType > img = io.openImg( "/home/tobias/workspace/data/73_float.tif", new ArrayImgFactory(), new FloatType()); + + final ARGBScreenImage screenImage = new ARGBScreenImage( ( int )img.dimension( 0 ), ( int )img.dimension( 1 ) ); + final XYProjector< FloatType, ARGBType > projector = new XYProjector< FloatType, ARGBType >( img, screenImage, new RealARGBConverter< FloatType >( 0, 127 ) ); + + final ColorProcessor cp = new ColorProcessor( screenImage.image() ); + final ImagePlus imp = new ImagePlus( "argbScreenProjection", cp ); + imp.show(); + + for ( int k = 0; k < 3; ++k ) + for ( int i = 0; i < img.dimension( 2 ); ++i ) + { + projector.setPosition( i, 2 ); + projector.map(); + final ColorProcessor cpa = new ColorProcessor( screenImage.image() ); + imp.setProcessor( cpa ); + imp.updateAndDraw(); + } + + projector.map(); + + projector.setPosition( 40, 2 ); + projector.map(); + } +} diff --git a/src/test/java/tests/OpenAndDisplayWithCellContainer.java b/src/test/java/tests/OpenAndDisplayWithCellContainer.java new file mode 100644 index 0000000..6fc858c --- /dev/null +++ b/src/test/java/tests/OpenAndDisplayWithCellContainer.java @@ -0,0 +1,62 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package tests; + +import ij.ImageJ; +import net.imglib2.img.Img; +import net.imglib2.img.ImgFactory; +import net.imglib2.img.cell.CellImgFactory; +import net.imglib2.img.display.imagej.ImageJFunctions; +import net.imglib2.io.ImgOpener; +import net.imglib2.type.numeric.real.FloatType; + +/** + * TODO + * + */ +public class OpenAndDisplayWithCellContainer +{ + final static public void main( final String[] args ) + { + new ImageJ(); + + Img< FloatType > img = null; + try + { + ImgFactory< FloatType > imgFactory = new CellImgFactory( new int[] {64, 64} ); + final ImgOpener io = new ImgOpener(); + img = io.openImg( "/home/tobias/workspace/data/73_float.tif", imgFactory, new FloatType() ); + } + catch ( Exception e ) + { + e.printStackTrace(); + return; + } + + ImageJFunctions.show( img ); + } +} diff --git a/src/test/java/tests/XYProjectorBenchmark.java b/src/test/java/tests/XYProjectorBenchmark.java new file mode 100644 index 0000000..de3b05e --- /dev/null +++ b/src/test/java/tests/XYProjectorBenchmark.java @@ -0,0 +1,76 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package tests; + +import ij.ImageJ; +import net.imglib2.display.RealARGBConverter; +import net.imglib2.display.XYProjector; +import net.imglib2.exception.IncompatibleTypeException; +import net.imglib2.img.Img; +import net.imglib2.img.array.ArrayImgFactory; +import net.imglib2.img.display.imagej.ImageJFunctions; +import net.imglib2.io.ImgIOException; +import net.imglib2.io.ImgOpener; +import net.imglib2.type.numeric.ARGBType; +import net.imglib2.type.numeric.integer.UnsignedByteType; + +public class XYProjectorBenchmark +{ + final Img< UnsignedByteType > img; + + final Img< ARGBType > argbImg; + + public XYProjectorBenchmark( final String filename ) throws ImgIOException, IncompatibleTypeException + { + // open with ImgOpener using an ArrayImgFactory + final ArrayImgFactory< UnsignedByteType > factory = new ArrayImgFactory< UnsignedByteType >(); + img = new ImgOpener().openImg( filename, factory, new UnsignedByteType() ); + argbImg = new ArrayImgFactory< ARGBType >().create( img, new ARGBType() ); + convert( img, argbImg ); + + ImageJFunctions.show( argbImg ); + } + + public void convert( final Img< UnsignedByteType > in, final Img< ARGBType > out ) + { + final XYProjector< UnsignedByteType, ARGBType > projector = new XYProjector< UnsignedByteType, ARGBType >( in, out, new RealARGBConverter< UnsignedByteType >(0, 1000) ); + for ( int iteration = 0; iteration < 10; ++iteration ) + { + final long start = System.currentTimeMillis(); + for ( int i = 0; i < 50; ++i ) + projector.map(); + final long end = System.currentTimeMillis(); + System.out.println( ( end - start ) + " ms (iteration " + iteration + ")" ); + } + } + + public static void main( final String[] args ) throws IncompatibleTypeException, ImgIOException + { + new ImageJ(); + new XYProjectorBenchmark( "/home/tobias/workspace/data/DrosophilaWing.tif" ); + } +} diff --git a/src/test/java/tests/XYRandomAccessibleProjectorBenchmark.java b/src/test/java/tests/XYRandomAccessibleProjectorBenchmark.java new file mode 100644 index 0000000..2963ec5 --- /dev/null +++ b/src/test/java/tests/XYRandomAccessibleProjectorBenchmark.java @@ -0,0 +1,76 @@ +/* + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2013 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, + * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves + * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, + * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, + * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +package tests; + +import ij.ImageJ; +import net.imglib2.display.RealARGBConverter; +import net.imglib2.display.XYRandomAccessibleProjector; +import net.imglib2.exception.IncompatibleTypeException; +import net.imglib2.img.Img; +import net.imglib2.img.array.ArrayImgFactory; +import net.imglib2.img.display.imagej.ImageJFunctions; +import net.imglib2.io.ImgIOException; +import net.imglib2.io.ImgOpener; +import net.imglib2.type.numeric.ARGBType; +import net.imglib2.type.numeric.integer.UnsignedByteType; + +public class XYRandomAccessibleProjectorBenchmark +{ + final Img< UnsignedByteType > img; + + final Img< ARGBType > argbImg; + + public XYRandomAccessibleProjectorBenchmark( final String filename ) throws ImgIOException, IncompatibleTypeException + { + // open with ImgOpener using an ArrayImgFactory + final ArrayImgFactory< UnsignedByteType > factory = new ArrayImgFactory< UnsignedByteType >(); + img = new ImgOpener().openImg( filename, factory, new UnsignedByteType() ); + argbImg = new ArrayImgFactory< ARGBType >().create( img, new ARGBType() ); + convert( img, argbImg ); + + ImageJFunctions.show( argbImg ); + } + + public void convert( final Img< UnsignedByteType > in, final Img< ARGBType > out ) + { + final XYRandomAccessibleProjector< UnsignedByteType, ARGBType > projector = new XYRandomAccessibleProjector< UnsignedByteType, ARGBType >( in, out, new RealARGBConverter< UnsignedByteType >(0, 1000) ); + for ( int iteration = 0; iteration < 10; ++iteration ) + { + final long start = System.currentTimeMillis(); + for ( int i = 0; i < 50; ++i ) + projector.map(); + final long end = System.currentTimeMillis(); + System.out.println( ( end - start ) + " ms (iteration " + iteration + ")" ); + } + } + + public static void main( final String[] args ) throws IncompatibleTypeException, ImgIOException + { + new ImageJ(); + new XYRandomAccessibleProjectorBenchmark( "/home/tobias/workspace/data/DrosophilaWing.tif" ); + } +}