Skip to content

Commit 0d5e352

Browse files
committed
Added as yet untested auto colour correlogram (fixed at 4 distance sets) distance calculator.
1 parent dfed780 commit 0d5e352

File tree

8 files changed

+208
-2
lines changed

8 files changed

+208
-2
lines changed

README.md

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,19 @@ The result is subtracted from Double.MAX_VALUE to create a descending scoring va
2424

2525
The first hash is sent in as a parameter: `param_hash`, the other is expected to be stored in a field also identified by a parameter: `param_field`.
2626

27+
## AutoColourCorrelogram
28+
This script will calculate a distance between a given 64x4 correlogram (4 distance sets) in the format:
29+
```
30+
X0Y0,X0Y1,X0Y2,X0Y4;X1Y0,X1Y1,X1Y2,X1Y3;...;X64Y0,X64Y1,X64Y2,X64Y3
31+
```
32+
Because in distance terms, the smaller the distance the more likely the match, an in elastic terms, the greater the score the more likely
33+
the match, we need to turn the score on its head. So the result returned is actually `Integer.MAX_VALUE - distance`.
34+
35+
If the parameter is incorrect, or the document does not have all the expected fields for the correlogram, the result will be `Integer.MAX_VALUE`.
36+
37+
The script expects that the correlogram is stored in a field called `correlogram` in the same format as the parameter is provided (see above).
38+
39+
2740
**See Usage Examples below for clarity.**
2841

2942
# Setup
@@ -34,7 +47,7 @@ The first hash is sent in as a parameter: `param_hash`, the other is expected to
3447
Include the following in your elasticsearch.yml config file:
3548

3649
script.native:
37-
hamming_distance.type: com.cameraforensics.elasticsearch.plugins.HammingDistanceScriptFactory
50+
hamming_distance.type: com.cameraforensics.elasticsearch.plugins.AutoColourCorrelogramDistanceScriptFactory
3851
euclidean_distance.type: com.cameraforensics.elasticsearch.plugins.EuclideanDistanceScriptFactory
3952

4053
**Note:** If you don’t do this, they still show up on the plugins list (see later) but you’ll get errors when you try to use either of them saying that elasticsearch can’t find the plugin.
@@ -124,4 +137,28 @@ produces something like:
124137
]
125138
}
126139
}
140+
}'
141+
142+
### Auto Colour Correlogram
143+
144+
curl -XPOST 'http://localhost:9200/twitter/_search?pretty' -d '{
145+
"query": {
146+
"function_score": {
147+
"min_score": IDEAL MIN SCORE HERE,
148+
"query":{
149+
"match_all":{}
150+
},
151+
"functions": [
152+
{
153+
"script_score": {
154+
"script": "autocolourcorrelogram",
155+
"lang" : "native",
156+
"params": {
157+
"param_acc": "CORRELOGRAM TO COMPARE WITH"
158+
}
159+
}
160+
}
161+
]
162+
}
163+
}
127164
}'

autocolourcorrelogram/build.gradle

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
group 'com.cameraforensics'
2+
version '2.4.1.0'
3+
4+
sourceCompatibility = JavaVersion.VERSION_1_7
5+
targetCompatibility = JavaVersion.VERSION_1_7
6+
7+
configurations {
8+
provided
9+
}
10+
11+
apply plugin: 'idea'
12+
13+
idea {
14+
module {
15+
scopes.PROVIDED.plus += [configurations.provided]
16+
}
17+
}
18+
19+
sourceSets {
20+
main.compileClasspath += configurations.provided
21+
test.compileClasspath += configurations.provided
22+
test.runtimeClasspath += configurations.provided
23+
}
24+
25+
jar {
26+
baseName = 'autocolourcorrelogram'
27+
version = '2.4.1.0'
28+
from {
29+
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
30+
}
31+
}
32+
33+
dependencies {
34+
provided 'org.elasticsearch:elasticsearch:2.4.1'
35+
compile "commons-codec:commons-codec:1.10"
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.cameraforensics.elasticsearch.plugins;
2+
3+
import org.elasticsearch.plugins.Plugin;
4+
import org.elasticsearch.script.ScriptModule;
5+
6+
public class AutoColourCorrelogramDistancePlugin extends Plugin {
7+
8+
private static final String PLUGIN_NAME = "autocolourcorrelogram";
9+
10+
@Override
11+
public String name() {
12+
return PLUGIN_NAME;
13+
}
14+
15+
@Override
16+
public String description() {
17+
return "A scoring function to calculate the distance between two Auto Colour Correlograms.";
18+
}
19+
20+
public void onModule(ScriptModule scriptModule) {
21+
scriptModule.registerScript(PLUGIN_NAME, AutoColourCorrelogramDistanceScriptFactory.class);
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package com.cameraforensics.elasticsearch.plugins;
2+
3+
import org.elasticsearch.index.fielddata.ScriptDocValues;
4+
import org.elasticsearch.script.AbstractFloatSearchScript;
5+
6+
import java.util.Map;
7+
8+
public class AutoColourCorrelogramDistanceScript extends AbstractFloatSearchScript {
9+
10+
private static final int SIZE_X = 64;
11+
private static final int SIZE_Y = 4;
12+
13+
private float[][] queryCorrelogram = new float[SIZE_X][SIZE_Y];
14+
15+
public AutoColourCorrelogramDistanceScript(Map<String, Object> params) {
16+
super();
17+
queryCorrelogram = parseCorrelogram((String) params.get("param_acc"));
18+
}
19+
20+
/**
21+
* EG: This:
22+
* ```
23+
* 11.0,9.0,7.0,7.0;13.0,12.0,12.0,11.0;8.0,5.0,4.0,3.0;10.0,7.0,6.0,6.0;5.0,3.0,2.0,1.0;3.0,0.0,0.0,0.0;2.0,0.0,0.0,0.0;0.0,0.0,0.0,0.0;10.0,8.0,6.0,5.0;8.0,4.0,3.0,2.0;12.0,10.0,9.0,8.0;10.0,7.0,6.0,5.0;8.0,5.0,4.0,3.0;10.0,6.0,3.0,1.0;1.0,0.0,0.0,0.0;0.0,0.0,0.0,0.0;6.0,3.0,1.0,1.0;3.0,0.0,0.0,0.0;3.0,1.0,0.0,0.0;0.0,0.0,0.0,0.0;0.0,0.0,0.0,0.0;0.0,0.0,0.0,0.0;0.0,0.0,0.0,0.0;0.0,0.0,0.0,0.0;7.0,3.0,2.0,2.0;4.0,1.0,0.0,0.0;3.0,0.0,0.0,0.0;0.0,0.0,0.0,0.0;1.0,0.0,0.0,0.0;0.0,0.0,0.0,0.0;1.0,0.0,0.0,0.0;0.0,0.0,0.0,0.0;7.0,3.0,1.0,1.0;15.0,14.0,13.0,13.0;10.0,7.0,6.0,4.0;15.0,15.0,14.0,14.0;13.0,11.0,9.0,8.0;15.0,15.0,15.0,15.0;1.0,0.0,0.0,0.0;10.0,7.0,5.0,3.0;11.0,8.0,6.0,5.0;12.0,10.0,9.0,9.0;13.0,11.0,10.0,9.0;4.0,1.0,0.0,0.0;5.0,2.0,1.0,0.0;0.0,0.0,0.0,0.0;0.0,0.0,0.0,0.0;0.0,0.0,0.0,0.0;8.0,5.0,3.0,2.0;9.0,7.0,5.0,5.0;5.0,2.0,1.0,0.0;0.0,0.0,0.0,0.0;1.0,0.0,0.0,0.0;0.0,0.0,0.0,0.0;0.0,0.0,0.0,0.0;0.0,0.0,0.0,0.0;11.0,8.0,7.0,6.0;11.0,8.0,7.0,7.0;6.0,2.0,1.0,0.0;2.0,0.0,0.0,0.0;2.0,0.0,0.0,0.0;0.0,0.0,0.0,0.0;0.0,0.0,0.0,0.0;0.0,0.0,0.0,0.0;
24+
* ```
25+
* will produce:
26+
* [[11.0, 9.0, 7.0, 7.0], [13.0, 12.0, 12.0, 11.0] ... ]
27+
* @param correlogramStr
28+
* @return
29+
*/
30+
private float[][] parseCorrelogram(String correlogramStr) {
31+
if (correlogramStr == null) {
32+
return null;
33+
}
34+
35+
float[][] correlogram = new float[SIZE_X][SIZE_Y];
36+
String[] rows = correlogramStr.split(";");
37+
if (rows.length != SIZE_X) {
38+
return null;
39+
}
40+
41+
for (int i = 0; i < rows.length; i++) {
42+
String[] cols = rows[i].split(",");
43+
if (cols.length != SIZE_Y) {
44+
return null;
45+
}
46+
47+
for (int j = 0; j < cols.length; j++) {
48+
try {
49+
correlogram[i][j] = Integer.parseInt(cols[j]);
50+
} catch (NumberFormatException nfe) {
51+
return null;
52+
}
53+
}
54+
}
55+
return correlogram;
56+
}
57+
58+
private float getDistance(float[][] correlogram, float[][] queryCorrelogram) {
59+
float result = 0;
60+
for (int i = 0; i < correlogram.length; i++) {
61+
float[] ints = correlogram[i];
62+
for (int j = 0; j < ints.length; j++) {
63+
result += (correlogram[i][j] > 0 ? (correlogram[i][j] / 2f) * Math.log((2f * correlogram[i][j]) / (correlogram[i][j] + queryCorrelogram[i][j])) : 0) +
64+
(queryCorrelogram[i][j] > 0 ? (queryCorrelogram[i][j] / 2f) * Math.log((2f * queryCorrelogram[i][j]) / (correlogram[i][j] + queryCorrelogram[i][j])) : 0);
65+
}
66+
}
67+
68+
return (float) Integer.MAX_VALUE - result;
69+
}
70+
71+
@Override
72+
public float runAsFloat() {
73+
if (queryCorrelogram == null) {
74+
return Integer.MAX_VALUE;
75+
}
76+
77+
float[][] correlogram = parseCorrelogram(((ScriptDocValues.Strings) doc().get("correlogram")).getValue());
78+
if (correlogram == null) {
79+
return Integer.MAX_VALUE;
80+
}
81+
82+
return getDistance(correlogram, queryCorrelogram);
83+
}
84+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.cameraforensics.elasticsearch.plugins;
2+
3+
import org.elasticsearch.common.Nullable;
4+
import org.elasticsearch.script.ExecutableScript;
5+
import org.elasticsearch.script.NativeScriptFactory;
6+
7+
import java.util.Map;
8+
9+
public class AutoColourCorrelogramDistanceScriptFactory implements NativeScriptFactory {
10+
@Override
11+
public ExecutableScript newScript(@Nullable Map<String, Object> params) {
12+
return new AutoColourCorrelogramDistanceScript(params);
13+
}
14+
15+
@Override
16+
public boolean needsScores() {
17+
return false;
18+
}
19+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
name=autocolourcorrelogram
2+
description=A scoring function to calculate the distance between two Auto Colour Correlograms.
3+
version=2.4.1.0
4+
jvm=true
5+
classname=com.cameraforensics.elasticsearch.plugins.AutoColourCorrelogramDistancePlugin
6+
java.version=1.7
7+
elasticsearch.version=2.4.1

settings.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
rootProject.name = 'elasticsearch-plugins'
22
include 'hammingdistance'
33
include 'euclideandistance'
4+
include 'autocolourcorrelogram'
45

travis-build.gradle

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
group 'com.cameraforensics'
22
version '2.4.1'
33

4-
apply plugin: 'java'
54
apply plugin: 'java'
65

76
sourceCompatibility = JavaVersion.VERSION_1_7

0 commit comments

Comments
 (0)