Horus Doc || User Guide || Introduction   Installation   Getting Started  

Instantiation of a unary pixel operation: Tri state threshold

The file HxImageRep/Global/HxTriStateThreshold.c provides a complete overview of all that is needed to implement a function that performs a tri state threshold:

/*
 *  Copyright (c) 2000, University of Amsterdam, The Netherlands.
 *  All rights reserved.
 *
 *  Author(s):
 *  Dennis Koelma (koelma@wins.uva.nl)
 *
 */


#include "HxTriStateThreshold.h"
#include "HxImgFtorUpo.h"
#include "HxIncludedSigs.h"


/** Pixel functor for computation of tri state threshold
 */
template<class DstValT, class SrcValT>
class HxUpoTriStateThreshold
{
public:
    /** Functor is translation invariant */
    typedef HxTagTransInVar TransVarianceCategory;

                        /** Constructor : get parameters from taglist */
                        HxUpoTriStateThreshold(HxTagList&);

                        /** Actual operation. */
    DstValT             doIt(const SrcValT& x);

                        /** The name : "triStateThreshold" */
    static HxString     className();

private:
    SrcValT             _level;
    SrcValT             _v1;
    SrcValT             _v2;
    SrcValT             _v3;
};

template<class DstValT, class SrcValT>
HxUpoTriStateThreshold<DstValT, SrcValT>::HxUpoTriStateThreshold(HxTagList& tl)
{
    _level = HxGetTag<HxValue>(tl, "level");
    _v1 = HxGetTag<HxValue>(tl, "v1");
    _v2 = HxGetTag<HxValue>(tl, "v2");
    _v3 = HxGetTag<HxValue>(tl, "v3");
}

template<class DstValT, class SrcValT>
inline DstValT
HxUpoTriStateThreshold<DstValT, SrcValT>::doIt(const SrcValT& x)
{
    if (x < _level)
        return _v1;
    if (x > _level)
        return _v3;
    return _v2;
}

template<class DstValT, class SrcValT>
HxString
HxUpoTriStateThreshold<DstValT, SrcValT>::className()
{
    return HxString("triStateThreshold");
}


/** Instantiator for unary pixel operation with tri state threshold */
template<class ImgSigT>
struct HxInstantiatorTriStateThreshold
{
    /** Instantiate image functor */
    HxImgFtorUpo<ImgSigT, ImgSigT,
        HxUpoTriStateThreshold<
                typename ImgSigT::ArithType, typename ImgSigT::ArithType> > f;
};


// Put static variables in a namespace to avoid conflicts with file inclusion
namespace HxTriStateThreshold_c {

/** Call instantiator for 2dByte images */
static HxInstantiatorTriStateThreshold<HxImageSig2dByte>           f001;
/** Call instantiator for 2dShort images */
static HxInstantiatorTriStateThreshold<HxImageSig2dShort>          f002;
/** Call instantiator for 2dInt images */
static HxInstantiatorTriStateThreshold<HxImageSig2dInt>            f003;
/** Call instantiator for 2dFloat images */
static HxInstantiatorTriStateThreshold<HxImageSig2dFloat>          f004;
/** Call instantiator for 2dDouble images */
static HxInstantiatorTriStateThreshold<HxImageSig2dDouble>         f005;
/** Call instantiator for 2dVec2Byte images */
static HxInstantiatorTriStateThreshold<HxImageSig2dVec2Byte>       f006;
/** Call instantiator for 2dVec2Short images */
static HxInstantiatorTriStateThreshold<HxImageSig2dVec2Short>      f007;
/** Call instantiator for 2dVec2Int images */
static HxInstantiatorTriStateThreshold<HxImageSig2dVec2Int>        f008;
/** Call instantiator for 2dVec2Float images */
static HxInstantiatorTriStateThreshold<HxImageSig2dVec2Float>      f009;
/** Call instantiator for 2dVec2Double images */
static HxInstantiatorTriStateThreshold<HxImageSig2dVec2Double>     f010;
/** Call instantiator for 2dVec3Byte images */
static HxInstantiatorTriStateThreshold<HxImageSig2dVec3Byte>       f011;
/** Call instantiator for 2dVec3Short images */
static HxInstantiatorTriStateThreshold<HxImageSig2dVec3Short>      f012;
/** Call instantiator for 2dVec3Int images */
static HxInstantiatorTriStateThreshold<HxImageSig2dVec3Int>        f013;
/** Call instantiator for 2dVec3Float images */
static HxInstantiatorTriStateThreshold<HxImageSig2dVec3Float>      f014;
/** Call instantiator for 2dVec3Double images */
static HxInstantiatorTriStateThreshold<HxImageSig2dVec3Double>     f015;
/** Call instantiator for 3dByte images */
static HxInstantiatorTriStateThreshold<HxImageSig3dByte>           f016;
/** Call instantiator for 3dShort images */
static HxInstantiatorTriStateThreshold<HxImageSig3dShort>          f017;
/** Call instantiator for 3dInt images */
static HxInstantiatorTriStateThreshold<HxImageSig3dInt>            f018;
/** Call instantiator for 3dFloat images */
static HxInstantiatorTriStateThreshold<HxImageSig3dFloat>          f019;
/** Call instantiator for 3dDouble images */
static HxInstantiatorTriStateThreshold<HxImageSig3dDouble>         f020;

};


