📄 processfeatures.cpp
字号:
col = 5;
row_space = 12;
col_space = 12;
for (format = 0; format < 2; format++)
{
for (int c = col; c < m_bounds.right; c += col_space)
{
for (int r = row; r < m_bounds.bottom; r += row_space)
{
CLocation newLoc( c, r, diameter ); // create location
newLoc.SetSmall( false ); // look at bigger region
RECT big = newLoc.GetRect();
if (big.left >= m_bounds.left &&
big.top >= m_bounds.top &&
big.right <= m_bounds.right &&
big.bottom <= m_bounds.bottom)
{ // add this location to the list.
m_locs.Add( newLoc );
}
}
}
row = col = 11;
}
got_some = true;
break;
case 98: // Special test values for debug on cube
{
CLocation newLoc( 16, 31, diameter ); // white to black
m_locs.Add( newLoc );
newLoc.Initialize( 24, 16, diameter ); // 211 deg
m_locs.Add( newLoc );
}
got_some = true;
break;
case 99: // Special test values for 64 x 64 square
{
CLocation newLoc( 8, 8, diameter ); // all gray
m_locs.Add( newLoc );
newLoc.Initialize( 32, 32, diameter ); // all dark
m_locs.Add( newLoc );
newLoc.Initialize( 32, 16, diameter );
m_locs.Add( newLoc ); // top light, lower dark
newLoc.Initialize( 32, 48, diameter );
m_locs.Add( newLoc ); // top dark, lower light
newLoc.Initialize( 48, 32, diameter );
m_locs.Add( newLoc ); // left dark, right light
newLoc.Initialize( 15, 32, diameter );
m_locs.Add( newLoc ); // left light, right dark
newLoc.Initialize( 16, 32, diameter );
m_locs.Add( newLoc ); // left light, right dark
newLoc.Initialize( 17, 32, diameter );
m_locs.Add( newLoc ); // center at 16.5
newLoc.Initialize( 18, 32, diameter );
m_locs.Add( newLoc ); // center at 17.5
newLoc.Initialize( 19, 32, diameter );
m_locs.Add( newLoc ); // center at 18.5
}
got_some = true;
break;
default:
return got_some; // bad style
}
return got_some;
}
/*------------------------------------------------------------------------*/
// Set the grid file name to the new value.
// If this is the same as before, do nothing.
// Otherwise, read and validate the new grid file.
// If the new grid is not valid, retain the old one
// and return "false". Otherwise return "true".
bool CProcessFeatures::SetGrid( CString gridFileName )
{
if (gridFileName == m_gridFileName)
return true;
CString oldName = m_gridFileName;
if (ReadGrid())
return true;
// else failed to read new file
m_gridFileName = oldName;
ReadGrid();
return false;
}
/*------------------------------------------------------------------------*/
// Filter the image at a particular location
// return true if successful.
bool CProcessFeatures::Filter( CLocation& location )
{
PROFILE("Filter");
location.SetSmall(true);
location.SetOdd(false);
CFilter even, odd;
bool newFilter = false;
float magSqr, evenMagSqr, oddMagSqr;
float evenResults[4];
float oddResults[3];
int xcent, ycent, orn;
location.GetLocation(&xcent, &ycent);
#ifdef TRACE_ME
ofstream traceFile( "Trace.txt", ios::app );
traceFile << "Starting Filter at " << xcent << ", " << ycent << endl;
traceFile.close();
#endif // TRACE_ME
if (xcent == 62 && ycent == 146)
// if (xcent == 149 && ycent == 197)
{ // trouble spot on cube image.
int i = 0; // do nothing statement for a breakpoint.
}
int bestBand = 1;
// Small diameter even filters
location.SetOdd(false);
location.SetSmall(true);
int diam = location.GetDiam();
if (!m_filters.Lookup( diam, even ))
{
// create filters of this size
CFilter newFilters( diam, diam/m_subSampleDiam );
newFilter = true;
// put filters into the CMap
m_filters.SetAt( diam, newFilters );
if (!m_filters.Lookup( diam, even ))
return false; // failed to put filter into CMap.
}
#ifdef TRACE_ME
traceFile << "Starting 1st correlation at " << xcent << ", " << ycent << endl;
traceFile.close();
#endif // TRACE_ME
// Correlate small diameter even filters with subimage
evenMagSqr = correlate( location, even, bestBand);
// save the results
for (orn = 0; orn < even.m_orientations; orn ++)
evenResults[orn] = location.GetResult(orn);
// Small diameter odd filters
location.SetOdd(true);
diam = -diam; // negative key for odd filters
if (!m_filters.Lookup( diam, odd ))
{
// create filters of this size
CFilter newFilters( diam, diam/m_subSampleDiam );
newFilter = true;
// put filters into the CMap
m_filters.SetAt( diam, newFilters );
if (!m_filters.Lookup( diam, odd ))
return false; // failed to put filter into CMap.
}
// Correlate small diameter odd filters with subimage
oddMagSqr = correlate( location, odd, bestBand);
// save the results
for (orn = 0; orn < odd.m_orientations; orn ++)
oddResults[orn] = location.GetResult(orn);
if (newFilter)
{ // compute cross correlations.
even.fl_correlate( odd );
odd.fl_correlate( even );
// put filters into the CMap
m_filters.SetAt( diam, odd ); // negative diam for odd
diam = -diam; // positive key for even filters
m_filters.SetAt( diam, even );
newFilter = false;
}
// Now see if there are other color bands that give more response
// Ideally, the image is preprocessed into a luminance and 2 chrominance bands.
// More often, we are looking at red, green and blue bands.
// The edge found will be the maximum over all bands for the small diameter.
// Possible undesired effect: it might find edges in alpha
magSqr = evenMagSqr + oddMagSqr;
for (int band = 2; band <= m_pImage->NBands(); band++)
{
// Correlate small diameter even filters with subimage
location.SetOdd(false);
evenMagSqr = correlate( location, even, band);
// Correlate small diameter odd filters with subimage
location.SetOdd(true);
oddMagSqr = correlate( location, odd, band);
if (evenMagSqr + oddMagSqr > magSqr)
{
magSqr = evenMagSqr + oddMagSqr;
bestBand = band;
for (orn = 0; orn < odd.m_orientations; orn ++)
oddResults[orn] = location.GetResult(orn);
location.SetOdd(false);
for (orn = 0; orn < even.m_orientations; orn ++)
evenResults[orn] = location.GetResult(orn);
}
}
// Restore the results from the best band
for (orn = 0; orn < odd.m_orientations; orn ++)
location.SetResult( orn, oddResults[orn]);
location.SetOdd(false);
for (orn = 0; orn < even.m_orientations; orn ++)
location.SetResult( orn, evenResults[orn]);
#ifdef TRACE_ME
traceFile << "Done with small correlations at " << xcent << ", " << ycent << endl;
traceFile.close();
#endif // TRACE_ME
// Next do the even large diameter
location.SetOdd(false);
location.SetSmall(false);
diam = location.GetDiam();
if (!m_filters.Lookup( diam, even ))
{
// create filters of this size
CFilter newFilters( diam, diam/m_subSampleDiam );
// put filters into the CMap
newFilter = true;
m_filters.SetAt( diam, newFilters );
if (!m_filters.Lookup( diam, even ))
return false; // failed to put filter into CMap.
}
// Correlate large diameter even filters with subimage
correlate( location, even, bestBand);
// Next is the odd large diameter
diam = -diam; // negative key for odd filters
location.SetOdd(true);
if (!m_filters.Lookup( diam, odd ))
{
// create filters of this size
CFilter newFilters( diam, diam/m_subSampleDiam );
newFilter = true;
// put filters into the CMap
m_filters.SetAt( diam, newFilters );
if (!m_filters.Lookup( diam, odd ))
return false; // failed to put filter into CMap.
}
// Correlate large diameter odd filters with subimage
correlate( location, odd, bestBand);
if (newFilter)
{ // compute cross correlations.
even.fl_correlate( odd );
odd.fl_correlate( even );
// put filters into the CMap
m_filters.SetAt( diam, odd ); // negative diam for odd
diam = -diam; // positive key for even filters
m_filters.SetAt( diam, even );
}
#ifdef TRACE_ME
traceFile << "Finished Filter at " << xcent << ", " << ycent << endl;
traceFile.close();
#endif // TRACE_ME
return true;
}
/*------------------------------------------------------------------------*/
// Find the features at a particular location
bool CProcessFeatures::Interpret( CLocation& loc )
{
PROFILE("Interpret");
float corrEven; // not to be confused with the array of same name in loc
float corrOdd;
float magn_sqr; // squared magnitude of response at angles
if (loc.GetStrengthBound() < m_threshold * PRE_THRESH)
return true; // Nothing is there
// This is for debugging behavior at a particular place.
int xcent, ycent;
loc.GetLocation(&xcent, &ycent);
if (xcent == 62 && ycent == 146)
// if (xcent == 149 && ycent == 197)
{ // trouble spot on cube image.
magn_sqr = 0; // do nothing statement for a breakpoint.
#ifdef TRACE_ME
ofstream traceFile( "Trace.txt", ios::app );
traceFile << "Starting Interpret" << endl;
traceFile.close();
#endif // TRACE_ME
}
// Find the feature orientation
float angle = loc.GetAngle( &magn_sqr,
&corrEven, &corrOdd, m_fixedDirection);
// Retreive the filter used
// Small diameter odd filters
loc.SetSmall(true);
loc.SetOdd(true);
int diam = loc.GetDiam();
diam = -diam; // negative key for odd filters
CFilter filter;
if (!m_filters.Lookup( diam, filter ))
return false; // can't find filter
float base_strength = filter.m_maxResponse / 2;
// float base_strength = STRENGTH_SCALE * filter.m_self_ovlap[0];
loc.SetSmall(false);
int big_diam = loc.GetDiam();
big_diam = -big_diam; // negative key for odd filters
if (!m_filters.Lookup( big_diam, filter ))
return false; // can't find filter
float big_base_strength = filter.m_maxResponse / 2;
// float big_base_strength = STRENGTH_SCALE * filter.m_self_ovlap[0];
float strength = (float) sqrt((double)(magn_sqr)) / base_strength;
if (m_threshold < (float) 0.0)
m_threshold *= -strength;
if (strength > m_threshold * PRE_THRESH)
{ /* Strength is significant within the residual image */
int x, y, diam;
diam = loc.GetLocation( &x, &y);
// Retreive the filter used
// Small diameter even filters
loc.SetSmall(true);
loc.SetOdd(false);
diam = loc.GetDiam(); // positive key for even filters
if (!m_filters.Lookup( diam, filter ))
return false; // can't find filter
float center_lobe = filter.m_center_lobe;
// Large diameter even filters
loc.SetSmall(false);
big_diam = loc.GetDiam(); // positive key for even filters
if (!m_filters.Lookup( big_diam, filter ))
return false; // can't find filter
float big_center_lobe = filter.m_center_lobe;
float width_tuning = (float) 0.5 * (center_lobe +
big_center_lobe);
// Steer big filters to this angle
loc.SetSmall(false);
loc.SetOdd( false);
float corrBigEven = loc.Steer( angle);
loc.SetOdd( true);
float corrBigOdd = loc.Steer( angle);
// Create a CFeature
CFeature feature( x, y, diam, angle,
corrEven, corrOdd, corrBigEven, corrBigOdd,
base_strength, big_base_strength, big_diam,
big_center_lobe, width_tuning);
feature.multi_find(0, m_viewEdgesOnly);
// steer to other orientations.
// for (int i = 1; i < 4; i++)
int i = 2;
{
angle += PI_1/2; // PI_1/4 to use m_45
// Steer small filters to this angle
loc.SetSmall(true);
loc.SetOdd( false);
corrEven = loc.Steer( angle);
loc.SetOdd( true);
corrOdd = loc.Steer( angle);
// Steer big filters to this angle
loc.SetSmall(false);
loc.SetOdd( false);
corrBigEven = loc.Steer( angle);
loc.SetOdd( true);
corrBigOdd = loc.Steer( angle);
feature.AddSecondary( i, angle, corrEven, corrOdd, corrBigEven,
corrBigOdd);
feature.multi_find(i, m_viewEdgesOnly);
}
feature.corners();
// Add the feature to m_features if it is above threshold.
// We do not have any results from lateral antagonism at this point.
// GetAnagonism is used here for future expansion to the case where
// we are processing multiple frames and have previous results available.
if (feature.GetStrength() /* + m_lateralFactor * feature.GetAntagonism() */
>= m_threshold * PRE_THRESH)
{
m_features.Add( feature );
}
}
return true;
}
/*------------------------------------------------------------------------*/
/* This is used for correlating an image with a kernel. */
// Correlate the image at the given location with the filters.
// returned value is the squared sum of magnitudes at all orientations.
float CProcessFeatures::correlate(
CLocation& location,
CFilter& filters,
int band)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -