OpenCV  3.2.0
Open Source Computer Vision
Creating yor own corner detector

.2.0+dfsg_doc_tutorials_features2d_trackingmotion_generic_corner_detector_generic_corner_detector

Goal

In this tutorial you will learn how to:

  • Use the OpenCV function cv::cornerEigenValsAndVecs to find the eigenvalues and eigenvectors to determine if a pixel is a corner.
  • Use the OpenCV function cv::cornerMinEigenVal to find the minimum eigenvalues for corner detection.
  • To implement our own version of the Harris detector as well as the Shi-Tomasi detector, by using the two functions above.

Theory

Code

This tutorial code's is shown lines below. You can also download it from here

#include <iostream>
using namespace cv;
using namespace std;
Mat src, src_gray;
Mat myHarris_dst; Mat myHarris_copy; Mat Mc;
Mat myShiTomasi_dst; Mat myShiTomasi_copy;
int myShiTomasi_qualityLevel = 50;
int myHarris_qualityLevel = 50;
int max_qualityLevel = 100;
double myHarris_minVal; double myHarris_maxVal;
double myShiTomasi_minVal; double myShiTomasi_maxVal;
RNG rng(12345);
const char* myHarris_window = "My Harris corner detector";
const char* myShiTomasi_window = "My Shi Tomasi corner detector";
void myShiTomasi_function( int, void* );
void myHarris_function( int, void* );
int main( int, char** argv )
{
src = imread( argv[1], IMREAD_COLOR );
cvtColor( src, src_gray, COLOR_BGR2GRAY );
int blockSize = 3; int apertureSize = 3;
myHarris_dst = Mat::zeros( src_gray.size(), CV_32FC(6) );
Mc = Mat::zeros( src_gray.size(), CV_32FC1 );
cornerEigenValsAndVecs( src_gray, myHarris_dst, blockSize, apertureSize, BORDER_DEFAULT );
/* calculate Mc */
for( int j = 0; j < src_gray.rows; j++ )
{ for( int i = 0; i < src_gray.cols; i++ )
{
float lambda_1 = myHarris_dst.at<Vec6f>(j, i)[0];
float lambda_2 = myHarris_dst.at<Vec6f>(j, i)[1];
Mc.at<float>(j,i) = lambda_1*lambda_2 - 0.04f*pow( ( lambda_1 + lambda_2 ), 2 );
}
}
minMaxLoc( Mc, &myHarris_minVal, &myHarris_maxVal, 0, 0, Mat() );
/* Create Window and Trackbar */
namedWindow( myHarris_window, WINDOW_AUTOSIZE );
createTrackbar( " Quality Level:", myHarris_window, &myHarris_qualityLevel, max_qualityLevel, myHarris_function );
myHarris_function( 0, 0 );
myShiTomasi_dst = Mat::zeros( src_gray.size(), CV_32FC1 );
cornerMinEigenVal( src_gray, myShiTomasi_dst, blockSize, apertureSize, BORDER_DEFAULT );
minMaxLoc( myShiTomasi_dst, &myShiTomasi_minVal, &myShiTomasi_maxVal, 0, 0, Mat() );
/* Create Window and Trackbar */
namedWindow( myShiTomasi_window, WINDOW_AUTOSIZE );
createTrackbar( " Quality Level:", myShiTomasi_window, &myShiTomasi_qualityLevel, max_qualityLevel, myShiTomasi_function );
myShiTomasi_function( 0, 0 );
waitKey(0);
return(0);
}
void myShiTomasi_function( int, void* )
{
myShiTomasi_copy = src.clone();
if( myShiTomasi_qualityLevel < 1 ) { myShiTomasi_qualityLevel = 1; }
for( int j = 0; j < src_gray.rows; j++ )
{ for( int i = 0; i < src_gray.cols; i++ )
{
if( myShiTomasi_dst.at<float>(j,i) > myShiTomasi_minVal + ( myShiTomasi_maxVal - myShiTomasi_minVal )*myShiTomasi_qualityLevel/max_qualityLevel )
{ circle( myShiTomasi_copy, Point(i,j), 4, Scalar( rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255) ), -1, 8, 0 ); }
}
}
imshow( myShiTomasi_window, myShiTomasi_copy );
}
void myHarris_function( int, void* )
{
myHarris_copy = src.clone();
if( myHarris_qualityLevel < 1 ) { myHarris_qualityLevel = 1; }
for( int j = 0; j < src_gray.rows; j++ )
{ for( int i = 0; i < src_gray.cols; i++ )
{
if( Mc.at<float>(j,i) > myHarris_minVal + ( myHarris_maxVal - myHarris_minVal )*myHarris_qualityLevel/max_qualityLevel )
{ circle( myHarris_copy, Point(i,j), 4, Scalar( rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255) ), -1, 8, 0 ); }
}
}
imshow( myHarris_window, myHarris_copy );
}

Explanation

Result

cv::Mat::rows
int rows
the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions
Definition: mat.hpp:1959
imgproc.hpp
cv::IMREAD_COLOR
@ IMREAD_COLOR
If set, always convert image to the 3 channel BGR color image.
Definition: imgcodecs.hpp:67
cv::Mat::zeros
static MatExpr zeros(int rows, int cols, int type)
Returns a zero array of the specified size and type.
CV_32FC
#define CV_32FC(n)
Definition: interface.h:116
cv::cvtColor
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0)
Converts an image from one color space to another.
cv::Mat::at
_Tp & at(int i0=0)
Returns a reference to the specified array element.
cv::cornerEigenValsAndVecs
void cornerEigenValsAndVecs(InputArray src, OutputArray dst, int blockSize, int ksize, int borderType=BORDER_DEFAULT)
Calculates eigenvalues and eigenvectors of image blocks for corner detection.
cv::waitKey
int waitKey(int delay=0)
Waits for a pressed key.
cv::BORDER_DEFAULT
@ BORDER_DEFAULT
same as BORDER_REFLECT_101
Definition: base.hpp:262
highgui.hpp
cv::namedWindow
void namedWindow(const String &winname, int flags=WINDOW_AUTOSIZE)
Creates a window.
cv::pow
void pow(InputArray src, double power, OutputArray dst)
Raises every array element to a power.
cv::imread
Mat imread(const String &filename, int flags=IMREAD_COLOR)
Loads an image from a file.
cv::COLOR_BGR2GRAY
@ COLOR_BGR2GRAY
convert between RGB/BGR and grayscale, color conversions
Definition: imgproc.hpp:538
cv::Vec
Template class for short numerical vectors, a partial case of Matx.
Definition: matx.hpp:306
cv::Mat::cols
int cols
Definition: mat.hpp:1959
cv::Mat::size
MatSize size
Definition: mat.hpp:1978
imgcodecs.hpp
cv::cornerMinEigenVal
void cornerMinEigenVal(InputArray src, OutputArray dst, int blockSize, int ksize=3, int borderType=BORDER_DEFAULT)
Calculates the minimal eigenvalue of gradient matrices for corner detection.
cv::imshow
void imshow(const String &winname, InputArray mat)
Displays an image in the specified window.
cv::minMaxLoc
void minMaxLoc(InputArray src, double *minVal, double *maxVal=0, Point *minLoc=0, Point *maxLoc=0, InputArray mask=noArray())
Finds the global minimum and maximum in an array.
cv::Scalar
Scalar_< double > Scalar
Definition: types.hpp:606
cv::RNG
Random Number Generator.
Definition: core.hpp:2690
cv::Mat::clone
Mat clone() const
Creates a full copy of the array and the underlying data.
cv::Point
Point2i Point
Definition: types.hpp:183
cv::Mat
n-dimensional dense array class
Definition: mat.hpp:741
i
for i
Definition: modelConvert.m:63
cv::createTrackbar
int createTrackbar(const String &trackbarname, const String &winname, int *value, int count, TrackbarCallback onChange=0, void *userdata=0)
Creates a trackbar and attaches it to the specified window.
cv
Definition: affine.hpp:52
cv::WINDOW_AUTOSIZE
@ WINDOW_AUTOSIZE
the user cannot resize the window, the size is constrainted by the image displayed.
Definition: highgui.hpp:184
CV_32FC1
#define CV_32FC1
Definition: interface.h:112
cv::circle
void circle(InputOutputArray img, Point center, int radius, const Scalar &color, int thickness=1, int lineType=LINE_8, int shift=0)
Draws a circle.