github.com/weaviate/weaviate@v1.24.6/modules/img2vec-neural/vectorizer/vectorizer.go (about) 1 // _ _ 2 // __ _____ __ ___ ___ __ _| |_ ___ 3 // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ 4 // \ V V / __/ (_| |\ V /| | (_| | || __/ 5 // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| 6 // 7 // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. 8 // 9 // CONTACT: hello@weaviate.io 10 // 11 12 package vectorizer 13 14 import ( 15 "context" 16 "fmt" 17 18 "github.com/go-openapi/strfmt" 19 "github.com/weaviate/weaviate/entities/models" 20 "github.com/weaviate/weaviate/entities/moduletools" 21 "github.com/weaviate/weaviate/modules/img2vec-neural/ent" 22 libvectorizer "github.com/weaviate/weaviate/usecases/vectorizer" 23 ) 24 25 type Vectorizer struct { 26 client Client 27 } 28 29 func New(client Client) *Vectorizer { 30 return &Vectorizer{ 31 client: client, 32 } 33 } 34 35 type Client interface { 36 Vectorize(ctx context.Context, 37 id, image string) (*ent.VectorizationResult, error) 38 } 39 40 type ClassSettings interface { 41 ImageField(property string) bool 42 } 43 44 func (v *Vectorizer) Object(ctx context.Context, object *models.Object, 45 comp moduletools.VectorizablePropsComparator, cfg moduletools.ClassConfig, 46 ) ([]float32, models.AdditionalProperties, error) { 47 vec, err := v.object(ctx, object.ID, comp, cfg) 48 return vec, nil, err 49 } 50 51 func (v *Vectorizer) VectorizeImage(ctx context.Context, id, image string, cfg moduletools.ClassConfig) ([]float32, error) { 52 res, err := v.client.Vectorize(ctx, id, image) 53 if err != nil { 54 return nil, err 55 } 56 57 return res.Vector, nil 58 } 59 60 func (v *Vectorizer) object(ctx context.Context, id strfmt.UUID, 61 comp moduletools.VectorizablePropsComparator, cfg moduletools.ClassConfig, 62 ) ([]float32, error) { 63 ichek := NewClassSettings(cfg) 64 prevVector := comp.PrevVector() 65 if cfg.TargetVector() != "" { 66 prevVector = comp.PrevVectorForName(cfg.TargetVector()) 67 } 68 69 vectorize := prevVector == nil 70 71 // vectorize image 72 images := []string{} 73 74 it := comp.PropsIterator() 75 for propName, propValue, ok := it.Next(); ok; propName, propValue, ok = it.Next() { 76 if !ichek.ImageField(propName) { 77 continue 78 } 79 80 switch typed := propValue.(type) { 81 case string: 82 vectorize = vectorize || comp.IsChanged(propName) 83 images = append(images, typed) 84 85 case nil: 86 vectorize = vectorize || comp.IsChanged(propName) 87 } 88 } 89 90 // no property was changed, old vector can be used 91 if !vectorize { 92 return prevVector, nil 93 } 94 95 vectors := [][]float32{} 96 for i, image := range images { 97 imgID := fmt.Sprintf("%s_%v", id, i) 98 vector, err := v.VectorizeImage(ctx, imgID, image, cfg) 99 if err != nil { 100 return nil, err 101 } 102 vectors = append(vectors, vector) 103 } 104 105 return libvectorizer.CombineVectors(vectors), nil 106 }