www.pudn.com > imageFeatures_Ver3_0_source.zip > IFFeature.h


// IFFeature.h 
 
/* 
** Copyright (C) 1994, 2003 Tyler C. Folsom 
** 
** Permission to use, copy, modify, and distribute this software and its 
** documentation for any purpose and without fee is hereby granted, provided 
** that the above copyright notice appear in all copies and that both that 
** copyright notice and this permission notice appear in supporting 
** documentation.  This software is provided "as is" without express or 
** implied warranty. 
*/ 
#ifndef IFFEATURE_H 
#define IFFEATURE_H 
 
#include  
#include  
#include  
 
// The detected feature 
enum feature_type 
{ 
    eNOT_AVAILABE,  // indicates no data (e.g. no answer) 
    eNO_FEATURE,    // there is nothing in the circle 
    eEDGE,    /* Edge: A dark to light step. */ 
    /* Until 2/27/00, eDARK_BAR meant 0,255,0 
       Changed so that eBAR_LIGHT is 0,255,0.  0 is black; 255 white. */ 
    /* 6/27/03: replace with the new names eWHITE_LINE and eBLACK_LINE */ 
    eWHITE_LINE,  // eBAR_DARK, 
    eBLACK_LINE,  // eBAR_LIGHT, 
    eCORNER,  /* Corner: A corner or point of high curvature. */ 
    eDARK_CORNER, 
    eLIGHT_CORNER, 
    eBLOB,     /* Blob: A spot or region not strongly connected 
                to the borders of the receptive field. */ 
    eDARK_BLOB, 
    eLIGHT_BLOB, 
    eSTOPPED_BAR_DARK, 
    eSTOPPED_BAR_LIGHT, 
	eFEATURE_TYPE_SIZE 
}; 
 
 
// The number of nearest neighbors 
const NEIGHBORS = 6; 
 
// Gives the points defining the outline of a feature 
struct Outline 
{ 
    // points defining the shape to draw 
    CArray< POINT, POINT&> segment; 
    COLORREF color; // of line 
    int thickness;  // of line to draw 
}; 
// One dimensional data found in a receptive field 
struct Data_1D 
{ 
    float m_degrees; /*  The orientation of the feature in degrees. 
       A vertical edge has 0° orientation; horizontal is 90°. 
	   The unit vector for 0 is (0,1), pointing down. 
	   The unit vector for 90 is (-1,0), pointing left. 
	   An edge at 0 has dark to the left, light to the right. 
	   An edge at 90 has dark to the top. 
	   An edge at 180 has dark to the right. 
	   An edge at 270 has dark to the bottom. 
       For corners, the implied 2nd angle is m_degrees + 90.. 
       The angle determines which is the inside and outside of the feature. 
       Bars and blobs with dark insides have angles greater than or equal 
       to 0 and less than 180.  If the interior is light, the angle is 
       greater or equal to 180 and less than 360. 
       For edges, corners and curves, the dark side is to the left of  
       a vector oriented at “angle”. */ 
	float m_sin_th;  // sine of m_degrees 
	float m_cos_th;  // cosine of m_degrees 
    float m_strength;  /* relative contrast of the feature. 
       The value ranges from 2.0 for a totally dark to totally white edge 
       to 0 for a uniform field */ 
    float m_x;   /* Column index location of the feature. */ 
    float m_y;   /* Row index feature location. */ 
    float m_pos; // distance of the feature from the center 
    enum feature_type m_type;  
    float m_width;  /*    Width in pixels for bars and blobs */ 
 
    // The four 1D filter results are used to generate the features. 
    float m_corrEven; 
    float m_corrOdd; 
    float m_corrBigEven; 
    float m_corrBigOdd; 
 
    Data_1D() {m_type = eNOT_AVAILABE;} 
    ~Data_1D() {} 
    Data_1D(const Data_1D &right); 
    const Data_1D &operator=( const Data_1D &right ); 
    inline void Copy(const Data_1D &right); 
    // normally write numbers for feature_type; 
    // If names is true, instead give a text name. 
    void write( ofstream& outFile, bool names = false, int verbosity = 0); 
    // return a string describing the feature type. 
    const char* Name( feature_type featureType); 
	// Return true if the line thru (x + m_pos + delta, y) rotated m_degrees 
	// intersects the circle centered at (x,y) in one or more two points. 
	bool DoesIntersect 
	(   float x, float y,  // [in] center of circle 
		float radius, // [in] of circle 
		float delta   // [in] displacement 
	); 
	// Return true if the line thru (x + m_pos + delta, y) rotated m_degrees 
	// intersects the circle centered at (x,y) in one or two points. 
	bool FindIntersect 
	(   float x, float y,  // [in] center of circle 
		float radius,  // [in] of circle 
		float delta,   // [in] displacement 
		float *ax, float *ay, // [out] 1st intersection point 
		float *bx, float *by  // [out] 2nd intersection point 
	); 
 
}; 
 
// Two dimensional data (interest points) found in a receptive field 
struct Data_2D 
{ 
    float m_x;   /* Column index location of the interest point. */ 
    float m_y;   /* Row index interest point location. */ 
    enum feature_type m_type;  
 
    Data_2D() {m_type = eNOT_AVAILABE;} 
    ~Data_2D() {} 
    Data_2D(const Data_2D &right); 
    const Data_2D &operator=( const Data_2D &right ); 
    inline void Copy(const Data_2D &right); 
    // normally write numbers for feature_type; 
    // If names is true, instead give a text name. 
    void write( ofstream& outFile, bool names = false, int verbosity = 0); 
    // return a string describing the feature type. 
    const char* Name( feature_type featureType); 
}; 
 
// typedef Data_1D data_1D; 
 
 
 
// CFeature interprets what was found at an image location. 
class CFeature 
{ 
public: 
	BOOL DrawCircle( HDC hDeviceContext); 
    CFeature() {} // for temporary use only 
 
    // Must specify all of these to construct a feature 
    CFeature( int x_rf, int y_rf, // sampling location 
     int diam,      // diameter of small filters 
     float angle,   // angle of maximum response (radians) 
     // the following four correlations are steered to angle 
     float corrEven,    // correlation with small even filter 
     float corrOdd,     // correlation with small odd filter   
     float corrBigEven, // correlation with big even filter 
     float corrBigOdd,  // correlation with big odd filter 
     float base_strength, // relative strength of small filters 
     float big_base_strength, // relative strength of big filters 
     float big_diam,      // diameter of big filters 
     float center_lobe,   // width of big even filter 
     float width_tuning); // average width of big and small 
 
    // This allows us to steer to another angle and save the corelations 
    void AddSecondary( int i,  
     float angle,   // angle of secondary response (radians) 
     float corrEven, float corrOdd,  
     float corrBigEven, float corrBigOdd); 
 
    CFeature(const CFeature &right); 
    const CFeature &operator=( const CFeature &right ); 
 
    // normally write numbers for feature_type; 
    // If names is true, instead give a text name. 
    void write( ofstream& outFile, bool names = false, int verbosity = 0); 
    // read a feature from a file 
//  void read( ifstream& inFile); 
 
    // multi_find: call find_pos for different angles. 
    void multi_find(int i, bool edgesOnly); 
 
/*  find_pos: given a convolution of an image with even and odd  
    filters at two different scales, find the type of edge, the edge position 
    edge strength and bar width.  The results are kept in the class. */ 
    void find_pos( Data_1D* pData, bool edgesOnly); 
 
	void corners();  // Find 2D interest points. 
 
    // find secondary feature at the same location 
    void FindSecondary();  // assumes all steering has been done 
    void FindResidual(); 
    float GetStrength() 
    {  return m_main.m_strength; } 
    float GetAntagonism() 
    {  return m_lateral; } 
    float GetDegrees() 
    {  return m_main.m_degrees; } 
    enum feature_type GetType() 
    {  return m_corner.m_type; } 
    float GetWidth() 
    {  return m_main.m_width; } 
    // Compute distance from feature to base  
    float PositionDifference( Data_1D& base, bool fromRfCenter = false); 
    // test if the features are within two radii; set m_pNbr if so. 
	bool CFeature::IsNeighbor(CFeature *other); 
 
	// Lateral antagonism: increase or decrease the strength of neighbors. 
	void LateralAntagonism(); 
    // Find error in identified type. 
    int TypeDifference( Data_1D& base ); 
    // Generate points on a line for a graphical representation. 
    void CadData( Outline& shape, bool useMain ); 
	void FindPlotInfo( Outline& shape, bool useMain ); 
	inline bool Is2D()	{ return (m_corner.m_type >= eCORNER);} 
    // round from float to int 
    inline int Round( float x ) 
    { return ((int) (x>0? (x+(float)0.5) : (x-(float)0.5))); }  
 
 
private: 
    float find_strength( float magnitude, float phase,   
      enum feature_type type); 
    inline void Copy(const CFeature &right); 
    double look_up( double x, int points, double *x_table, 
      double *y_table); 
    float find_step (double phase); 
    float find_bar (double phase); 
    float find_width (float ratio, float center_lobe); 
	float find_width (float ratio, float center_lobe, float pos, float *faint); 
 
    float m_x_rf;   /* x coordinate of receptive field center (pixels). */ 
    float m_y_rf;   /* y coordinate of receptive field center. */ 
    int m_diam_rf;  /* diameter of smaller receptive field (pixels) */ 
    float m_angle; //  The orientation of the feature in radians 
    float m_length;  /*    of blob */ 
	float m_lateral;  /* the amount of lateral inhibition or facilitation */ 
	CFeature *m_pNbr[NEIGHBORS]; /* Neighboring receptive fields involved in lateral antagonism */ 
//  struct color m_foreground; 
//  struct color m_background; 
    // values by which to scale the strength of the response. 
    float m_base_strength; 
    float m_big_base_strength; 
    float m_scale; 
    float m_big_scale; 
    float m_center_lobe; 
    float m_width_tuning; 
    Data_1D m_main;   // feature found at m_angle 
    Data_1D m_90; // feature found at 90 degrees to m_angle 
/*  Steering to 45 degrees can distinguish a cross from a blob. 
    Data_1D m_45;   // feature found at +45 degrees to m_angle 
    Data_1D m_135;  // feature found at 145 degrees to m_angle 
*/ 
	Data_2D m_corner;  // interest point 
};   
 
#endif // IFFEATURE_H