001 /*----------------------------------------------------------------------------*/
002 /* Copyright (c) FIRST 2008-2012. All Rights Reserved. */
003 /* Open Source Software - may be modified and shared by FRC teams. The code */
004 /* must be accompanied by the FIRST BSD license file in the root directory of */
005 /* the project. */
006 /*----------------------------------------------------------------------------*/
007
008 package edu.wpi.first.wpilibj.image;
009
010 import com.sun.cldc.jna.Pointer;
011 import edu.wpi.first.wpilibj.util.SortedVector;
012
013 /**
014 * An image where each pixel is treated as either on or off.
015 * @author dtjones
016 */
017 public class BinaryImage extends MonoImage {
018 private int numParticles = -1;
019
020 BinaryImage() throws NIVisionException{
021 }
022
023 BinaryImage(BinaryImage sourceImage) {
024 super(sourceImage);
025 }
026
027 /**
028 * Returns the number of particles.
029 * @return The number of particles
030 */
031 public int getNumberParticles () throws NIVisionException{
032 if (numParticles < 0)
033 numParticles = NIVision.countParticles(image);
034 return numParticles;
035 }
036
037
038 private class ParticleSizeReport{
039 final int index;
040 final double size;
041 public ParticleSizeReport(int index) throws NIVisionException{
042 if ((!(index < BinaryImage.this.getNumberParticles())) || index < 0)
043 throw new IndexOutOfBoundsException();
044 this.index = index;
045 size = ParticleAnalysisReport.getParticleToImagePercent(BinaryImage.this, index);
046 }
047 public ParticleAnalysisReport getParticleAnalysisReport () throws NIVisionException{
048 return new ParticleAnalysisReport(BinaryImage.this, index);
049 }
050 }
051
052 /**
053 * Get a particle analysis report for the particle at the given index.
054 * @param index The index of the particle to report on.
055 * @return The ParticleAnalysisReport for the particle at the given index
056 */
057 public ParticleAnalysisReport getParticleAnalysisReport(int index) throws NIVisionException{
058 if (!(index < getNumberParticles())) throw new IndexOutOfBoundsException();
059 return new ParticleAnalysisReport(this, index);
060 }
061
062 /**
063 * Gets all the particle analysis reports ordered from largest area to smallest.
064 * @param size The number of particles to return
065 * @return An array of ParticleReports from largest area to smallest
066 */
067 public ParticleAnalysisReport[] getOrderedParticleAnalysisReports(int size) throws NIVisionException{
068 if (size > getNumberParticles())
069 size = getNumberParticles();
070 ParticleSizeReport[] reports = new ParticleSizeReport[size];
071 SortedVector sorter = new SortedVector(new SortedVector.Comparator() {
072 public int compare(Object object1, Object object2) {
073 ParticleSizeReport p1 = (ParticleSizeReport)object1;
074 ParticleSizeReport p2 = (ParticleSizeReport)object2;
075 if (p1.size < p2.size)
076 return -1;
077 else if (p1.size > p2.size)
078 return 1;
079 return 0;
080 }
081 });
082 for (int i = 0; i < getNumberParticles(); i++)
083 sorter.addElement(new ParticleSizeReport(i));
084 sorter.setSize(size);
085 sorter.copyInto(reports);
086 ParticleAnalysisReport[] finalReports = new ParticleAnalysisReport[reports.length];
087 for (int i = 0; i < finalReports.length; i++)
088 finalReports[i] = reports[i].getParticleAnalysisReport();
089 return finalReports;
090 }
091
092 /**
093 * Gets all the particle analysis reports ordered from largest area to smallest.
094 * @return An array of ParticleReports from largest are to smallest
095 */
096 public ParticleAnalysisReport[] getOrderedParticleAnalysisReports() throws NIVisionException{
097 return getOrderedParticleAnalysisReports(getNumberParticles());
098 }
099
100
101 public void write(String fileName) throws NIVisionException{
102 Pointer colorTable = new Pointer(1024);
103 //Black Background
104 colorTable.setByte(0, (byte)0); //B
105 colorTable.setByte(1, (byte)0); //G
106 colorTable.setByte(2, (byte)0); //R
107 colorTable.setByte(3, (byte)0); //Alpha
108 //Red Particles:
109 colorTable.setByte(4, (byte)0); //B
110 colorTable.setByte(5, (byte)0); //G
111 colorTable.setByte(6, (byte)255); //R
112 colorTable.setByte(7, (byte)0); //Alpha
113 try {
114 NIVision.writeFile(image, fileName, colorTable);
115 } finally {
116 colorTable.free();
117 }
118 }
119
120 /**
121 * removeSmallObjects filters particles based on their size.
122 * The algorithm erodes the image a specified number of times and keeps the
123 * particles from the original image that remain in the eroded image.
124 * @param connectivity8 true to use connectivity-8 or false for connectivity-4 to determine
125 * whether particles are touching. For more information about connectivity, see Chapter 9,
126 * Binary Morphology, in the NI Vision Concepts manual.
127 * @param erosions the number of erosions to perform
128 * @return a BinaryImage after applying the filter
129 * @throws NIVisionException
130 */
131 public BinaryImage removeSmallObjects(boolean connectivity8, int erosions) throws NIVisionException {
132 BinaryImage result = new BinaryImage();
133 try {
134 NIVision.sizeFilter(result.image, image, connectivity8, erosions, true);
135 } catch (NIVisionException ex) {
136 result.free();
137 throw ex;
138 }
139 return result;
140 }
141
142 /**
143 * removeLargeObjects filters particles based on their size.
144 * The algorithm erodes the image a specified number of times and discards the
145 * particles from the original image that remain in the eroded image.
146 * @param connectivity8 true to use connectivity-8 or false for connectivity-4 to determine
147 * whether particles are touching. For more information about connectivity, see Chapter 9,
148 * Binary Morphology, in the NI Vision Concepts manual.
149 * @param erosions the number of erosions to perform
150 * @return a BinaryImage after applying the filter
151 * @throws NIVisionException
152 */
153 public BinaryImage removeLargeObjects(boolean connectivity8, int erosions) throws NIVisionException {
154 BinaryImage result = new BinaryImage();
155 try {
156 NIVision.sizeFilter(result.image, image, connectivity8, erosions, false);
157 } catch (NIVisionException ex) {
158 result.free();
159 throw ex;
160 }
161 return result;
162 }
163
164 public BinaryImage convexHull(boolean connectivity8) throws NIVisionException {
165 BinaryImage result = new BinaryImage();
166 try {
167 NIVision.convexHull(result.image, image, connectivity8 ? 1 : 0);
168 } catch (NIVisionException ex) {
169 result.free();
170 throw ex;
171 }
172 return result;
173 }
174
175 public BinaryImage particleFilter(CriteriaCollection criteria) throws NIVisionException {
176 BinaryImage result = new BinaryImage();
177 NIVision.particleFilter(result.image, image, criteria);
178 return result;
179 }
180 }