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  }