예제 #1
0
	def __init__(self, filename, thresh):
		self.__filename = filename
		self.__thresh = thresh
		self.__image = cv.LoadImage(filename, cv.CV_LOAD_IMAGE_UNCHANGED)
		gray = mt.normalize_image(cv.LoadImage(filename,
											   cv.CV_LOAD_IMAGE_GRAYSCALE))
		self.__grayscale = cv.CreateImage(cv.GetSize(gray), cv.IPL_DEPTH_8U, 1)
		cv.Convert(gray, self.__grayscale)
		self.__integralImage = mt.integral_image(self.__grayscale)
		self.__responses = []
		self.__features = []
		self.__traces = []
		self.__orientation = []
		self.__descriptors = []
예제 #2
0
	def __build_descriptors(self):
		for k in range(0, len(self.__features)):
			(x, y, s, l_sign) = self.__features[k]
			sigma = mt.SIGMA[s]
			l = int(0.5*sigma)
			theta = self.__orientation[k]
			cosT, sinT = np.cos(theta), np.sin(theta)
			descriptor = np.zeros((64))
			k = 0
			for (i, j) in itertools.product(range(0, 4), range(0, 4)):
				sum_resp_x = sum_resp_y = sum_abs_resp_x = sum_abs_resp_y = 0
				for (m, n) in itertools.product(range(0, 5), range(0, 5)):
					X = cv.Round(x + sigma*(cosT*(5*(i-2) + m) - sinT*(5*(j-2) + n)))
					Y = cv.Round(y + sigma*(sinT*(5*(i-2) + m) + cosT*(5*(j-2) + n)))
					gauss = mt.gaussian(X-x, Y-y, 3.3*sigma)
					resp_x = (self.__box_integral(0, l, l, l, X, Y) - 
							  self.__box_integral(l, 0, l, l, X, Y))
					resp_y = (self.__box_integral(l, l, l, 0, X, Y) - 
							  self.__box_integral(l, l, 0, l, X, Y))
					respX = gauss*(-sinT*resp_x + cosT*resp_y)
					respY = gauss*(cosT*resp_x + sinT*resp_y)
					sum_resp_x += respX
					sum_resp_y += respY
					sum_abs_resp_x += np.abs(respX)
					sum_abs_resp_y += np.abs(respY)
				descriptor[k] = sum_resp_x
				descriptor[k+1] = sum_resp_y
				descriptor[k+2] = sum_abs_resp_x
				descriptor[k+3] = sum_abs_resp_y
				k = k + 4
			norm = np.linalg.norm(descriptor)
			self.__descriptors.append(descriptor / norm)		
예제 #3
0
	def __find_orientation(self):
		for (x, y, s, l_sign) in self.__features:
			sigma = mt.SIGMA[s]
			l = cv.Round(2*sigma)
			haar_respX = {}
			haar_respY = {}
			angle = {}
			indexes = set(itertools.product(range(-6, 7), range(-6, 7)))
			for (i, j) in [elem for elem in indexes if (elem[0]**2 + elem[1]**2) <= 36]:
				X, Y = cv.Round(x + i * sigma), cv.Round(y + j * sigma)
				gauss = mt.gaussian(X-x, Y-y, 2*sigma)
				haar_respX[(i, j)] = (self.__box_integral(0, l, l, l, X, Y) - 
									  self.__box_integral(l, 0, l, l, X, Y)) * gauss
				haar_respY[(i, j)] = (self.__box_integral(l, l, l, 0, X, Y) - 
									  self.__box_integral(l, l, 0, l, X, Y)) * gauss
				angle[(i, j)] = cv.FastArctan(haar_respY[(i, j)], haar_respX[(i, j)])
			max_length = 0
			max_resp_x = max_resp_y = 0
			for theta in range(Surf.STARTING_ANGLE, Surf.LAST_ANGLE):
				resp_x = resp_y = 0
				for p in [index for index in angle.keys() if (theta - 30 <= angle[index] and 
															  angle[index] <= theta + 30)]:
					resp_x += haar_respX[p]
					resp_y += haar_respY[p]
				resp_len = resp_x**2 + resp_y**2
				if resp_len > max_length:
					max_resp_x, max_resp_y = resp_x, resp_y
					max_length = resp_len
			self.__orientation.append(cv.FastArctan(max_resp_y, max_resp_x) * mt.TO_RADS_RATIO)		
