Codes
void harris_corners(cv::Mat const &input, cv::Mat &output,
int block_size, int ksize, float k)
{
//step 1 : make sure the type of the input is valid
if(!(input.type() == CV_8U || input.type() == CV_32F)){
throw std::runtime_error(COMMON_DEBUG_MESSAGE +
"input.type() != CV_8U ||"
" input.type() != CV_32F\n");
}
output.create(input.size(), CV_32F);
//step 2 : scale need to normalize the result of the sobel filter
//I don't get it why they initialize the scale like this
//if anyone figure it out please tell me why, thanks
double scale = (double)(1 << ((ksize > 0 ? ksize : 3) - 1))
* block_size;
//the range of CV_8U are in range [0, 255];
//CV_32F are in range [0, 1]
if(input.type() == CV_8U){
scale *= 255.0;
}
scale = 1.0/scale;
//step 3 : calculate the gradient of x and y direction
cv::Mat dx, dy;
cv::Sobel(input, dx, CV_32F, 1, 0, ksize, scale);
cv::Sobel(input, dy, CV_32F, 0, 1, ksize, scale);
cv::Size size = input.size();
//step 4 : convolution and save dx*dx, dx*dy, dy*dy in cov
using Type = float;
cv::Mat cov(size, CV_32FC3);
for(int i = 0; i < size.height; ++i){
Type *cov_data = cov.ptr<Type>(i);
Type const *dxdata = dx.ptr<Type>(i);
Type const *dydata = dy.ptr<Type>(i);
for(int j = 0; j < size.width; ++j){
Type const dx = dxdata[j];
Type const dy = dydata[j];
*cov_data = dx*dx; ++cov_data;
*cov_data = dx*dy; ++cov_data;
*cov_data = dy*dy; ++cov_data;
}
}
//step 5 : generate the result of Harris matrix,
//all of the weight are set as 1
cv::boxFilter(cov, cov, cov.depth(), cv::Size(block_size, block_size),
cv::Point(-1,-1), false);
//step 6 : optimize the iteration speed, not a neccessary
//step for harris_corner
if( cov.isContinuous() && output.isContinuous() ){
size.width = input.total();
size.height = 1;
}
//step 7 : find out Mc and save it to the output Mat
for(int i = 0; i < size.height; ++i){
Type const *cov_data = cov.ptr<Type>(i);
Type *dst = output.ptr<Type>(i);
for(int j = 0; j < size.width; ++j){
Type const a = *cov_data; ++cov_data;
Type const b = *cov_data; ++cov_data;
Type const c = *cov_data; ++cov_data;
Type const temp = a + c;
dst[j] = a*c - b*b - k*(temp)*(temp);
}
}
}
The most curious step is step 2, I have no idea why are they select a scale like that?If anybody know the answer, please give me some comment or leave the answer at openCV forum.
Results
![]() |
| graph_00 |
![]() |
| graph_01 |
Shi-Tomashi improve the result of Harris corners, openCV2 implemented it as function "cv::goodFeaturesToTrack".
As usual, the codes can download from github.


No comments:
Post a Comment