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
|
- 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
|
need to do sep
|
||||||
|
|
||||||
- do conv and morph quickly as simple wrappers over the vips7 operations
|
- do conv and morph quickly as simple wrappers over the vips7 operations
|
||||||
|
@ -4,6 +4,7 @@ libconvolution_la_SOURCES = \
|
|||||||
convolution.c \
|
convolution.c \
|
||||||
pconvolution.h \
|
pconvolution.h \
|
||||||
conv.c \
|
conv.c \
|
||||||
|
compass.c \
|
||||||
morph.c \
|
morph.c \
|
||||||
convol_dispatch.c \
|
convol_dispatch.c \
|
||||||
im_addgnoise.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
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif /*HAVE_CONFIG_H*/
|
#endif /*HAVE_CONFIG_H*/
|
||||||
@ -51,8 +46,11 @@ typedef struct {
|
|||||||
VipsConvolution parent_instance;
|
VipsConvolution parent_instance;
|
||||||
|
|
||||||
int times;
|
int times;
|
||||||
VipsRotate45 angle;
|
VipsAngle45 angle;
|
||||||
int join;
|
VipsCombine combine;
|
||||||
|
VipsPrecision precision;
|
||||||
|
int layers;
|
||||||
|
int cluster;
|
||||||
} VipsCompass;
|
} VipsCompass;
|
||||||
|
|
||||||
typedef VipsConvolutionClass VipsCompassClass;
|
typedef VipsConvolutionClass VipsCompassClass;
|
||||||
@ -64,12 +62,73 @@ vips_compass_build( VipsObject *object )
|
|||||||
{
|
{
|
||||||
VipsConvolution *convolution = (VipsConvolution *) object;
|
VipsConvolution *convolution = (VipsConvolution *) object;
|
||||||
VipsCompass *compass = (VipsCompass *) 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 );
|
g_object_set( compass, "out", vips_image_new(), NULL );
|
||||||
|
|
||||||
if( VIPS_OBJECT_CLASS( vips_compass_parent_class )->build( object ) )
|
if( VIPS_OBJECT_CLASS( vips_compass_parent_class )->build( object ) )
|
||||||
return( -1 );
|
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 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,21 +145,42 @@ vips_compass_class_init( VipsCompassClass *class )
|
|||||||
object_class->description = _( "convolution operation" );
|
object_class->description = _( "convolution operation" );
|
||||||
object_class->build = vips_compass_build;
|
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" ),
|
_( "Precision" ),
|
||||||
_( "Convolve with this precision" ),
|
_( "Convolve with this precision" ),
|
||||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
G_STRUCT_OFFSET( VipsCompass, precision ),
|
G_STRUCT_OFFSET( VipsCompass, precision ),
|
||||||
VIPS_TYPE_PRECISION, VIPS_PRECISION_INTEGER );
|
VIPS_TYPE_PRECISION, VIPS_PRECISION_INTEGER );
|
||||||
|
|
||||||
VIPS_ARG_INT( class, "layers", 104,
|
VIPS_ARG_INT( class, "layers", 204,
|
||||||
_( "Layers" ),
|
_( "Layers" ),
|
||||||
_( "Use this many layers in approximation" ),
|
_( "Use this many layers in approximation" ),
|
||||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
G_STRUCT_OFFSET( VipsCompass, layers ),
|
G_STRUCT_OFFSET( VipsCompass, layers ),
|
||||||
1, 1000, 5 );
|
1, 1000, 5 );
|
||||||
|
|
||||||
VIPS_ARG_INT( class, "cluster", 105,
|
VIPS_ARG_INT( class, "cluster", 205,
|
||||||
_( "Cluster" ),
|
_( "Cluster" ),
|
||||||
_( "Cluster lines closer than this in approximation" ),
|
_( "Cluster lines closer than this in approximation" ),
|
||||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
@ -112,9 +192,12 @@ vips_compass_class_init( VipsCompassClass *class )
|
|||||||
static void
|
static void
|
||||||
vips_compass_init( VipsCompass *compass )
|
vips_compass_init( VipsCompass *compass )
|
||||||
{
|
{
|
||||||
compass->times = 1;
|
compass->times = 2;
|
||||||
compass->angle = 5;
|
compass->angle = VIPS_ANGLE45_90;
|
||||||
compass->join = 1;
|
compass->combine = VIPS_COMBINE_MAX;
|
||||||
|
compass->precision = VIPS_PRECISION_INTEGER;
|
||||||
|
compass->layers = 5;
|
||||||
|
compass->cluster = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -127,7 +127,7 @@ vips_convolution_class_init( VipsConvolutionClass *class )
|
|||||||
VIPS_ARGUMENT_REQUIRED_OUTPUT,
|
VIPS_ARGUMENT_REQUIRED_OUTPUT,
|
||||||
G_STRUCT_OFFSET( VipsConvolution, out ) );
|
G_STRUCT_OFFSET( VipsConvolution, out ) );
|
||||||
|
|
||||||
VIPS_ARG_IMAGE( class, "mask", 102,
|
VIPS_ARG_IMAGE( class, "mask", 20,
|
||||||
_( "Mask" ),
|
_( "Mask" ),
|
||||||
_( "Input matrix image" ),
|
_( "Input matrix image" ),
|
||||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
@ -148,7 +148,9 @@ vips_convolution_operation_init( void )
|
|||||||
{
|
{
|
||||||
extern int vips_conv_get_type( void );
|
extern int vips_conv_get_type( void );
|
||||||
extern int vips_morph_get_type( void );
|
extern int vips_morph_get_type( void );
|
||||||
|
extern int vips_compass_get_type( void );
|
||||||
|
|
||||||
vips_conv_get_type();
|
vips_conv_get_type();
|
||||||
vips_morph_get_type();
|
vips_morph_get_type();
|
||||||
|
vips_compass_get_type();
|
||||||
}
|
}
|
||||||
|
@ -2088,6 +2088,82 @@ im_recomb( IMAGE *in, IMAGE *out, DOUBLEMASK *recomb )
|
|||||||
return( 0 );
|
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
|
static int
|
||||||
vips__round( VipsImage *in, VipsImage *out, VipsOperationRound round )
|
vips__round( VipsImage *in, VipsImage *out, VipsOperationRound round )
|
||||||
{
|
{
|
||||||
|
@ -41,11 +41,40 @@ extern "C" {
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
VIPS_PRECISION_INTEGER,
|
VIPS_PRECISION_INTEGER,
|
||||||
VIPS_PRECISION_FLOAT,
|
VIPS_PRECISION_FLOAT,
|
||||||
VIPS_PRECISION_APPROXIMATE
|
VIPS_PRECISION_APPROXIMATE,
|
||||||
|
VIPS_PRECISION_LAST
|
||||||
} VipsPrecision;
|
} 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, ... )
|
int vips_conv( VipsImage *in, VipsImage **out, VipsImage *mask, ... )
|
||||||
__attribute__((sentinel));
|
__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 );
|
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" */
|
/* enumerations from "../../../libvips/include/vips/convolution.h" */
|
||||||
GType vips_precision_get_type (void) G_GNUC_CONST;
|
GType vips_precision_get_type (void) G_GNUC_CONST;
|
||||||
#define VIPS_TYPE_PRECISION (vips_precision_get_type())
|
#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;
|
GType vips_operation_morphology_get_type (void) G_GNUC_CONST;
|
||||||
#define VIPS_TYPE_OPERATION_MORPHOLOGY (vips_operation_morphology_get_type())
|
#define VIPS_TYPE_OPERATION_MORPHOLOGY (vips_operation_morphology_get_type())
|
||||||
/* enumerations from "../../../libvips/include/vips/object.h" */
|
/* enumerations from "../../../libvips/include/vips/object.h" */
|
||||||
|
@ -38,26 +38,6 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /*__cplusplus*/
|
#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_INTEGER, "VIPS_PRECISION_INTEGER", "integer"},
|
||||||
{VIPS_PRECISION_FLOAT, "VIPS_PRECISION_FLOAT", "float"},
|
{VIPS_PRECISION_FLOAT, "VIPS_PRECISION_FLOAT", "float"},
|
||||||
{VIPS_PRECISION_APPROXIMATE, "VIPS_PRECISION_APPROXIMATE", "approximate"},
|
{VIPS_PRECISION_APPROXIMATE, "VIPS_PRECISION_APPROXIMATE", "approximate"},
|
||||||
|
{VIPS_PRECISION_LAST, "VIPS_PRECISION_LAST", "last"},
|
||||||
{0, NULL, NULL}
|
{0, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -633,7 +634,24 @@ vips_precision_get_type( void )
|
|||||||
|
|
||||||
return( etype );
|
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
|
GType
|
||||||
vips_operation_morphology_get_type( void )
|
vips_operation_morphology_get_type( void )
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user