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 }