1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
| for( int y = 1; y < imgsize.height - 1; y++ )
{
const float* eig_data = (const float*)myShiTomasi_dst.ptr(y);
const float* tmp_data = (const float*)tmp.ptr(y);
const uchar* mask_data = mask.data ? mask.ptr(y) : 0;
for( int x = 1; x < imgsize.width - 1; x++ )
{
float val = eig_data[x];
if( val != 0 && val == tmp_data[x] && (!mask_data || mask_data[x]) )
tmpcorners.push_back(eig_data + x);
}
}
sort(tmpcorners, greaterThanPtr<float>() );
int total = tmpcorners.size(), ncorners = 0;;
if(minDistance >= 1)
{
// Partition the image into larger grids
int w = src.cols;
int h = src.rows;
const int cell_size = cvRound(minDistance);
const int grid_width = (w + cell_size - 1) / cell_size;
const int grid_height = (h + cell_size - 1) / cell_size;
std::vector<std::vector<Point2f> > grid(grid_width*grid_height);
minDistance *= minDistance;
for( int i = 0; i < total; i++ )
{
int ofs = (int)((const uchar*)tmpcorners[i] - myShiTomasi_dst.data);
int y = (int)(ofs / myShiTomasi_dst.step);
int x = (int)((ofs - y*myShiTomasi_dst.step)/sizeof(float));
bool good = true;
int x_cell = x / cell_size;
int y_cell = y / cell_size;
int x1 = x_cell - 1;
int y1 = y_cell - 1;
int x2 = x_cell + 1;
int y2 = y_cell + 1;
// boundary check
x1 = std::max(0, x1);
y1 = std::max(0, y1);
x2 = std::min(grid_width-1, x2);
y2 = std::min(grid_height-1, y2);
for( int yy = y1; yy <= y2; yy++ )
{
for( int xx = x1; xx <= x2; xx++ )
{
vector <Point2f> &m = grid[yy*grid_width + xx];
if( m.size() )
{
for(int j = 0; j < m.size(); j++)
{
float dx = x - m[j].x;
float dy = y - m[j].y;
if( dx*dx + dy*dy < minDistance )
{
good = false;
goto break_out;
}
}
}
}
}
break_out:
if(good)
{
grid[y_cell*grid_width + x_cell].push_back(Point2f((float)x, (float)y));
Corners.push_back(Point2f((float)x, (float)y));
++ncorners;
if( max_qualityLevel > 0 && (int)ncorners == max_qualityLevel )
break;
}
}
}
else
{
for(int i = 0; i < total; i++ )
{
int ofs = (int)((const uchar*)tmpcorners[i] - myShiTomasi_dst.data);
int y = (int)(ofs / myShiTomasi_dst.step);
int x = (int)((ofs - y*myShiTomasi_dst.step)/sizeof(float));
Corners.push_back(Point2f((float)x, (float)y));
++ncorners;
if( max_qualityLevel > 0 && (int)ncorners == max_qualityLevel )
break;
}
} |
Partager