⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 v2.cpp

📁 A tutorial and open source code for finding edges and corners based on the filters used in primary v
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		m_corner.m_y = (x1 * m_90.m_pos * m_90.m_pos -
						x2 * m_main.m_pos * m_main.m_pos) / denom + m_y_rf;
	}
	else if (FL_ABS(m_main.m_pos) < EPSILON)
	{	// main feature is at origin
		m_corner.m_x = m_90.m_x;
		m_corner.m_y = m_90.m_y;
	}
	// else perpendicular feature is at origin.
	// But we defaulted to using (m_main.m_x, m_main.m_y), which works.
}

/*------------------------------------------------------------------------*/
// write text feature information to a file.

void CFeature::write
(   ofstream& outFile, 
    bool names,     // If names is true, give a text name,
                    // otherwise write numbers for feature_type;
    int verbosity   // 0 for brief, 1 for longer ...
)  
{
    if (m_corner.m_type == eNO_FEATURE || m_corner.m_type == eNOT_AVAILABE)
    {
        outFile << endl;
        return;
    }

    // set to show 1 decimal place
    int oldPrecision = outFile.precision(1);
    outFile.setf( ios::fixed, ios::floatfield );
    outFile << m_x_rf << '\t' << m_y_rf << '\t' << m_diam_rf << '\t'
		<< m_lateral << '\t';
//	int type_index = (int) m_corner.m_type;
//	outFile << featureName[ type_index] << '\t';
    m_corner.write( outFile, names, verbosity );
    m_main.write( outFile, names, verbosity );
    if (verbosity > 0)
    {
        // Write perpendicular features
        m_90.write( outFile, names, verbosity );
/*        // Write +45 degree features
        m_45.write( outFile, names, verbosity );
        // Write -45 degree features
        m_135.write( outFile, names, verbosity );  */
    }
    outFile << endl;
    outFile.precision(oldPrecision); // restore previous precision
}
/*------------------------------------------------------------------------*/
// Compute distance from feature to base position
float CFeature::PositionDifference
(   Data_1D& base,     // the answer; true position of feature 
    bool fromRfCenter  // if true, use center of receptive field.
                       // if false, use location of found feature 
)
{
    double distance = 0.0;
    if (m_corner.m_type == eNO_FEATURE || m_corner.m_type == eNOT_AVAILABE)
        return (float) distance;

    // intersection of base line with perpendicular thru m_main.m_x,y
    double x = base.m_x;
    double y = base.m_y;
    double degrees = base.m_degrees;
    double xFrom = m_main.m_x;
    double yFrom = m_main.m_y;
    if (fromRfCenter)
    {
        xFrom = m_x_rf;
        yFrom = m_y_rf;
    }
    switch (base.m_type)
    {
    case eNO_FEATURE:
    case eNOT_AVAILABE:
        // distance is meaningless
        break;

    case eEDGE:
    case eWHITE_LINE:
    case eBLACK_LINE:
        // TO DO: case of mismatched edges and bars
        while (degrees > 180)
            degrees -= 180;
        while (degrees < 0)
            degrees += 180;
        if (degrees > 90 - EPSILON && degrees < 90 + EPSILON)
            x = xFrom;
        else if (degrees > 180 - EPSILON || degrees < EPSILON)
            y = yFrom;
        else
        {
            double slope = tan( degrees * PI / 180.0);
            x = (slope / (slope * slope + 1.0)) * ( yFrom - base.m_y +
                xFrom / slope + base.m_x * slope);
            y = slope * (x - base.m_x) + base.m_y;
        }
        distance = sqrt( (x - xFrom) * (x - xFrom) + (y - yFrom) * (y - yFrom));
        if (xFrom - x + yFrom - y < 0)
            distance = -distance;

        // if matched an edge to a bar, report the distance to the edge of the bar
        if (m_main.m_type == eEDGE && 
           (base.m_type == eBLACK_LINE || base.m_type == eWHITE_LINE))
        {
            double half_width =  base.m_width * 0.5;
            distance += fabs( distance - half_width) < fabs( distance + half_width)?
                -half_width : half_width;
        }
        if (base.m_type == eEDGE && 
           (m_main.m_type == eBLACK_LINE || m_main.m_type == eWHITE_LINE))
        {
            double cosine = 
                fabs( cos( (base.m_degrees - m_main.m_degrees) * PI / 180.0));
            if (cosine > EPSILON)
            {
                double half_width =  base.m_width * 0.5 / cosine;
                distance += fabs( distance - half_width) < 
                    fabs( distance + half_width)?
                    -half_width : half_width;
            }
        }
        break;

    case eCORNER:
    case eDARK_CORNER:
    case eLIGHT_CORNER:
    case eBLOB:
    case eDARK_BLOB:
    case eLIGHT_BLOB:
    default:
        distance = sqrt( (x - xFrom) * (x - xFrom) + (y - yFrom) * (y - yFrom));
        if (xFrom - x + yFrom - y < 0)
            distance = -distance;
        break;
    }
    return (float) distance;

}
/*------------------------------------------------------------------------*/
// Compute error in type identification 
// Returned: difference in type values.
int CFeature::TypeDifference( Data_1D& base )
{
    enum feature_type answer = base.m_type;
    float half_width =  base.m_width * 0.5;
	bool edge1seen = base.DoesIntersect(m_x_rf, m_y_rf, m_diam_rf/2, half_width);
	bool edge2seen = edge1seen;			
    if (answer == eBLACK_LINE || answer == eWHITE_LINE)
		edge2seen = base.DoesIntersect(m_x_rf, m_y_rf, m_diam_rf/2, -half_width);			
    // if the feature is not in the small receptive field, no feature.
	if (!edge1seen && !edge2seen)			
        answer = eNO_FEATURE;
    // if the feature is a bar, can we see both edges?
    if ((answer == eBLACK_LINE || answer == eWHITE_LINE) &&
		(!edge1seen || !edge2seen))
        answer = eEDGE;  // can't see far bar edge
    return (int) (m_corner.m_type - answer);
}
/*------------------------------------------------------------------------*/
void CFeature::FindPlotInfo( Outline& shape, bool useMain )
{   // replaces CadData
	Data_1D& oneD = useMain? m_main : m_90;
    float radius = m_diam_rf / 2; /* effective radius of smaller filter */
    if (oneD.m_type == eNO_FEATURE || oneD.m_type == eNOT_AVAILABE)
		return;
    shape.color = EDGE_COLOR; 
	float half_width =  oneD.m_width * 0.5;
	float p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y;
	bool edge1seen = oneD.FindIntersect(m_x_rf, m_y_rf, radius, half_width,
		&p1x, &p1y, &p2x, &p2y);
	bool edge2seen = edge1seen;			
    if (oneD.m_type == eBLACK_LINE || oneD.m_type == eWHITE_LINE)
	{
		edge2seen = oneD.FindIntersect(m_x_rf, m_y_rf, radius, -half_width,
		&p4x, &p4y, &p3x, &p3y);
		shape.color = oneD.m_type == eWHITE_LINE?
		LIGHT_BAR_COLOR: DARK_BAR_COLOR;
	}
	if (Is2D())
	{
        shape.color = CORNER_COLOR;
		if (oneD.m_type == eEDGE)
		{
			p2x = m_corner.m_x;
			p2y = m_corner.m_y;
		}
	}
	if (!edge1seen && !edge2seen)			
        return;  // should not happen

    // Make a quadrilateral describing the bar or line
    POINT vertex; 
    vertex.x = Round(p1x);       
    vertex.y = Round(p1y);
    shape.segment.Add( vertex );
    POINT firstPoint = vertex;
    vertex.x = Round(p2x);       
    vertex.y = Round(p2y);
    shape.segment.Add( vertex );
	if (oneD.m_type != eEDGE)
	{
		vertex.x = Round(p3x);       
		vertex.y = Round(p3y);
		shape.segment.Add( vertex );
		vertex.x = Round(p4x);       
		vertex.y = Round(p4y);
		shape.segment.Add( vertex );
        shape.segment.Add( firstPoint );
	}
    shape.thickness = 1;

}
/*------------------------------------------------------------------------*/
void CFeature::CadData( Outline& shape, bool useMain )
{
/* cad_info: write information that is useful for making a drawing of
   the features that were located. */
/* This routine added 5/11/95 by Tyler C. Folsom */

//  float m_x_rf, m_y_rf,  /* center point of the filter */
//  float m_pos,           /* position of feature relative to center */
//  float m_angle,         /* angle of feature in radians */
//  int   m_type,          /* feature type */
//  float m_bar_width,     /* width of a bar */

	if (!useMain)
		return;  // corner drawing is not yet working
	Data_1D& oneD = useMain? m_main : m_90;
    float radius = m_diam_rf / 2; /* effective radius of smaller filter */

    float sin_a, cos_a, half_bar;
  /* intersection of circle with line from center to feature location. */
    float cx, cy;
  /* end points of the feature in the smaller filter */
    float px, py, qx, qy;
    /* centerline of bar */
    float pcx, pcy, qcx, qcy;
  /* angle by which (cx, cy) is rotated into (px, py), (qx, qy). */
    double alpha;
    POINT vertex; 
	float sin_th = oneD.m_sin_th;
	float cos_th = oneD.m_cos_th;
	/*  The graphics origin is at the upper left.
	    X axis points right and Y axis points down.
		0 degrees points down and a positive angle is clockwise.
		Thus for rotation, the origin is at (0,R) and the angle is positive.
		x = -radius * sin_th;
		y = radius * cos_th;
		(cx, cy) is normal to (x,y)
	*/

  /* intersection of circle with line from center to feature location. */
	if (oneD.m_degrees < 180)
	{
		cx =  radius * cos_th;
		cy =  radius * sin_th;
	}
	else
	{
		cx = -radius * cos_th;
		cy = -radius * sin_th;
	}
    if (oneD.m_type == eBLACK_LINE || oneD.m_type == eWHITE_LINE)
    {
        half_bar = (float) 0.5 * oneD.m_width;
        shape.color = oneD.m_type == eWHITE_LINE?
			LIGHT_BAR_COLOR: DARK_BAR_COLOR;
        if (FL_ABS(oneD.m_pos) < half_bar)
        {   /* center line is the longest segment */
            cos_a = oneD.m_pos / radius;
            sin_a = (float) sqrt(1.0 - cos_a * cos_a);
            /* centerline of bar: (cx, cy) rotated +/- alpha */
            pcx = m_x_rf + cx * cos_a + cy * sin_a;
            pcy = m_y_rf - cx * sin_a + cy * cos_a;
            qcx = m_x_rf + cx * cos_a - cy * sin_a;
            qcy = m_y_rf + cx * sin_a + cy * cos_a; 
            /* inner edge of bar */
            px = pcx - half_bar * cos_th;
            py = pcy - half_bar * sin_th;
            qx = qcx - half_bar * cos_th;
            qy = qcy - half_bar * sin_th;
        }
        else
        {   /* inner edge is the longest segment */
            alpha = acos ((double) ((oneD.m_pos - half_bar) / radius));
            sin_a = (float) sin(alpha);
            cos_a = (float) cos(alpha);
            /* inner edge of bar */
            px = m_x_rf + cx * cos_a + cy * sin_a;
            py = m_y_rf - cx * sin_a + cy * cos_a;
            qx = m_x_rf + cx * cos_a - cy * sin_a;
            qy = m_y_rf + cx * sin_a + cy * cos_a;
            /* centerline of bar */
            pcx = px + half_bar * cos_th;
            pcy = py + half_bar * sin_th;
            qcx = qx + half_bar * cos_th;
            qcy = qy + half_bar * sin_th;
        }
        // Make a quadrilateral describing the bar
        vertex.x = Round(px);       
        vertex.y = Round(py);
        POINT firstPoint = vertex;
        shape.segment.Add( vertex );
        vertex.x = Round(qx);       
        vertex.y = Round(qy);
        shape.segment.Add( vertex );

        /* outer edge of bar */
        px = pcx + half_bar * cos_th;
        py = pcy + half_bar * sin_th;
        qx = qcx + half_bar * cos_th;
        qy = qcy + half_bar * sin_th;

        vertex.x = Round(qx);       
        vertex.y = Round(qy);
        shape.segment.Add( vertex );
        vertex.x = Round(px);       
        vertex.y = Round(py);
        shape.segment.Add( vertex );
        shape.segment.Add( firstPoint );

    }
    else   /* a step edge */
    {   /* compute the points where the edge meets the boundary of the smaller 
           receptive field */
        shape.color = EDGE_COLOR; 
        alpha = acos ((double) (oneD.m_pos / radius));
        sin_a = (float) sin(alpha);
        cos_a = (float) cos(alpha);
        // Points on the edge are (cx, cy) rotated by +/- alpha.
        px = m_x_rf + cx * cos_a + cy * sin_a;
        py = m_y_rf - cx * sin_a + cy * cos_a;
        qx = m_x_rf + cx * cos_a - cy * sin_a;
        qy = m_y_rf + cx * sin_a + cy * cos_a;

        vertex.x = Round(px);       
        vertex.y = Round(py);
        shape.segment.Add( vertex );
        vertex.x = Round(qx);       
        vertex.y = Round(qy);
        shape.segment.Add( vertex );
    }
/*
	if (Is2D())
	{
        shape.color = CORNER_COLOR; 
	}
*/
    if (oneD.m_strength < 0.5)
    {
        shape.thickness = 1;
    }
    else if (oneD.m_strength < 1.0)
    {
        shape.thickness = 2;
    }
    else if (oneD.m_strength < 1.5)
    {
        shape.thickness = 3;
    }
    else
    {
        shape.thickness = 4;
    }
}
/*------------------------------------------------------------------------*/
// draw a circle corresponding to the small filter.
BOOL CFeature::DrawCircle(HDC hDeviceContext)
{
    return 
    ( 
        Arc( hDeviceContext, 
            m_x_rf - m_diam_rf/2, // x Up Left
            m_y_rf - m_diam_rf/2, // y Up Left
            m_x_rf + m_diam_rf/2, // x Low Right
            m_y_rf + m_diam_rf/2, // y Low Right
            m_x_rf,                          // x start
            m_y_rf + m_diam_rf/2, // y start
            m_x_rf,                          // x end
            m_y_rf + m_diam_rf/2  // y end
            )
    );

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -