initial commit
This commit is contained in:
commit
1253955070
75 changed files with 13972 additions and 0 deletions
122
api/internal/analysis/analysis.go
Normal file
122
api/internal/analysis/analysis.go
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
// Package analysis inspects an uploaded picture and derives badges describing
|
||||
// what can be recognised in it.
|
||||
//
|
||||
// Two implementations are provided. LocalAnalyzer measures the picture's own
|
||||
// pixels and EXIF metadata and turns those measurements into scene and content
|
||||
// badges; it needs no external service and is fully deterministic. RemoteAnalyzer
|
||||
// delegates to an external inference service (a trained object-detection model)
|
||||
// and returns the labels that model predicts. The two can be combined, in which
|
||||
// case model labels take precedence over heuristics of the same name.
|
||||
package analysis
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"go-places-api/internal/domain"
|
||||
)
|
||||
|
||||
// Input is the picture to analyse.
|
||||
type Input struct {
|
||||
// ContentType is the MIME type as supplied by the client.
|
||||
ContentType string
|
||||
// Bytes is the complete encoded picture.
|
||||
Bytes []byte
|
||||
// MaxDimension bounds the longest edge used for pixel measurements. The
|
||||
// picture is downscaled before sampling so that cost does not grow with
|
||||
// megapixels. Zero means use the package default.
|
||||
MaxDimension int
|
||||
// Hints carries scene labels already known about the picture, which lets a
|
||||
// remote analyzer disambiguate using earlier results.
|
||||
Hints []string
|
||||
}
|
||||
|
||||
// Metadata is the capture information recovered from EXIF, if any.
|
||||
type Metadata struct {
|
||||
// Coordinate is the GPS position from the EXIF GPS IFD.
|
||||
Coordinate *domain.Coordinate
|
||||
// TakenAt is the original capture timestamp.
|
||||
TakenAt *time.Time
|
||||
// Make and Model identify the camera or phone.
|
||||
Make string
|
||||
Model string
|
||||
}
|
||||
|
||||
// Signals are the measurements taken from the pixels. Every field is
|
||||
// normalised to 0..1 so the badge rules can use a single comparable scale.
|
||||
type Signals struct {
|
||||
// Width and Height are the dimensions of the sampled image.
|
||||
Width int
|
||||
Height int
|
||||
|
||||
// Brightness is the mean perceptual luminance.
|
||||
Brightness float64
|
||||
// Saturation is the mean colour saturation.
|
||||
Saturation float64
|
||||
// Colorfulness is the spread of hue across the image, a stand-in for how
|
||||
// varied the scene is.
|
||||
Colorfulness float64
|
||||
// EdgeDensity is the fraction of pixels sitting on a strong gradient, which
|
||||
// indicates how much fine detail the picture holds.
|
||||
EdgeDensity float64
|
||||
|
||||
// HueWeights holds the fraction of pixels falling into each colour class:
|
||||
// blue, green, warm (red/orange/yellow), purple and achromatic.
|
||||
HueWeights HueWeights
|
||||
|
||||
// Top, Middle and Bottom hold the same measurements restricted to the
|
||||
// upper, central and lower horizontal bands of the picture. Sky, ground
|
||||
// and water all separate cleanly this way.
|
||||
Top Band
|
||||
Middle Band
|
||||
Bottom Band
|
||||
}
|
||||
|
||||
// Band is the measurement set for one horizontal third of a picture.
|
||||
type Band struct {
|
||||
Brightness float64
|
||||
Saturation float64
|
||||
EdgeDensity float64
|
||||
HueWeights HueWeights
|
||||
PixelShare float64
|
||||
PixelCount int
|
||||
}
|
||||
|
||||
// HueWeights is the distribution of pixels across colour classes. The values
|
||||
// sum to approximately 1 for a fully populated band.
|
||||
type HueWeights struct {
|
||||
Blue float64
|
||||
Green float64
|
||||
Warm float64
|
||||
// Purple covers magenta and violet, which read as neither blue nor warm.
|
||||
Purple float64
|
||||
// Achromatic is the share of pixels with little or no hue: greys, whites,
|
||||
// blacks and near-neutrals.
|
||||
Achromatic float64
|
||||
}
|
||||
|
||||
// Result is everything the pipeline learned about a picture.
|
||||
type Result struct {
|
||||
// Width and Height are the true dimensions of the encoded picture.
|
||||
Width int
|
||||
Height int
|
||||
// Signals are the pixel measurements, retained for debugging and for the
|
||||
// remote analyzer's fallback.
|
||||
Signals Signals
|
||||
// Metadata is what EXIF reported.
|
||||
Metadata Metadata
|
||||
// Badges are the conclusions drawn from the above.
|
||||
Badges []domain.Badge
|
||||
// Note carries a non-fatal warning, such as a degraded analyzer, so the
|
||||
// caller can record why the badge set may be incomplete.
|
||||
Note string
|
||||
}
|
||||
|
||||
// Analyzer inspects a picture.
|
||||
type Analyzer interface {
|
||||
// Name identifies the analyzer in badge sources.
|
||||
Name() string
|
||||
// Analyze inspects the picture. It returns an error only when the picture
|
||||
// cannot be inspected at all; a picture that yields no badges is a success.
|
||||
Analyze(ctx context.Context, in Input) (*Result, error)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue