diff --git a/vips/arithmetic.c b/vips/arithmetic.c index 557f613c..6356d814 100644 --- a/vips/arithmetic.c +++ b/vips/arithmetic.c @@ -28,6 +28,13 @@ int average(VipsImage *in, double *out) { return vips_avg(in, out, NULL); } +int maxpos(VipsImage *in, double *out, int *x, int *y) { + return vips_max(in, out, "x", x, "y", y, NULL); +} + +int minpos(VipsImage *in, double *out, int *x, int *y) { + return vips_min(in, out, "x", x, "y", y, NULL); +} int find_trim(VipsImage *in, int *left, int *top, int *width, int *height, double threshold, double r, double g, double b) { @@ -58,6 +65,10 @@ int hist_find(VipsImage *in, VipsImage **out) { return vips_hist_find(in, out, NULL); } +int hist_find_ndim(VipsImage *in, VipsImage **out, int bins) { + return vips_hist_find_ndim(in, out, "bins", bins, NULL); +} + int hist_cum(VipsImage *in, VipsImage **out) { return vips_hist_cum(in, out, NULL); } diff --git a/vips/arithmetic.go b/vips/arithmetic.go index 3bdf5baa..98cbd7d4 100644 --- a/vips/arithmetic.go +++ b/vips/arithmetic.go @@ -139,6 +139,44 @@ func vipsHistFind(in *C.VipsImage) (*C.VipsImage, error) { return out, nil } +// https://www.libvips.org/API/current/libvips-arithmetic.html#vips-hist-find-ndim +func vipsHistFindNdim(in *C.VipsImage, bins int) (*C.VipsImage, error) { + incOpCounter("histFindNdim") + var out *C.VipsImage + + if err := C.hist_find_ndim(in, &out, C.int(bins)); err != 0 { + return nil, handleImageError(out) + } + + return out, nil +} + +// https://www.libvips.org/API/current/libvips-arithmetic.html#vips-max +func vipsMax(in *C.VipsImage) (int, int, error) { + incOpCounter("max") + var out C.double + var x, y C.int + + if err := C.maxpos(in, &out, &x, &y); err != 0 { + return -1, -1, handleVipsError() + } + + return int(x), int(y), nil +} + +// https://www.libvips.org/API/current/libvips-arithmetic.html#vips-min +func vipsMin(in *C.VipsImage) (int, int, error) { + incOpCounter("min") + var out C.double + var x, y C.int + + if err := C.maxpos(in, &out, &x, &y); err != 0 { + return -1, -1, handleVipsError() + } + + return int(x), int(y), nil +} + // https://www.libvips.org/API/current/libvips-histogram.html#vips-hist-norm func vipsHistNorm(in *C.VipsImage) (*C.VipsImage, error) { incOpCounter("histNorm") diff --git a/vips/arithmetic.h b/vips/arithmetic.h index 693b4fdd..eb484a41 100644 --- a/vips/arithmetic.h +++ b/vips/arithmetic.h @@ -14,7 +14,10 @@ int find_trim(VipsImage *in, int *left, int *top, int *width, int *height, double threshold, double r, double g, double b); int getpoint(VipsImage *in, double **vector, int n, int x, int y); int stats(VipsImage *in, VipsImage **out); +int maxpos(VipsImage *in, double *out, int *x, int *y); +int minpos(VipsImage *in, double *out, int *x, int *y); int hist_find(VipsImage *in, VipsImage **out); +int hist_find_ndim(VipsImage *in, VipsImage **out, int bins); int hist_cum(VipsImage *in, VipsImage **out); int hist_norm(VipsImage *in, VipsImage **out); int hist_entropy(VipsImage *in, double *out); diff --git a/vips/image.go b/vips/image.go index 24ff6cf0..d02a9daa 100644 --- a/vips/image.go +++ b/vips/image.go @@ -1708,7 +1708,7 @@ func (r *ImageRef) Stats() error { return nil } -// HistogramFind find the histogram the image. +// HistogramFind find the histogram of the image. // Find the histogram for all bands (producing a one-band histogram). // char and uchar images are cast to uchar before histogramming, all other image types are cast to ushort. func (r *ImageRef) HistogramFind() error { @@ -1720,6 +1720,26 @@ func (r *ImageRef) HistogramFind() error { return nil } +// Make a one, two or three dimensional histogram of a 1, 2 or 3 band image. Divide each axis into `bins` bins .. ie. output is 1 x bins, bins x bins, or bins x bins x bins bands. bins defaults to 10. +func (r *ImageRef) HistogramFindNdim(bins int) error { + out, err := vipsHistFindNdim(r.image, bins) + if err != nil { + return err + } + r.setImage(out) + return nil +} + +// This operation finds the maximum value in an image. +func (r *ImageRef) MaxPos() (x, y int, err error) { + return vipsMax(r.image) +} + +// This operation finds the maximum value in an image. +func (r *ImageRef) MinPos() (x, y int, err error) { + return vipsMin(r.image) +} + // HistogramCumulative form cumulative histogram. func (r *ImageRef) HistogramCumulative() error { out, err := vipsHistCum(r.image)