Classify: Improve moments & location labels

This commit is contained in:
Michael Mayer 2021-02-21 17:18:36 +01:00
parent 32ef03083d
commit d42eb4e01b
11 changed files with 148 additions and 26 deletions

View file

@ -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.

View file

@ -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
}

View file

@ -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)
})

View file

@ -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())
})
}

View file

@ -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,

View file

@ -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

View file

@ -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)

View file

@ -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 {

View file

@ -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

View file

@ -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_\\-]+")

View file

@ -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.