예제 #4
0
	def __scale_space_refinement(self):
		responses = self.__responses
		fake_maxima = []
		for i in range(0, len(self.__features)):
			(x, y, s, l_sign) = self.__features[i]
			k = Surf.REFINEMENT_ITERATION_COUNT
			while k >= 0 and self.__is_not_outlier(x, y, s):
				k = k - 1 
				dx = mt.du_dx(responses, x, y, s)
				dy = mt.du_dy(responses, x, y, s)
				ds = mt.du_ds(responses, x, y, s)
				dxx = mt.du2_dx2(responses, x, y, s)
				dyy = mt.du2_dy2(responses, x, y, s)
				dxy = mt.du2_dxdy(responses, x, y, s)
				dss = mt.du2_ds2(responses, x, y, s)
				dxds = mt.du2_dxds(responses, x, y, s)
				dyds = mt.du2_dyds(responses, x, y, s)
				detH = (2*dxds*dxy*dyds - (dxds**2)*dyy - (dxy**2)*dss + 
					    dxx*dyy*dss - dxx*(dyds**2))
				if detH <> 0:
					delta_x = -(dx*(dyy*dss - dyds**2) + 
							    dy*(dxds*dyds - dss*dxy) + 
							    ds*(dxy*dyds - dxds*dyy)) / detH
					delta_y = -(dx*(dxy*dss - dxds*dyds) + 
							    dy*(dxds**2 - dxx*dss) + 
							    ds*(dxx*dyds - dxds*dxy)) / detH
					delta_s = -(dx*(dxy*dyds - dxds*dyy) + 
							    dy*(dxds*dxy - dxx*dyds) + 
							    ds*(dxx*dyy - dxy**2)) / detH
					if (np.abs(delta_x) < 1 and np.abs(delta_y) < 1 and 
					    np.abs(delta_s) < 0.4*(2**Surf.OCTAVES[s])):
						break
					else:
						(x, y, s) = (int(x + delta_x + 0.5), 
									 int(y + delta_y + 0.5), 
									 int(s + delta_s/(0.4*(2**Surf.OCTAVES[s])) + 0.5))
				else:
					break
			if (k == -1 or not self.__is_not_outlier(x, y, s) or 
			    np.abs(x - self.__features[i][0]) > Surf.REFINEMENT_ITERATION_COUNT or 
			    np.abs(y - self.__features[i][1]) > Surf.REFINEMENT_ITERATION_COUNT):
				fake_maxima.append(self.__features[i])
			else:
				self.__features[i] = (x, y, s, l_sign)
		self.__features = mt.list_subtraction(self.__features, fake_maxima)
예제 #5
0
	def __find_features(self):
		self.__build_resp_layers()
		resp_layers = self.__responses
		for i in range(0, len(Surf.FILTER_MAP)):
			for j in range(1, 3):
				b = resp_layers[Surf.FILTER_MAP[i, j-1]]
				indM = Surf.FILTER_MAP[i, j]
				m = resp_layers[indM]
				t = resp_layers[Surf.FILTER_MAP[i, j+1]]
				candidates = mt.nms_2d(m, m.width, m.height, Surf.N)
				for (k, n) in candidates:
					if np.abs(m[k, n]) <= self.__thresh:
						continue
					failed = False
					for (x, y) in itertools.product(range(k-1, k+2), range(n-1, n+2)):
						if failed:
							break
						# > or >=
						if b[x, y] >= m[k, n] or t[x, y] >= m[k, n]:
							failed = True
					if not failed and self.__is_not_outlier(n, k, indM):
						self.__features.append((n, k, indM, 
											    self.__laplacian_sign(n, k, indM)))