Object Detection using Template

- Main Page
- Packages
- Classes
- Files

- File List

All Classes Namespaces Files Functions Variables
HOG.java
Go to the documentation of this file.
1 package cz.vutbr.feec.novak68;
2
3 import ij.ImagePlus;
4 import ij.plugin.filter.Convolver;
5 import ij.process.Blitter;
6 import ij.process.ColorProcessor;
7 import ij.process.FloatProcessor;
8 import ij.process.ImageConverter;
9 import ij.process.ImageProcessor;
10
11 import java.awt.Color;
12
13 import cz.vutbr.feec.novak68.hogfilters.HOGFilter;
14 import cz.vutbr.feec.novak68.hogfilters.StrengthElementFilter;
19 public class HOG {
20 private ImagePlus img;
21 private int cellSizeX;
22 private int cellSizeY;
23 private int numOfBins;
24
25 private FloatProcessor magnitude;
26 private FloatProcessor orientation;
27 private int cellCountX;
28 private int cellCountY;
29 private ImageProcessor dX;
30 private ImageProcessor dY;
31 private float[][][] cells;
32 private float[][][] cellsCopy;
33 private final int DISP_WIDTH = 30;
34 private int DISP_HEIGHT = 30;
35
36 public HOG(ImagePlus img, int cellSizeX, int cellSizeY, int numOfBins) {
37 super();
38 this.cellSizeX = cellSizeX;
39 this.cellSizeY = cellSizeY;
40 this.img = img;
41 this.numOfBins = numOfBins;
42 }
43
47 public void compute() {compute (false);}
48 public void compute(boolean normalize) {
49 computeOrientationAndMagnitude(img);
50 computeBins(cellSizeX, cellSizeY, numOfBins);
51 if (normalize)
52 normalizeL2();
53 }
61 private void computeBins(int cellSizeX, int cellSizeY, int numOfBins) {
62 // Compute number of cells.
63 cellCountX = (int) Math.ceil(img.getWidth() / cellSizeX);
64 cellCountY = (int) Math.ceil(img.getHeight() / cellSizeY);
65
66 // Set up array for cells.
67 cells = new float[cellCountX][cellCountY][numOfBins];
68
69 // For each pixel compute sum of maginitudes for each angle bins
70 for (int x = 0; x < cellCountX * cellSizeX; x++) {
71 for (int y = 0; y < cellCountY * cellSizeY; y++) {
72 // Compute correct cell position.
73 int cellPositionX = (int) Math.floor(x / cellSizeX);
74 int cellPositionY = (int) Math.floor(y / cellSizeY);
75
76
77 // Get gradient orientation and select angle bin.
78 int angleBin = (int) Math.floor(orientation.getf(x, y)
79 / (180. / (double) numOfBins));
80
81 // Add gradient magnitude from current pixel to cell histogram.
82 cells[cellPositionX][cellPositionY][angleBin] += magnitude
83 .getf(x, y);
84 }
85 }
86 }
87
94 private void computeOrientationAndMagnitude(ImagePlus img2) {
95 Convolver conv = new Convolver();
96 float[] kernelGradient = { -1.0f, 0.0f, 1.0f };
97
98 // Convert to float
99 ImageConverter ic = new ImageConverter(img);
100 ic.convertToGray32();
101
102 // Duplicate image so we can do two different derivations.
103 dX = img.getProcessor().duplicate();
104 dY = img.getProcessor().duplicate();
105
106 // Compute horizontal derivation (by X).
107 conv.convolve(dX, kernelGradient, 3, 1);
108 dX.resetMinAndMax();
109
110 // Compute vertical derivation (by Y).
111 conv.convolve(dY, kernelGradient, 1, 3);
112 dY.resetMinAndMax();
113
114 // Set up empty matrices for magnitude and orientation.
115 magnitude = new FloatProcessor(img.getWidth(), img.getHeight());
116 orientation = new FloatProcessor(img.getWidth(), img.getHeight());
117
118 // For each pixel...
119 for (int x = 0; x < img.getWidth(); x++) {
120 for (int y = 0; y < img.getHeight(); y++) {
121 // Get values from dX and dY for pixel at (x, y).
122 double dXvalue = dX.getf(x, y);
123 double dYvalue = dY.getf(x, y);
124
125 double magV = Math.sqrt(dXvalue * dXvalue + dYvalue * dYvalue);
126
127 // Compute magnitude, what is basically just sqrt(dX^2 + dY^2).
128 magnitude.setf(x, y, (float) (magV));
129
130 double ori = Math.toDegrees(Math.atan2(dXvalue, dYvalue));
131 if (ori < 0) {
132 ori += 180;
133 }
134
135 // Check for exactly 180 degrees, because that has to be 0.
136 if (ori == 180) {
137 ori = 0;
138 }
139
140 // Compute orientation, what is arctg(dX / dY).
141 orientation.setf(x, y, (float) ori);
142
143 // Convert gradients to unsigned, so only 0-180 degrees.
144 // if (dXvalue != 0 || dYvalue != 0) {
145 // System.out
146 // .println(String
147 // .format("[x = %2d, y = %2d] dXvalue = %3f, dYvalue = %3f, mag = %6.2f, ori = %6.2f",
148 // x, y, dXvalue, dYvalue,
149 // magnitude.getf(x, y),
150 // orientation.getf(x, y)));
151 // }
152 }
153 }
154 // ContrastEnhancer ce = new ContrastEnhancer();
155 // ce.equalize(magnitude);
156
157 }
161 public void useFilter(HOGFilter filter){
162 cells = filter.filter(cells);
163 }
164
168 public ImagePlus displayAngles() {
169 // display results
170 ImagePlus result = new ImagePlus("", new ColorProcessor(cellCountX
171 * DISP_WIDTH, cellCountY * DISP_HEIGHT));
172
173 ImageProcessor ip = magnitude.duplicate().resize(
174 cellCountX * DISP_WIDTH, cellCountY * DISP_HEIGHT);
175 result.getProcessor().copyBits(ip, 0, 0, Blitter.COPY);
176
177 // normalizuj magnitude
178 float max = 0.0000001f;
179 for (int x = 0; x < cellCountX; x++) {
180 for (int y = 0; y < cellCountY; y++) {
181 for (int a = 0; a < numOfBins; a++) {
182 if (max < cells[x][y][a]) {
183 max = cells[x][y][a];
184 }
185 }
186 }
187 }
188 // zobraz uhly
189 for (int x = 0; x < cellCountX; x++) {
190 for (int y = 0; y < cellCountY; y++) {
191 // Mrizka
192 result.setColor(Color.red);
193 result.getProcessor().drawRect(x * DISP_WIDTH, y * DISP_HEIGHT,
194 DISP_WIDTH, DISP_HEIGHT);
195
196 // Vykresli v mrizce smer a silu uhlu
197 for (int a = 0; a < numOfBins; a++) {
198 double angle = 180. / (double) numOfBins * (double)a;
199 double strength = cells[x][y][a] / max;
200 drawAngle(result, x, y, angle, strength);
201 }
202 }
203 }
204 result.show();
205 return result;
206 }
210 public void drawGrid(ImagePlus img){
211 // display results
212 ImagePlus result = new ImagePlus("", new ColorProcessor(cellCountX
213 * DISP_WIDTH, cellCountY * DISP_HEIGHT));
214 result = new ImagePlus("",img.getProcessor().resize(cellCountX
215 * DISP_WIDTH, cellCountY * DISP_HEIGHT));
216 // result = new ImagePlus()
217 // ImagePlus result = new ImagePlus("", new ColorProcessor(cellCountX
218 // * DISP_WIDTH, cellCountY * DISP_HEIGHT));
219
220 // ImageProcessor ip = magnitude.duplicate().resize(
221 // cellCountX * DISP_WIDTH, cellCountY * DISP_HEIGHT);
222 // result.getProcessor().copyBits(ip, 0, 0, Blitter.COPY);
223 // zobraz uhly
224 for (int x = 0; x < cellCountX; x++) {
225 for (int y = 0; y < cellCountY; y++) {
226 // Mrizka
227 result.setColor(Color.red);
228 result.getProcessor().drawRect(x * DISP_WIDTH, y * DISP_HEIGHT,
229 DISP_WIDTH, DISP_HEIGHT);
230 }
231 }
232 result.show();
233 }
237 public void displayStrenghtOnly(){
238 cellsCopy = cells.clone();
239 HOGFilter filter = new StrengthElementFilter();
240 // display results
241 ImagePlus result = new ImagePlus("", new ColorProcessor(cellCountX
242 * DISP_WIDTH, cellCountY * DISP_HEIGHT));
243
244 ImageProcessor ip = magnitude.duplicate().resize(
245 cellCountX * DISP_WIDTH, cellCountY * DISP_HEIGHT);
246 result.getProcessor().copyBits(ip, 0, 0, Blitter.COPY);
247
248 // normalizuj magnitude
249 float max = 0.0000001f;
250 for (int x = 0; x < cellCountX; x++) {
251 for (int y = 0; y < cellCountY; y++) {
252 for (int a = 0; a < numOfBins; a++) {
253 if (max < cellsCopy[x][y][a]) {
254 max = cellsCopy[x][y][a];
255 }
256 }
257 }
258 }
259 cellsCopy = filter.filter(cellsCopy);
260 // zobraz uhly
261 for (int x = 0; x < cellCountX; x++) {
262 for (int y = 0; y < cellCountY; y++) {
263 // Mrizka
264 result.setColor(Color.red);
265 result.getProcessor().drawRect(x * DISP_WIDTH, y * DISP_HEIGHT,
266 DISP_WIDTH, DISP_HEIGHT);
267
268 // Vykresli v mrizce smer a silu uhlu
269 for (int a = 0; a < numOfBins; a++) {
270 double angle = 180. / (double) numOfBins * (double)a;
271 double strength = cellsCopy[x][y][a] / max;
272 drawAngle(result, x, y, angle, strength);
273 }
274 }
275 }
276 result.show();
277 }
286 private void drawAngle(ImagePlus result, int x, int y, double angleDegrees,
287 double strength) {
288 result.setColor(new Color(0, (int) (255. * strength), 0));
289 double rX = DISP_WIDTH / 2.3;
290 double rY = DISP_HEIGHT / 2.3;
291 int fromX = (int) (x * DISP_WIDTH + DISP_WIDTH / 2. + Math.cos(Math
292 .toRadians(angleDegrees)) * rX);
293 int fromY = (int) (y * DISP_HEIGHT + DISP_HEIGHT / 2. - Math.sin(Math
294 .toRadians(angleDegrees)) * rY);
295 int toX = (int) (x * DISP_WIDTH + DISP_WIDTH / 2. - Math.cos(Math
296 .toRadians(angleDegrees)) * rX);
297 int toY = (int) ((y) * DISP_HEIGHT + DISP_HEIGHT / 2. + Math.sin(Math
298 .toRadians(angleDegrees)) * rY);
299 result.getProcessor().drawLine(fromX, fromY, toX, toY);
300 }
304 public ImagePlus showGradientX() {
305 dX.resetMinAndMax();
306 ImagePlus gradient = new ImagePlus("Derivace X", dX);
307 gradient.show();
308 return gradient;
309
310 }
311
315 public ImagePlus showGradientY() {
316 dY.resetMinAndMax();
317 ImagePlus gradienty = new ImagePlus("Derivace Y", dY);
318 gradienty.show();
319 return gradienty;
320 }
321
325 public ImagePlus showMagnification() {
326 magnitude.resetMinAndMax();
327 ImagePlus magn = new ImagePlus("Magnitude ", magnitude);
328 magn.show();
329 return magn;
330 }
331
335 public ImagePlus showOrientation() {
336 orientation.resetMinAndMax();
337 ImagePlus orient = new ImagePlus("Orientation ", orientation);
338 orient.show();
339 return orient;
340 }
341
342 public float getMagnitude(int x, int y, int angleBin) {
343 return cells[x][y][angleBin];
344 }
345 public float [][][] getCells (){
346 return cells;
347 }
351 public int[] getImageSize(){
352 return new int[]{img.getWidth() , img.getHeight()};
353 }
354
358 public void normalizeL2() {
359 double quadSum = 0;
360 double sqrtFromSum = 0;
361 for (int x = 0; x < cells.length ; x++){
362 for (int y = 0; y < cells[0].length; y++){
363 for(int a = 0; a < cells[0][0].length; a++){
364 quadSum += cells[x][y][a] * cells[x][y][a];
365 }
366 }
367 }
368 sqrtFromSum = Math.sqrt(quadSum);
369 for (int x = 0; x < cells.length ; x++){
370 for (int y = 0; y < cells[0].length; y++){
371 for(int a = 0; a < cells[0][0].length; a++){
372 cells[x][y][a] = (float) (cells[x][y][a] / sqrtFromSum);
373 }
374 }
375 }
376 }
377
378 }
cz.vutbr.feec.novak68.HOG.drawGrid
void drawGrid(ImagePlus img)
Definition: HOG.java:210
cz.vutbr.feec.novak68.HOG.getMagnitude
float getMagnitude(int x, int y, int angleBin)
Definition: HOG.java:342
cz.vutbr.feec.novak68.HOG.drawAngle
void drawAngle(ImagePlus result, int x, int y, double angleDegrees, double strength)
Definition: HOG.java:286
cz.vutbr.feec.novak68.HOG.normalizeL2
void normalizeL2()
Definition: HOG.java:358
cz.vutbr.feec.novak68.HOG.dX
ImageProcessor dX
Definition: HOG.java:29
cz.vutbr.feec.novak68.HOG.computeOrientationAndMagnitude
void computeOrientationAndMagnitude(ImagePlus img2)
Definition: HOG.java:94
cz.vutbr.feec.novak68.HOG.cellSizeY
int cellSizeY
Definition: HOG.java:22
cz.vutbr.feec.novak68.HOG.showGradientX
ImagePlus showGradientX()
Definition: HOG.java:304
cz.vutbr.feec.novak68.HOG.magnitude
FloatProcessor magnitude
Definition: HOG.java:25
cz.vutbr.feec.novak68.HOG.showGradientY
ImagePlus showGradientY()
Definition: HOG.java:315
cz.vutbr.feec.novak68.HOG.useFilter
void useFilter(HOGFilter filter)
Definition: HOG.java:161
cz.vutbr.feec.novak68.HOG.cells
float[][][] cells
Definition: HOG.java:31
cz.vutbr.feec.novak68.HOG.showOrientation
ImagePlus showOrientation()
Definition: HOG.java:335
cz.vutbr.feec.novak68.HOG.displayAngles
ImagePlus displayAngles()
Definition: HOG.java:168
cz.vutbr.feec.novak68.HOG.showMagnification
ImagePlus showMagnification()
Definition: HOG.java:325
cz.vutbr.feec.novak68.hogfilters.StrengthElementFilter
Definition: StrengthElementFilter.java:9
cz.vutbr.feec.novak68.HOG.cellCountX
int cellCountX
Definition: HOG.java:27
cz.vutbr.feec.novak68.HOG.compute
void compute(boolean normalize)
Definition: HOG.java:48
cz.vutbr.feec.novak68.HOG.dY
ImageProcessor dY
Definition: HOG.java:30
cz.vutbr.feec.novak68.HOG.getImageSize
int[] getImageSize()
Definition: HOG.java:351
cz.vutbr.feec.novak68.HOG.getCells
float[][][] getCells()
Definition: HOG.java:345
cz.vutbr.feec.novak68.HOG.cellsCopy
float[][][] cellsCopy
Definition: HOG.java:32
cz.vutbr.feec.novak68.HOG.orientation
FloatProcessor orientation
Definition: HOG.java:26
cz.vutbr.feec.novak68.HOG.DISP_WIDTH
final int DISP_WIDTH
Definition: HOG.java:33
cz.vutbr.feec.novak68.HOG.cellSizeX
int cellSizeX
Definition: HOG.java:21
cz.vutbr.feec.novak68.HOG.compute
void compute()
Definition: HOG.java:47
cz.vutbr.feec.novak68.HOG.HOG
HOG(ImagePlus img, int cellSizeX, int cellSizeY, int numOfBins)
Definition: HOG.java:36
cz.vutbr.feec.novak68.HOG.DISP_HEIGHT
int DISP_HEIGHT
Definition: HOG.java:34
cz.vutbr.feec.novak68.hogfilters.HOGFilter
Definition: HOGFilter.java:8
cz.vutbr.feec.novak68.HOG.cellCountY
int cellCountY
Definition: HOG.java:28
cz.vutbr.feec.novak68.HOG
Definition: HOG.java:19
cz.vutbr.feec.novak68.HOG.numOfBins
int numOfBins
Definition: HOG.java:23
cz.vutbr.feec.novak68.HOG.img
ImagePlus img
Definition: HOG.java:20
cz.vutbr.feec.novak68.HOG.displayStrenghtOnly
void displayStrenghtOnly()
Definition: HOG.java:237
cz.vutbr.feec.novak68.HOG.computeBins
void computeBins(int cellSizeX, int cellSizeY, int numOfBins)
Definition: HOG.java:61