1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package org.openimaj.image.model.landmark;
31
32 import org.openimaj.image.FImage;
33 import org.openimaj.image.analysis.algorithm.TemplateMatcher;
34 import org.openimaj.image.analysis.algorithm.TemplateMatcher.Mode;
35 import org.openimaj.image.pixel.FValuePixel;
36 import org.openimaj.math.geometry.point.Point2d;
37 import org.openimaj.math.geometry.point.PointList;
38 import org.openimaj.math.geometry.shape.Rectangle;
39 import org.openimaj.util.pair.ObjectFloatPair;
40
41
42
43
44
45
46
47 public class FPatchLandmarkModel implements LandmarkModel<FImage> {
48
49
50
51
52
53 public static class Factory implements LandmarkModelFactory<FImage> {
54 @Override
55 public LandmarkModel<FImage> createLandmarkModel() {
56 return new FPatchLandmarkModel();
57 }
58
59 @Override
60 public LandmarkModel<FImage> createLandmarkModel(float scaleFactor) {
61 return new FPatchLandmarkModel();
62 }
63 }
64
65 int blockSize = 11;
66 int searchSize = 31;
67
68 FImage average;
69 int n = 0;
70 TemplateMatcher matcher;
71
72 protected Rectangle getROI(int x, int y, int w, int h) {
73 if(w % 2 == 0 ) w+=1;
74 if(h % 2 == 0 ) h+=1;
75
76 int roiX = Math.max(0,x-(int)(w/2.0));
77 int roiY = Math.max(0,y-(int)(h/2.0));
78
79 int newWidth = (int)(w / 2.0) + 1 + (x - roiX);
80 int newHeight = (int)(h / 2.0) + 1 + (y - roiY);
81
82 return new Rectangle(roiX, roiY, newWidth, newHeight);
83 }
84
85 protected FImage extractBlock(FImage image, Point2d pt, int sz) {
86 return image.extractROI(getROI((int)pt.getX(), (int)pt.getY(), sz, sz));
87 }
88
89 @Override
90 public void updateModel(FImage image, Point2d point, PointList pointList) {
91 FImage extracted = extractBlock(image, point, blockSize);
92
93 n++;
94 if (average == null) {
95 average = extracted;
96 } else {
97 average.addInplace( extracted.subtractInplace(average).divide((float)n) );
98 }
99 matcher = null;
100 }
101
102 @Override
103 public float computeCost(FImage image, Point2d point, PointList pointList) {
104 FImage extracted = extractBlock(image, point, blockSize);
105
106 if (matcher == null)
107 matcher = new TemplateMatcher(average, Mode.NORM_SUM_SQUARED_DIFFERENCE);
108
109 matcher.setSearchBounds(null);
110 extracted.analyseWith(matcher);
111
112 return matcher.getResponseMap().pixels[0][0];
113 }
114
115 @Override
116 public ObjectFloatPair<Point2d> updatePosition(FImage image, Point2d initial, PointList pointList) {
117 Rectangle roi = getROI((int)initial.getX(), (int)initial.getY(), searchSize, searchSize);
118
119 if (matcher == null)
120 matcher = new TemplateMatcher(average, Mode.NORM_SUM_SQUARED_DIFFERENCE);
121
122 matcher.setSearchBounds(roi);
123 image.analyseWith(matcher);
124 FValuePixel p = matcher.getBestResponses(1)[0];
125
126 return new ObjectFloatPair<Point2d>(p, 0);
127 }
128 }