/* Global function to do tri state threshold.
 */
HxImageRep
HxTriStateThreshold(HxImageRep im, HxValue level, HxValue v1, HxValue v2, HxValue v3)
{
    HxString fname("HxTriStateThreshold");

    if (im.isNull())
    {
        HxGlobalError::instance()->reportError(fname, im.name(), "null image", HxGlobalError::HX_GE_INVALID);
        return HxImageRep();
    }

    if (im.pixelDimensionality() == 1)
    {
        if ((level.tag() != HxValue::SI) && (level.tag() != HxValue::SD))
        {
            HxGlobalError::instance()->reportError(fname, im.name(), "level is of wrong value type", HxGlobalError::HX_GE_INVALID);
        }
    }
    if (im.pixelDimensionality() == 2)
    {
        if ((level.tag() != HxValue::V2I) && (level.tag() != HxValue::V2D) 
                                            && (level.tag() != HxValue::CPL))
        {
            HxGlobalError::instance()->reportError(fname, im.name(), "level is of wrong value type", HxGlobalError::HX_GE_INVALID);
        }
    }
    if (im.pixelDimensionality() == 3)
    {
        if ((level.tag() != HxValue::V3I) && (level.tag() != HxValue::V3D))
        {
            HxGlobalError::instance()->reportError(fname, im.name(), "level is of wrong value type", HxGlobalError::HX_GE_INVALID);
        }
    }

    // Put all non-image parameters in a TagList
    HxTagList tags;
    HxAddTag(tags, "level", level);
    HxAddTag(tags, "v1", v1);
    HxAddTag(tags, "v2", v2);
    HxAddTag(tags, "v3", v3);

    // call HxImageRep member function to do the image processing
    return im.unaryPixOp("triStateThreshold", tags);
}

Tri state threshold assigns three values to output pixels instead of two (0 and 1) like the normal threshold does. All pixels below the threshold level will be set to the first value, pixels equal to the threshold level will be set to the second value, and all other pixel values to the third value.

Extension of the generic unary pixel operation is basically the same as extension of the generic binary pixel operation. So, we implement a functor HxUpoTriStateThreshold to do our operation on one pixel and we instantiate the unary pixel algorithm HxImgFtorUpo for all image types. However, as the tri state threshold function requires more parameters than the usual unary pixel operation (which has only one: the pixel value) we have to use the tag list to pass the additional parameters to the pixel functor.

The tag list is passed to the constructor of the pixel functor (HxUpoTriStateTreshold in this case) by the generic unary pixel operation HxImgFtorUpo. In the constructor we save the parameters in private member variables. As this is a functor, the parameters can be used again when the unary pixel operation calls the 'doIt' operation with a pixel value to be processed.


Go to the next section or return to the index.


Generated on Mon Jan 27 15:12:12 2003 for UserGuide by doxygen1.2.12 written by Dimitri van Heesch, © 1997-2001