package tensorflow import ( "bufio" iofs "io/fs" "os" "path/filepath" "github.com/photoprism/photoprism/pkg/clean" ) func loadLabelsFromPath(path string) (labels []string, err error) { log.Infof("vision: loading TensorFlow model labels from %s", path) f, err := os.Open(path) //nolint:gosec // path originates from known model directory; reading labels is expected if err != nil { return nil, err } defer f.Close() scanner := bufio.NewScanner(f) // Labels are separated by newlines for scanner.Scan() { labels = append(labels, scanner.Text()) } err = scanner.Err() return labels, err } // LoadLabels loads the labels of classification models from the specified path and returns them. func LoadLabels(modelPath string, expectedLabels int) (labels []string, err error) { dir := os.DirFS(modelPath) matches, err := iofs.Glob(dir, "labels*.txt") if err != nil { return nil, err } for i := range matches { loadedLabels, labelsErr := loadLabelsFromPath(filepath.Join(modelPath, matches[i])) if labelsErr != nil { return nil, labelsErr } switch expectedLabels - len(loadedLabels) { case 0: log.Infof("vision: found valid labels in %s", clean.Log(matches[i])) return loadedLabels, nil case 1: log.Infof("vision: found valid labels in %s, but bias needs to be added", clean.Log(matches[i])) return append([]string{"background"}, loadedLabels...), nil default: log.Infof("vision: invalid labels file, expected %d labels and found %d", expectedLabels, len(loadedLabels)) } } return nil, os.ErrNotExist }