almost done compass
This commit is contained in:
parent
4d724c0023
commit
e74a0b71d9
7
TODO
7
TODO
@ -1,5 +1,12 @@
|
||||
- started compass .. convolution with a rotating mask
|
||||
|
||||
vips im_gradient k2.jpg x.v line.mat
|
||||
vips compass k2.jpg x2.v line.mat --times 2 --angle 90 --combine sum
|
||||
|
||||
should give the same result, you'd think
|
||||
|
||||
deprecated/vips7compat.c defs for compass/grad/lindet commented out for now
|
||||
|
||||
need to do sep
|
||||
|
||||
- do conv and morph quickly as simple wrappers over the vips7 operations
|
||||
|
@ -4,6 +4,7 @@ libconvolution_la_SOURCES = \
|
||||
convolution.c \
|
||||
pconvolution.h \
|
||||
conv.c \
|
||||
compass.c \
|
||||
morph.c \
|
||||
convol_dispatch.c \
|
||||
im_addgnoise.c \
|
||||
|
@ -31,11 +31,6 @@
|
||||
|
||||
*/
|
||||
|
||||
/* This is a simple wrapper over the old vips7 functions. At some point we
|
||||
* should rewrite this as a pure vips8 class and redo the vips7 functions as
|
||||
* wrappers over this.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
@ -51,8 +46,11 @@ typedef struct {
|
||||
VipsConvolution parent_instance;
|
||||
|
||||
int times;
|
||||
VipsRotate45 angle;
|
||||
int join;
|
||||
VipsAngle45 angle;
|
||||
VipsCombine combine;
|
||||
VipsPrecision precision;
|
||||
int layers;
|
||||
int cluster;
|
||||
} VipsCompass;
|
||||
|
||||
typedef VipsConvolutionClass VipsCompassClass;
|
||||
@ -64,12 +62,73 @@ vips_compass_build( VipsObject *object )
|
||||
{
|
||||
VipsConvolution *convolution = (VipsConvolution *) object;
|
||||
VipsCompass *compass = (VipsCompass *) object;
|
||||
VipsImage **masks;
|
||||
VipsImage *mask;
|
||||
VipsImage **images;
|
||||
int i;
|
||||
VipsImage **abs;
|
||||
VipsImage **combine;
|
||||
VipsImage *x;
|
||||
|
||||
g_object_set( compass, "out", vips_image_new(), NULL );
|
||||
|
||||
if( VIPS_OBJECT_CLASS( vips_compass_parent_class )->build( object ) )
|
||||
return( -1 );
|
||||
|
||||
masks = (VipsImage **)
|
||||
vips_object_local_array( object, compass->times );
|
||||
images = (VipsImage **)
|
||||
vips_object_local_array( object, compass->times );
|
||||
abs = (VipsImage **)
|
||||
vips_object_local_array( object, compass->times );
|
||||
combine = (VipsImage **)
|
||||
vips_object_local_array( object, compass->times );
|
||||
|
||||
mask = convolution->M;
|
||||
for( i = 0; i < compass->times; i++ ) {
|
||||
if( vips_conv( convolution->in, &images[i], mask,
|
||||
"precision", compass->precision,
|
||||
"layers", compass->layers,
|
||||
"cluster", compass->cluster,
|
||||
NULL ) )
|
||||
return( -1 );
|
||||
if( vips_rot45( mask, &masks[i],
|
||||
"angle", compass->angle,
|
||||
NULL ) )
|
||||
return( -1 );
|
||||
|
||||
mask = masks[i];
|
||||
}
|
||||
|
||||
for( i = 0; i < compass->times; i++ )
|
||||
if( vips_abs( images[i], &abs[i], NULL ) )
|
||||
return( -1 );
|
||||
|
||||
switch( compass->combine ) {
|
||||
case VIPS_COMBINE_MAX:
|
||||
if( vips_bandrank( abs, &combine[0], compass->times,
|
||||
"index", compass->times - 1,
|
||||
NULL ) )
|
||||
return( -1 );
|
||||
x = combine[0];
|
||||
break;
|
||||
|
||||
case VIPS_COMBINE_SUM:
|
||||
x = abs[0];
|
||||
for( i = 1; i < compass->times; i++ ) {
|
||||
if( vips_add( x, abs[i], &combine[i], NULL ) )
|
||||
return( -1 );
|
||||
x = combine[i];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert( 0 );
|
||||
}
|
||||
|
||||
if( vips_image_write( x, convolution->out ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
@ -86,21 +145,42 @@ vips_compass_class_init( VipsCompassClass *class )
|
||||
object_class->description = _( "convolution operation" );
|
||||
object_class->build = vips_compass_build;
|
||||
|
||||
VIPS_ARG_ENUM( class, "precision", 103,
|
||||
VIPS_ARG_INT( class, "times", 101,
|
||||
_( "Times" ),
|
||||
_( "Rotate and convolve this many times" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCompass, times ),
|
||||
1, 1000, 2 );
|
||||
|
||||
VIPS_ARG_ENUM( class, "angle", 103,
|
||||
_( "Angle" ),
|
||||
_( "Rotate mask by this much between convolutions" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCompass, angle ),
|
||||
VIPS_TYPE_ANGLE45, VIPS_ANGLE45_90 );
|
||||
|
||||
VIPS_ARG_ENUM( class, "combine", 104,
|
||||
_( "Combine" ),
|
||||
_( "Combine convolution results like this" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCompass, combine ),
|
||||
VIPS_TYPE_COMBINE, VIPS_COMBINE_MAX );
|
||||
|
||||
VIPS_ARG_ENUM( class, "precision", 203,
|
||||
_( "Precision" ),
|
||||
_( "Convolve with this precision" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCompass, precision ),
|
||||
VIPS_TYPE_PRECISION, VIPS_PRECISION_INTEGER );
|
||||
|
||||
VIPS_ARG_INT( class, "layers", 104,
|
||||
VIPS_ARG_INT( class, "layers", 204,
|
||||
_( "Layers" ),
|
||||
_( "Use this many layers in approximation" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCompass, layers ),
|
||||
1, 1000, 5 );
|
||||
|
||||
VIPS_ARG_INT( class, "cluster", 105,
|
||||
VIPS_ARG_INT( class, "cluster", 205,
|
||||
_( "Cluster" ),
|
||||
_( "Cluster lines closer than this in approximation" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
@ -112,9 +192,12 @@ vips_compass_class_init( VipsCompassClass *class )
|
||||
static void
|
||||
vips_compass_init( VipsCompass *compass )
|
||||
{
|
||||
compass->times = 1;
|
||||
compass->angle = 5;
|
||||
compass->join = 1;
|
||||
compass->times = 2;
|
||||
compass->angle = VIPS_ANGLE45_90;
|
||||
compass->combine = VIPS_COMBINE_MAX;
|
||||
compass->precision = VIPS_PRECISION_INTEGER;
|
||||
compass->layers = 5;
|
||||
compass->cluster = 1;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -127,7 +127,7 @@ vips_convolution_class_init( VipsConvolutionClass *class )
|
||||
VIPS_ARGUMENT_REQUIRED_OUTPUT,
|
||||
G_STRUCT_OFFSET( VipsConvolution, out ) );
|
||||
|
||||
VIPS_ARG_IMAGE( class, "mask", 102,
|
||||
VIPS_ARG_IMAGE( class, "mask", 20,
|
||||
_( "Mask" ),
|
||||
_( "Input matrix image" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
@ -148,7 +148,9 @@ vips_convolution_operation_init( void )
|
||||
{
|
||||
extern int vips_conv_get_type( void );
|
||||
extern int vips_morph_get_type( void );
|
||||
extern int vips_compass_get_type( void );
|
||||
|
||||
vips_conv_get_type();
|
||||
vips_morph_get_type();
|
||||
vips_compass_get_type();
|
||||
}
|
||||
|
@ -2088,6 +2088,82 @@ im_recomb( IMAGE *in, IMAGE *out, DOUBLEMASK *recomb )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
int
|
||||
im_compass( VipsImage *in, VipsImage *out, INTMASK *mask )
|
||||
{
|
||||
VipsImage *t1, *t2;
|
||||
|
||||
if( !(t1 = vips_image_new()) ||
|
||||
im_imask2vips( mask, t1 ) )
|
||||
return( -1 );
|
||||
if( vips_compass( in, &t2, t1,
|
||||
"times", 8,
|
||||
NULL ) ) {
|
||||
g_object_unref( t1 );
|
||||
return( -1 );
|
||||
}
|
||||
g_object_unref( t1 );
|
||||
if( vips_image_write( t2, out ) ) {
|
||||
g_object_unref( t2 );
|
||||
return( -1 );
|
||||
}
|
||||
g_object_unref( t2 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int
|
||||
im_lindetect( IMAGE *in, IMAGE *out, INTMASK *mask )
|
||||
{
|
||||
VipsImage *t1, *t2;
|
||||
|
||||
if( !(t1 = vips_image_new()) ||
|
||||
im_imask2vips( mask, t1 ) )
|
||||
return( -1 );
|
||||
if( vips_compass( in, &t2, t1,
|
||||
"times", 4,
|
||||
NULL ) ) {
|
||||
g_object_unref( t1 );
|
||||
return( -1 );
|
||||
}
|
||||
g_object_unref( t1 );
|
||||
if( vips_image_write( t2, out ) ) {
|
||||
g_object_unref( t2 );
|
||||
return( -1 );
|
||||
}
|
||||
g_object_unref( t2 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int
|
||||
im_gradient( IMAGE *in, IMAGE *out, INTMASK *mask )
|
||||
{
|
||||
VipsImage *t1, *t2;
|
||||
|
||||
if( !(t1 = vips_image_new()) ||
|
||||
im_imask2vips( mask, t1 ) )
|
||||
return( -1 );
|
||||
if( vips_compass( in, &t2, t1,
|
||||
"times", 2,
|
||||
"angle", VIPS_ANGLE45_90,
|
||||
"combine", VIPS_COMBINE_SUM,
|
||||
NULL ) ) {
|
||||
g_object_unref( t1 );
|
||||
return( -1 );
|
||||
}
|
||||
g_object_unref( t1 );
|
||||
if( vips_image_write( t2, out ) ) {
|
||||
g_object_unref( t2 );
|
||||
return( -1 );
|
||||
}
|
||||
g_object_unref( t2 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
*/
|
||||
|
||||
static int
|
||||
vips__round( VipsImage *in, VipsImage *out, VipsOperationRound round )
|
||||
{
|
||||
|
@ -41,11 +41,40 @@ extern "C" {
|
||||
typedef enum {
|
||||
VIPS_PRECISION_INTEGER,
|
||||
VIPS_PRECISION_FLOAT,
|
||||
VIPS_PRECISION_APPROXIMATE
|
||||
VIPS_PRECISION_APPROXIMATE,
|
||||
VIPS_PRECISION_LAST
|
||||
} VipsPrecision;
|
||||
|
||||
typedef enum {
|
||||
VIPS_COMBINE_MAX,
|
||||
VIPS_COMBINE_SUM,
|
||||
VIPS_COMBINE_LAST
|
||||
} VipsCombine;
|
||||
|
||||
/**
|
||||
* VipsOperationMorphology:
|
||||
* @VIPS_OPERATION_MORPHOLOGY_ERODE: true if all set
|
||||
* @VIPS_OPERATION_MORPHOLOGY_DILATE: true if one set
|
||||
*
|
||||
* More like hit-miss, really.
|
||||
*
|
||||
* See also: vips_morph().
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
VIPS_OPERATION_MORPHOLOGY_ERODE,
|
||||
VIPS_OPERATION_MORPHOLOGY_DILATE,
|
||||
VIPS_OPERATION_MORPHOLOGY_LAST
|
||||
} VipsOperationMorphology;
|
||||
|
||||
int vips_conv( VipsImage *in, VipsImage **out, VipsImage *mask, ... )
|
||||
__attribute__((sentinel));
|
||||
int vips_compass( VipsImage *in, VipsImage **out, VipsImage *mask, ... )
|
||||
__attribute__((sentinel));
|
||||
|
||||
int vips_morph( VipsImage *in, VipsImage **out, VipsImage *mask,
|
||||
VipsOperationMorphology morph, ... )
|
||||
__attribute__((sentinel));
|
||||
|
||||
void vips_convolution_operation_init( void );
|
||||
|
||||
|
@ -74,7 +74,8 @@ GType vips_operation_flags_get_type (void) G_GNUC_CONST;
|
||||
/* enumerations from "../../../libvips/include/vips/convolution.h" */
|
||||
GType vips_precision_get_type (void) G_GNUC_CONST;
|
||||
#define VIPS_TYPE_PRECISION (vips_precision_get_type())
|
||||
/* enumerations from "../../../libvips/include/vips/morphology.h" */
|
||||
GType vips_combine_get_type (void) G_GNUC_CONST;
|
||||
#define VIPS_TYPE_COMBINE (vips_combine_get_type())
|
||||
GType vips_operation_morphology_get_type (void) G_GNUC_CONST;
|
||||
#define VIPS_TYPE_OPERATION_MORPHOLOGY (vips_operation_morphology_get_type())
|
||||
/* enumerations from "../../../libvips/include/vips/object.h" */
|
||||
|
@ -38,26 +38,6 @@
|
||||
extern "C" {
|
||||
#endif /*__cplusplus*/
|
||||
|
||||
/**
|
||||
* VipsOperationMorphology:
|
||||
* @VIPS_OPERATION_MORPHOLOGY_ERODE: true if all set
|
||||
* @VIPS_OPERATION_MORPHOLOGY_DILATE: true if one set
|
||||
*
|
||||
* More like hit-miss, really.
|
||||
*
|
||||
* See also: vips_morph().
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
VIPS_OPERATION_MORPHOLOGY_ERODE,
|
||||
VIPS_OPERATION_MORPHOLOGY_DILATE,
|
||||
VIPS_OPERATION_MORPHOLOGY_LAST
|
||||
} VipsOperationMorphology;
|
||||
|
||||
int vips_morph( VipsImage *in, VipsImage **out, VipsImage *mask,
|
||||
VipsOperationMorphology morph, ... )
|
||||
__attribute__((sentinel));
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -625,6 +625,7 @@ vips_precision_get_type( void )
|
||||
{VIPS_PRECISION_INTEGER, "VIPS_PRECISION_INTEGER", "integer"},
|
||||
{VIPS_PRECISION_FLOAT, "VIPS_PRECISION_FLOAT", "float"},
|
||||
{VIPS_PRECISION_APPROXIMATE, "VIPS_PRECISION_APPROXIMATE", "approximate"},
|
||||
{VIPS_PRECISION_LAST, "VIPS_PRECISION_LAST", "last"},
|
||||
{0, NULL, NULL}
|
||||
};
|
||||
|
||||
@ -633,7 +634,24 @@ vips_precision_get_type( void )
|
||||
|
||||
return( etype );
|
||||
}
|
||||
/* enumerations from "../../libvips/include/vips/morphology.h" */
|
||||
GType
|
||||
vips_combine_get_type( void )
|
||||
{
|
||||
static GType etype = 0;
|
||||
|
||||
if( etype == 0 ) {
|
||||
static const GEnumValue values[] = {
|
||||
{VIPS_COMBINE_MAX, "VIPS_COMBINE_MAX", "max"},
|
||||
{VIPS_COMBINE_SUM, "VIPS_COMBINE_SUM", "sum"},
|
||||
{VIPS_COMBINE_LAST, "VIPS_COMBINE_LAST", "last"},
|
||||
{0, NULL, NULL}
|
||||
};
|
||||
|
||||
etype = g_enum_register_static( "VipsCombine", values );
|
||||
}
|
||||
|
||||
return( etype );
|
||||
}
|
||||
GType
|
||||
vips_operation_morphology_get_type( void )
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user