Introduction
So far, we have seen some tutorials on algorithms, which we use to detect objects from a given image. Lastly, we saw how to apply Hough circle transformation. Now we will see yet another algorithm for objects detection – the Harris corner detection algorithm. I will provide some brief information about it and then we will see an exemplary application of that algorithm.
Harris corner detection
First let’s define what is a corner. The Computer Vision world defines corner like a point at which two edges with different directions intersect. The algorithm tests and finds the difference in the intensity of each point with its neighboring points. Basically, there is a formula, which we apply to each pixel and depending on the value, the point might be a corner or not. Here is the formula:
R = det(M)−k(trace(M))2
Here det(M) is equal to λ1*λ2 and trace(M) is equal to λ1 + λ2. The k variable shall be between [0.04, 0.06]. The λ1 and λ2 are the eigenvalues of M. If the result R is greater than a given threshold, we say that the point is a corner. More information is available here, here and here. The good news is that OpenCV provides us with a function to calculate the Harris corner directly. And next we will see how to use it.
Harris corner detection implementation
As I said we have a function in OpenCV to take care of applying the Harris corner detection algorithm. We will see how to use it and the results from it. Let us see the exemplary code first.
// Apply the Harris Corner Detection operation to an image void applyHarrisCornerDetection() { // Path to the input image std::string l_pathToInputImage{ "../Resources/car.jpg" }; // Create an object to hold the image data of the first image Mat l_image; // Read the image date from a file with no change to color scheme l_image = imread(l_pathToInputImage, IMREAD_UNCHANGED); // Check if we have read the first image data correctly if (!l_image.data) { std::cout << "No image data \n"; return; } // Convert the image to grayscale Mat l_imageGrayscale{}; cvtColor(l_image, l_imageGrayscale, COLOR_BGR2GRAY); // Harris corner detection constants constexpr int const c_blockSize = 2; constexpr int const c_apertureSize = 3; constexpr double const c_kParameter = 0.06; constexpr int const c_threshold = 120; // Apply the Harris corner detection Mat l_outputHarris = Mat::zeros(l_image.size(), CV_32FC1); cornerHarris(l_imageGrayscale, l_outputHarris, c_blockSize, c_apertureSize, c_kParameter); // Normalize the result Mat l_outputHarrisNormalized, l_outputHarrisScaled; normalize(l_outputHarris, l_outputHarrisNormalized, 0, 255, NORM_MINMAX, CV_32FC1, Mat()); convertScaleAbs(l_outputHarrisNormalized, l_outputHarrisScaled); // Draw circles around the detected corners constexpr int const c_radius = 4; constexpr int const c_lineThickness = 2; for (int i = 0; i < l_outputHarrisNormalized.rows; i++) { for (int j = 0; j < l_outputHarrisNormalized.cols; j++) { if ((int)l_outputHarrisNormalized.at<float>(i, j) > c_threshold) { circle(l_outputHarrisScaled, Point(j, i), c_radius, Scalar(0, 0, 255), c_lineThickness, LINE_AA); } } } // Display the input image namedWindow("Input", WINDOW_NORMAL); cv::imshow("Input", l_image); // Display the Hough Transform result image namedWindow("Result Harris Corner Detection", WINDOW_NORMAL); cv::imshow("Result Harris Corner Detection", l_outputHarrisScaled); }
As always, we start with the loading of an image from the file system. We need to convert the image to a grayscale as a next step, because the Harris corner detection algorithm works with intensities. Next, we set some constants that we will use in the function call. And then we create one matrix, which will hold the results.
The OpenCV function
Following is the call to the function for Harris corner detection. The function is called cornerHarris. The first argument we provide to it is the source matrix, in our case the grayscale image matrix. The second argument is the output matrix, where we will store the results. Next is the size of the block, applied for the corner detection or in other words, the neighborhood of pixels used to calculate the eigenvalues. Following argument is the aperture size, which OpenCV uses internally to apply the Sobel operator. The fifth parameter is the “k” parameter, which we have seen in the above formula. We should set it to a value between 0.04 and 0.06. Finally, we have the border type, which I will leave to its default value.
After the OpenCV function finishes processing the Harris corner detection algorithm and then stores the result in some matrix, we will further proceed with our program. Next thing we do is to normalize the results we have. Using the normalize function we will normalize the results in the 0..255 range. Then we will convert them to 8-bit values, because the Harris corner function returns them in 32-bit format. We do this in order to be able to draw the result matrix.
Lastly, we will add circles around the points, which we detected as corners. In two loops we traverse the matrix and for each point we check whether it is greater than a given threshold and if so, we will consider it to be a corner and put a circle around it. We saw how to draw circles in this tutorial.
The result
After we have found the corners and circled them, it is time to display the results. Below you will see how it looks like on my side. You can see small black circles around points, which the OpenCV algorithms considers to be corners. You can go ahead and play with the parameters of the Harris corner detection function and see different results.

Conclusion
In this tutorial we saw how to detect corners in each image using the Harris corner detection algorithm. We touched some basics about that algorithm and saw how to use a ready-to-use OpenCV function to apply this algorithm. Later, you will find this functionality very useful.
As usual the code example is available below as an archive and in GitHub.
Next, we will see yet another algorithm to detect corners – the Shi-Tomasi algorithm.

Passionate developer, loving husband and caring father. As an introvert programming is my life. I work as a senior software engineer in a big international company. My hobbies include playing computer games (mostly World of Warcraft), watching TV series and hiking.