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.feature.global;
31
32 import gnu.trove.map.hash.TObjectFloatHashMap;
33 import gnu.trove.procedure.TObjectFloatProcedure;
34
35 import org.openimaj.citation.annotation.Reference;
36 import org.openimaj.citation.annotation.ReferenceType;
37 import org.openimaj.citation.annotation.References;
38 import org.openimaj.feature.DoubleFV;
39 import org.openimaj.feature.FeatureVectorProvider;
40 import org.openimaj.image.FImage;
41 import org.openimaj.image.MBFImage;
42 import org.openimaj.image.analyser.ImageAnalyser;
43 import org.openimaj.image.pixel.ConnectedComponent;
44 import org.openimaj.image.pixel.statistics.MaskingHistogramModel;
45 import org.openimaj.image.processor.connectedcomponent.render.BoundingBoxRenderer;
46 import org.openimaj.image.saliency.AchantaSaliency;
47 import org.openimaj.image.saliency.YehSaliency;
48 import org.openimaj.image.segmentation.FelzenszwalbHuttenlocherSegmenter;
49 import org.openimaj.math.statistics.distribution.MultidimensionalHistogram;
50 import org.openimaj.util.array.ArrayUtils;
51
52
53
54
55
56
57
58
59
60
61 @References(references = {
62 @Reference(
63 type = ReferenceType.Inproceedings,
64 author = { "Luo, Yiwen", "Tang, Xiaoou" },
65 title = "Photo and Video Quality Evaluation: Focusing on the Subject",
66 year = "2008",
67 booktitle = "Proceedings of the 10th European Conference on Computer Vision: Part III",
68 pages = { "386", "399" },
69 url = "http://dx.doi.org/10.1007/978-3-540-88690-7_29",
70 publisher = "Springer-Verlag",
71 series = "ECCV '08",
72 customData = { "isbn", "978-3-540-88689-1", "location", "Marseille, France", "numpages", "14", "doi",
73 "10.1007/978-3-540-88690-7_29", "acmid", "1478204", "address", "Berlin, Heidelberg" }),
74 @Reference(
75 type = ReferenceType.Inproceedings,
76 author = { "Che-Hua Yeh", "Yuan-Chen Ho", "Brian A. Barsky", "Ming Ouhyoung" },
77 title = "Personalized Photograph Ranking and Selection System",
78 year = "2010",
79 booktitle = "Proceedings of ACM Multimedia",
80 pages = { "211", "220" },
81 month = "October",
82 customData = { "location", "Florence, Italy" }) })
83 public class ModifiedLuoSimplicity implements ImageAnalyser<MBFImage>, FeatureVectorProvider<DoubleFV> {
84 protected YehSaliency extractor;
85 protected float alpha = 0.67f;
86
87 protected int binsPerBand = 16;
88 protected float gamma = 0.01f;
89 protected boolean boxMode = true;
90 protected double simplicity;
91
92
93
94
95 public ModifiedLuoSimplicity() {
96 extractor = new YehSaliency();
97 }
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122 public ModifiedLuoSimplicity(int binsPerBand, float gamma, boolean boxMode, float alpha, float saliencySigma,
123 float segmenterSigma, float k, int minSize)
124 {
125 extractor = new YehSaliency(saliencySigma, segmenterSigma, k, minSize);
126 this.binsPerBand = binsPerBand;
127 this.gamma = gamma;
128 this.boxMode = boxMode;
129 this.alpha = alpha;
130 }
131
132
133
134
135
136
137
138
139 @Override
140 public void analyseImage(MBFImage image) {
141 image.analyseWith(extractor);
142
143 FImage mask;
144 if (boxMode) {
145 final TObjectFloatHashMap<ConnectedComponent> componentMap = extractor.getSaliencyComponents();
146
147 final float max = ArrayUtils.maxValue(componentMap.values());
148
149 mask = new FImage(image.getWidth(), image.getHeight());
150 final float thresh = max * alpha;
151 final BoundingBoxRenderer<Float> renderer = new BoundingBoxRenderer<Float>(mask, 1F, true);
152
153 componentMap.forEachEntry(new TObjectFloatProcedure<ConnectedComponent>() {
154 @Override
155 public boolean execute(ConnectedComponent cc, float sal) {
156 if (sal >= thresh) {
157
158
159 renderer.process(cc);
160 }
161
162 return true;
163 }
164 });
165 } else {
166 mask = extractor.getSaliencyMap();
167 final float maskthresh = mask.max() * alpha;
168 mask = mask.threshold(maskthresh);
169 }
170
171 mask = mask.inverse();
172
173 final MaskingHistogramModel hm = new MaskingHistogramModel(mask, binsPerBand, binsPerBand, binsPerBand);
174 hm.estimateModel(image);
175
176 final MultidimensionalHistogram fv = hm.getFeatureVector();
177 final double thresh = gamma * fv.max();
178 int count = 0;
179 for (final double f : fv.values) {
180 if (f >= thresh)
181 count++;
182 }
183
184 simplicity = (double) count / (double) fv.values.length;
185 }
186
187 @Override
188 public DoubleFV getFeatureVector() {
189 return new DoubleFV(new double[] { simplicity });
190 }
191 }