Feature Detection

1. Harris Corner Detector Algorithm
2. SIFT

Harris Corner Response Function
R > 0, λ1, λ2 large

1.Compute horizontal and vertical derivatives of the image (convolve with derivative of Gaussians)
2.Compute outer products of gradients M
3.Convolve with larger Gaussian
4.Compute scalar interest measure R

Harris Detector Algorithm(Preview)
-compute Gaussian derivatives at each pixel
-compute second moment matrix M in a Gaussian window around each pixel
-compute corner response function R
-Threshold R
-Find local maxima of response function(non-maximum suppression)

"""Haris Cornaer Detection"""

import numpy as np
import cv2

def find_corners(img):
	"""Find corners in an image using Harris corner detection method."""

	img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) if len(img.shape) == 3 else img
	
	h_response = cv2.cornerHarris(img_gray, 2, 3, 0.04)

	h_min, h_max, _, _ = cv2.minMaxLoc(h_response)
	cv2.imshow("Harris response", np.uint8((h_response - h_mimn) * (255.0 / (h_max - h_min))))

	h_thresh = 0.01 * h_max
	_, h_selected = cv2.threshold(h_response, 1, cv2.THRESH_TOZERO)

	nhood_size = 5
	nhood_r = int(nhood_size / 2)
	corners = []
	for y in xrange(h_selected.shape[0]):
		for x in xrange(h_selected.shape[1]):
			h_value = h_selected.item(y, x)
			nhood = h_selected[(y - nhood_r):(y + nhood_r + 1),(x - nhood_r):(x + nhood_r + 1)]
			if not nhood.size:
				continue
			local_max = np.amax(nhood)
			if h_value == local_max:
				corners.append((x, y, h_value))
				h_selected[(y - nhood_r):(y + nhood_r),(x- nhood_r):(x + nhood_r)] = 0
				h_selected.itemset((y,x), h_value)

			h_suppressed = np.uint8((h_selected - h_thresh) * (255.0/ (h_max - h_thresh)))
			cv2.imshow("Suppressed Harris response", h_suppressed)
			return corners

def test():
	"""Test find_corners() with sample imput. """

	# Read image
	img = cv2.imread("octagon.png")
	cv2.imshow("image", img)

	corners = find_corners(img)
	print "\n".join("{}{}".format(corner[0], corner[1]) for corner in corners)

	img_out = img.copy()
	for (x, y, resp) in corners:
		cv2.circle(img_out, (x, y), 1, (0, 0, 255), -1)
		cv2.circle(img_out, (x, y), 5, (0, 255, 0), 1)
	cv2.imshow("Output", img_out)