1 #ifndef CVD_HARRIS_CORNER_H 2 #define CVD_HARRIS_CORNER_H 10 #include <cvd/convolution.h> 11 #include <cvd/image.h> 20 inline C sq(
const C& c)
29 static float Compute(
float xx,
float xy,
float yy)
31 return (xx * yy - xy * xy) - 0.04 * sq(xx + yy);
39 static float Compute(
float xx,
float xy,
float yy)
41 float l1 = xx + yy + std::sqrt(sq(xx - yy) + 4.0 * xy * xy);
42 float l2 = xx + yy - std::sqrt(sq(xx - yy) + 4.0 * xy * xy);
43 return std::min(abs(l1), std::abs(l2));
51 static void insert(std::vector<ImageRef>& i,
const std::pair<float, ImageRef>& p)
53 i.push_back(p.second);
61 static void insert(std::vector<std::pair<float, ImageRef>>& i,
const std::pair<float, ImageRef>& p)
81 template <
class Score,
class Inserter,
class C,
class B>
96 typedef typename Pixel::traits<B>::wider_type gType;
99 for(
int y = 1; y < i.
size().y - 1; y++)
100 for(
int x = 1; x < i.
size().x - 1; x++)
104 gType gx = (gType)i[y][x - 1] - i[y][x + 1];
105 gType gy = (gType)i[y - 1][x] - i[y + 1][x];
113 convolveGaussian(xx, xx, blur, sigmas);
114 convolveGaussian(xy, xy, blur, sigmas);
115 convolveGaussian(yy, yy, blur, sigmas);
119 int kspread = (int)ceil(sigmas * blur);
122 for(
int y = kspread; y < i.
size().y - kspread; y++)
123 for(
int x = kspread; x < i.
size().x - kspread; x++)
124 xx[y][x] = Score::Compute(xx[y][x], xy[y][x], yy[y][x]);
126 vector<pair<float, ImageRef>> corner_heap;
127 corner_heap.reserve(N + 1);
129 typedef greater<pair<float, ImageRef>> minheap_compare;
147 for(
int y = kspread; y < i.
size().y - kspread; y++)
148 for(
int x = kspread; x < i.
size().x - kspread; x++)
152 if(c > xx[y - 1][x - 1] && c > xx[y - 1][x + 0] && c > xx[y - 1][x + 1] && c > xx[y - 0][x - 1] && c > xx[y - 0][x + 1] && c > xx[y + 1][x - 1] && c > xx[y + 1][x + 0] && c > xx[y + 1][x + 1])
154 if(corner_heap.size() <= N || c > corner_heap[0].first)
156 corner_heap.push_back(make_pair(c,
ImageRef(x, y)));
157 push_heap(corner_heap.begin(), corner_heap.end(), minheap_compare());
160 if(corner_heap.size() > N)
162 pop_heap(corner_heap.begin(), corner_heap.end(), minheap_compare());
163 corner_heap.pop_back();
168 for(
unsigned int i = 0; i < corner_heap.
size(); i++)
169 Inserter::insert(c, corner_heap[i]);
173 void harris_corner_detect(
const BasicImage<C>& i, std::vector<ImageRef>& c,
unsigned int N,
float blur = 1.0,
float sigmas = 3.0)
176 harrislike_corner_detect<Harris::HarrisScore, Harris::PosInserter>(i, c, N, blur, sigmas, xx, xy, yy);
180 void shitomasi_corner_detect(
const BasicImage<C>& i, std::vector<ImageRef>& c,
unsigned int N,
float blur = 1.0,
float sigmas = 3.0)
183 harrislike_corner_detect<Harris::ShiTomasiScore, Harris::PosInserter>(i, c, N, blur, sigmas, xx, xy, yy);
All classes and functions are within the CVD namespace.
Definition: argb.h:6
ImageRef size() const
What is the size of this image?
Definition: image.h:557
Used to save corner positions from harrislike_corner_detect.
Definition: harris_corner.h:49
void harrislike_corner_detect(const BasicImage< B > &i, C &c, unsigned int N, float blur, float sigmas, BasicImage< float > &xx, BasicImage< float > &xy, BasicImage< float > &yy)
Generic Harris corner detection function.
Definition: harris_corner.h:82
Compute the score according to Shi-Tomasi.
Definition: harris_corner.h:37
Used to save corner positions and scores from harrislike_corner_detect.
Definition: harris_corner.h:59
Input images have incompatible dimensions.
Definition: convolution.h:117
Definition: image_ref.h:29
void zeroBorders(BasicImage< T > &I)
Set the one-pixel border (top, bottom, sides) of an image to zero values.
Definition: utility.h:109
A generic image class to manage a block of arbitrarily padded data as an image.
Definition: image.h:273
A full image which manages its own data.
Definition: image.h:623
Compute the corner score according to Harris.
Definition: harris_corner.h:27