Classify: Improve moments & location labels
This commit is contained in:
parent
32ef03083d
commit
d42eb4e01b
11 changed files with 148 additions and 26 deletions
|
@ -16,7 +16,9 @@ type Label struct {
|
|||
}
|
||||
|
||||
// LocationLabel returns a new location label.
|
||||
func LocationLabel(name string, uncertainty int, priority int) Label {
|
||||
func LocationLabel(name string, uncertainty int) Label {
|
||||
priority := -1
|
||||
|
||||
if index := strings.Index(name, " / "); index > 1 {
|
||||
name = name[:index]
|
||||
}
|
||||
|
@ -25,9 +27,20 @@ func LocationLabel(name string, uncertainty int, priority int) Label {
|
|||
name = name[:index]
|
||||
}
|
||||
|
||||
label := Label{Name: name, Source: SrcLocation, Uncertainty: uncertainty, Priority: priority}
|
||||
var categories []string
|
||||
|
||||
return label
|
||||
if rule, ok := rules.Find(name); ok {
|
||||
priority = rule.Priority
|
||||
categories = rule.Categories
|
||||
}
|
||||
|
||||
return Label{
|
||||
Name: name,
|
||||
Source: SrcLocation,
|
||||
Uncertainty: uncertainty,
|
||||
Priority: priority,
|
||||
Categories: categories,
|
||||
}
|
||||
}
|
||||
|
||||
// Title returns a formatted label title as string.
|
||||
|
|
|
@ -12,10 +12,10 @@ type LabelRule struct {
|
|||
type LabelRules map[string]LabelRule
|
||||
|
||||
// Find is a getter for LabelRules that give a default rule with a non-zero threshold for missing keys
|
||||
func (rules LabelRules) Find(label string) LabelRule {
|
||||
func (rules LabelRules) Find(label string) (rule LabelRule, ok bool) {
|
||||
if rule, ok := rules[label]; ok {
|
||||
return rule
|
||||
return rule, true
|
||||
}
|
||||
|
||||
return LabelRule{Threshold: 0.1}
|
||||
return LabelRule{Threshold: 0.1}, false
|
||||
}
|
||||
|
|
|
@ -23,13 +23,15 @@ func TestLabelRule_Find(t *testing.T) {
|
|||
}
|
||||
|
||||
t.Run("existing rule", func(t *testing.T) {
|
||||
result := rules.Find("cat")
|
||||
result, ok := rules.Find("cat")
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, -2, result.Priority)
|
||||
assert.Equal(t, float32(1), result.Threshold)
|
||||
})
|
||||
|
||||
t.Run("not existing rule", func(t *testing.T) {
|
||||
result := rules.Find("fish")
|
||||
result, ok := rules.Find("fish")
|
||||
assert.False(t, ok)
|
||||
t.Log(result)
|
||||
assert.Equal(t, float32(0.1), result.Threshold)
|
||||
})
|
||||
|
|
|
@ -7,14 +7,14 @@ import (
|
|||
)
|
||||
|
||||
func TestLabel_NewLocationLabel(t *testing.T) {
|
||||
LocLabel := LocationLabel("locationtest", 23, 1)
|
||||
LocLabel := LocationLabel("locationtest", 23)
|
||||
t.Log(LocLabel)
|
||||
assert.Equal(t, "location", LocLabel.Source)
|
||||
assert.Equal(t, 23, LocLabel.Uncertainty)
|
||||
assert.Equal(t, "locationtest", LocLabel.Name)
|
||||
|
||||
t.Run("locationtest / slash", func(t *testing.T) {
|
||||
LocLabel := LocationLabel("locationtest / slash", 24, -2)
|
||||
LocLabel := LocationLabel("locationtest / slash", 24)
|
||||
t.Log(LocLabel)
|
||||
assert.Equal(t, "location", LocLabel.Source)
|
||||
assert.Equal(t, 24, LocLabel.Uncertainty)
|
||||
|
@ -22,7 +22,7 @@ func TestLabel_NewLocationLabel(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("locationtest - minus", func(t *testing.T) {
|
||||
LocLabel := LocationLabel("locationtest - minus", 80, -2)
|
||||
LocLabel := LocationLabel("locationtest - minus", 80)
|
||||
t.Log(LocLabel)
|
||||
assert.Equal(t, "location", LocLabel.Source)
|
||||
assert.Equal(t, 80, LocLabel.Uncertainty)
|
||||
|
@ -32,12 +32,12 @@ func TestLabel_NewLocationLabel(t *testing.T) {
|
|||
|
||||
func TestLabel_Title(t *testing.T) {
|
||||
t.Run("locationtest123", func(t *testing.T) {
|
||||
LocLabel := LocationLabel("locationtest123", 23, 1)
|
||||
LocLabel := LocationLabel("locationtest123", 23)
|
||||
assert.Equal(t, "Locationtest123", LocLabel.Title())
|
||||
})
|
||||
|
||||
t.Run("Berlin/Neukölln", func(t *testing.T) {
|
||||
LocLabel := LocationLabel("berlin/neukölln_hasenheide", 23, 1)
|
||||
LocLabel := LocationLabel("berlin/neukölln_hasenheide", 23)
|
||||
assert.Equal(t, "Berlin / Neukölln Hasenheide", LocLabel.Title())
|
||||
})
|
||||
}
|
||||
|
|
|
@ -144,7 +144,7 @@ var rules = LabelRules{
|
|||
Label: "alpine",
|
||||
Threshold: 0.400000,
|
||||
Priority: 0,
|
||||
Categories: []string{"landscape", "mountains"},
|
||||
Categories: []string{"landscape", "mountain"},
|
||||
},
|
||||
"altar": {
|
||||
Label: "",
|
||||
|
@ -524,6 +524,12 @@ var rules = LabelRules{
|
|||
Priority: 0,
|
||||
Categories: []string{},
|
||||
},
|
||||
"beach": {
|
||||
Label: "",
|
||||
Threshold: 0.000000,
|
||||
Priority: 1,
|
||||
Categories: []string{"water"},
|
||||
},
|
||||
"beach wagon": {
|
||||
Label: "car",
|
||||
Threshold: 0.400000,
|
||||
|
@ -2072,6 +2078,12 @@ var rules = LabelRules{
|
|||
Priority: -2,
|
||||
Categories: []string{},
|
||||
},
|
||||
"fart machine": {
|
||||
Label: "",
|
||||
Threshold: 1.000000,
|
||||
Priority: -2,
|
||||
Categories: []string{},
|
||||
},
|
||||
"fashion": {
|
||||
Label: "portrait",
|
||||
Threshold: 0.500000,
|
||||
|
@ -2288,6 +2300,12 @@ var rules = LabelRules{
|
|||
Priority: 0,
|
||||
Categories: []string{"portrait"},
|
||||
},
|
||||
"gallery": {
|
||||
Label: "",
|
||||
Threshold: 0.500000,
|
||||
Priority: 0,
|
||||
Categories: []string{},
|
||||
},
|
||||
"gar fish": {
|
||||
Label: "fish",
|
||||
Threshold: 0.480000,
|
||||
|
@ -3608,6 +3626,12 @@ var rules = LabelRules{
|
|||
Priority: 0,
|
||||
Categories: []string{},
|
||||
},
|
||||
"memorial": {
|
||||
Label: "",
|
||||
Threshold: 0.500000,
|
||||
Priority: 0,
|
||||
Categories: []string{},
|
||||
},
|
||||
"menu": {
|
||||
Label: "document",
|
||||
Threshold: 0.500000,
|
||||
|
@ -3800,6 +3824,12 @@ var rules = LabelRules{
|
|||
Priority: 0,
|
||||
Categories: []string{"outdoor"},
|
||||
},
|
||||
"mountains": {
|
||||
Label: "mountain",
|
||||
Threshold: 0.400000,
|
||||
Priority: 0,
|
||||
Categories: []string{},
|
||||
},
|
||||
"mouse": {
|
||||
Label: "computer",
|
||||
Threshold: 0.200000,
|
||||
|
@ -4100,6 +4130,12 @@ var rules = LabelRules{
|
|||
Priority: -2,
|
||||
Categories: []string{},
|
||||
},
|
||||
"park": {
|
||||
Label: "",
|
||||
Threshold: 0.500000,
|
||||
Priority: 0,
|
||||
Categories: []string{"outdoor"},
|
||||
},
|
||||
"park bench": {
|
||||
Label: "bench",
|
||||
Threshold: 0.520000,
|
||||
|
@ -4954,9 +4990,9 @@ var rules = LabelRules{
|
|||
},
|
||||
"sea cucumber": {
|
||||
Label: "",
|
||||
Threshold: 0.800000,
|
||||
Priority: 0,
|
||||
Categories: []string{"water", "animal"},
|
||||
Threshold: 1.000000,
|
||||
Priority: -2,
|
||||
Categories: []string{},
|
||||
},
|
||||
"sea lion": {
|
||||
Label: "",
|
||||
|
@ -6032,6 +6068,12 @@ var rules = LabelRules{
|
|||
Priority: 0,
|
||||
Categories: []string{"architecture"},
|
||||
},
|
||||
"viewpoint": {
|
||||
Label: "",
|
||||
Threshold: 0.500000,
|
||||
Priority: 0,
|
||||
Categories: []string{"outdoor"},
|
||||
},
|
||||
"vine snake": {
|
||||
Label: "animal",
|
||||
Threshold: 0.900000,
|
||||
|
|
|
@ -1808,10 +1808,7 @@ sea urchin:
|
|||
see: ignore
|
||||
|
||||
sea cucumber:
|
||||
threshold: 0.8
|
||||
categories:
|
||||
- water
|
||||
- animal
|
||||
see: ignore
|
||||
|
||||
rabbit:
|
||||
label: rabbit
|
||||
|
@ -3877,7 +3874,7 @@ alp:
|
|||
threshold: 0.4
|
||||
categories:
|
||||
- landscape
|
||||
- mountains
|
||||
- mountain
|
||||
|
||||
cliff:
|
||||
label: landscape
|
||||
|
@ -4657,3 +4654,31 @@ scabbard:
|
|||
street sign:
|
||||
label: sign
|
||||
threshold: 0.12
|
||||
|
||||
fart machine:
|
||||
see: ignore
|
||||
|
||||
gallery:
|
||||
threshold: 0.5
|
||||
|
||||
beach:
|
||||
priority: 1
|
||||
categories:
|
||||
- water
|
||||
|
||||
park:
|
||||
threshold: 0.5
|
||||
categories:
|
||||
- outdoor
|
||||
|
||||
viewpoint:
|
||||
threshold: 0.5
|
||||
categories:
|
||||
- outdoor
|
||||
|
||||
memorial:
|
||||
threshold: 0.5
|
||||
|
||||
mountains:
|
||||
label: mountain
|
||||
threshold: 0.4
|
|
@ -7,7 +7,8 @@ import (
|
|||
)
|
||||
|
||||
func TestLabelRules_Find(t *testing.T) {
|
||||
result := rules.Find("cat")
|
||||
result, ok := rules.Find("cat")
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, "cat", result.Label)
|
||||
assert.Equal(t, "animal", result.Categories[0])
|
||||
assert.Equal(t, 5, result.Priority)
|
||||
|
|
|
@ -172,7 +172,7 @@ func (t *TensorFlow) bestLabels(probabilities []float32) Labels {
|
|||
|
||||
labelText := strings.ToLower(t.labels[i])
|
||||
|
||||
rule := rules.Find(labelText)
|
||||
rule, _ := rules.Find(labelText)
|
||||
|
||||
// discard labels that don't met the threshold
|
||||
if p < rule.Threshold {
|
||||
|
|
|
@ -102,7 +102,7 @@ func (m *Photo) UpdateLocation() (keywords []string, labels classify.Labels) {
|
|||
|
||||
// Append category from reverse location lookup
|
||||
if locCategory != "" {
|
||||
labels = append(labels, classify.LocationLabel(locCategory, 0, -1))
|
||||
labels = append(labels, classify.LocationLabel(locCategory, 0))
|
||||
}
|
||||
|
||||
return keywords, labels
|
||||
|
|
|
@ -36,6 +36,7 @@ var UnwantedDescriptions = map[string]bool{
|
|||
"qrf": true,
|
||||
"binary comment": true,
|
||||
"default": true,
|
||||
"Exif_JPEG_PICTURE": true,
|
||||
}
|
||||
|
||||
var LowerCaseRegexp = regexp.MustCompile("[a-z0-9_\\-]+")
|
||||
|
|
|
@ -20,16 +20,54 @@ type Moment struct {
|
|||
}
|
||||
|
||||
var MomentLabels = map[string]string{
|
||||
"botanical-garden": "Botanical Gardens",
|
||||
"park": "Parks & Gardens",
|
||||
"botanical-garden": "Parks & Gardens",
|
||||
"water-park": "Parks & Gardens",
|
||||
"alpine": "Outdoor Adventures",
|
||||
"hiking": "Outdoor Adventures",
|
||||
"mountain": "Outdoor Adventures",
|
||||
"mountains": "Outdoor Adventures",
|
||||
"camping": "Outdoor Adventures",
|
||||
"camper": "Outdoor Adventures",
|
||||
"bench": "Outdoor Adventures",
|
||||
"bunker": "Outdoor Adventures",
|
||||
"castle": "Outdoor Adventures",
|
||||
"viewpoint": "Outdoor Adventures",
|
||||
"nature-reserve": "Nature & Landscape",
|
||||
"landscape": "Nature & Landscape",
|
||||
"nature": "Nature & Landscape",
|
||||
"flower": "Nature & Landscape",
|
||||
"field": "Nature & Landscape",
|
||||
"forest": "Nature & Landscape",
|
||||
"rocks": "Nature & Landscape",
|
||||
"valley": "Nature & Landscape",
|
||||
"bay": "Bays, Capes & Beaches",
|
||||
"beach": "Bays, Capes & Beaches",
|
||||
"seashore": "Bays, Capes & Beaches",
|
||||
"cape": "Bays, Capes & Beaches",
|
||||
"ship": "Water, Ships & Boats",
|
||||
"water": "Water, Ships & Boats",
|
||||
"pier": "Water, Ships & Boats",
|
||||
"boat": "Water, Ships & Boats",
|
||||
"boathouse": "Water, Ships & Boats",
|
||||
"lakeside": "Water, Ships & Boats",
|
||||
"shark": "Water, Ships & Boats",
|
||||
"fish": "Water, Ships & Boats",
|
||||
"jellyfish": "Water, Ships & Boats",
|
||||
"submarine": "Water, Ships & Boats",
|
||||
"diving": "Water, Ships & Boats",
|
||||
"festival": "Festivals & Entertainment",
|
||||
"nightclub": "Festivals & Entertainment",
|
||||
"microphone": "Festivals & Entertainment",
|
||||
"stage": "Festivals & Entertainment",
|
||||
"theater": "Festivals & Entertainment",
|
||||
"theme park": "Festivals & Entertainment",
|
||||
"event": "Festivals & Entertainment",
|
||||
"wine": "Festivals & Entertainment",
|
||||
"cat": "Pets",
|
||||
"dog": "Pets",
|
||||
"rabbit": "Pets",
|
||||
"hamster": "Pets",
|
||||
}
|
||||
|
||||
// Slug returns an identifier string for a moment.
|
||||
|
|
Loading…
Reference in a new issue