def computeFeature(self, img, useGaussianSmoothing = True):
		img_hsv = cv2.cvtColor(img.astype(np.float32), cv2.COLOR_BGR2HSV)
		# print "hue channel:", img_hsv[:,:,0]
		# print "saturation channel:", img_hsv[:,:,1]
		inner_patch_size = comparePatches.getGaussianScale(self.patch.size, self.GAUSSIAN_SCALE_FACTOR, -3)
		inner_patch = comparePatches.Patch(self.patch.x, self.patch.y, inner_patch_size)

		gaussian_window = comparePatches.gauss_kernels(self.patch.size, sigma = self.patch.size/4.0)
		inner_gaussian_window = gaussian_window[ gaussian_window.shape[0]/2 - inner_patch.size/2: gaussian_window.shape[0]/2 + inner_patch.size/2 + 1 ,\
		 gaussian_window.shape[1]/2 - inner_patch.size/2: gaussian_window.shape[1]/2 + inner_patch.size/2 + 1]

		assert gaussian_window.shape == (self.patch.size, self.patch.size), "outer gaussian_window size not correct"
		assert inner_gaussian_window.shape == (inner_patch.size, inner_patch.size), "inner gaussian_window size not correct"

		if (self.patch.outer_hue_hist_scale_3_gaus_4 is None):
			self.patch.outer_hue_hist_scale_3_gaus_4 = self.computeHueHist(img_hsv, self.patch, gaussian_window)
		if (self.patch.inner_hue_hist_scale_3_gaus_4 is None):
			self.patch.inner_hue_hist_scale_3_gaus_4 = self.computeHueHist(img_hsv, inner_patch, inner_gaussian_window)
		
		outer_hist = self.patch.outer_hue_hist_scale_3_gaus_4
		inner_hist = self.patch.inner_hue_hist_scale_3_gaus_4
		border_hist = outer_hist - inner_hist
		# model_constructor = np.zeros(len(border_hist))
		# model_constructor[4:7] = border_hist[4:7]
		# print model_constructor
		self.hist = np.concatenate((border_hist, inner_hist[4:7]), axis = 1)
		self.hist = normalize(self.hist, norm='l1')[0] # normalize the histogram using l1
	def computeFeature(self, img, useGaussianSmoothing = True):
		inner_patch_size = comparePatches.getGaussianScale(self.patch.size, self.GAUSSIAN_SCALE_FACTOR, -self.GAUSSIAN_SCALE)
		inner_patch = comparePatches.Patch(self.patch.x, self.patch.y, inner_patch_size)

		gaussian_window = comparePatches.gauss_kernels(self.patch.size, sigma = self.patch.size/self.GAUSSIAN_WINDOW_LENGTH_SIGMA)
		inner_gaussian_window = gaussian_window[ \
		gaussian_window.shape[0]/2 - inner_patch.size/2: gaussian_window.shape[0]/2 + inner_patch.size/2 + 1 ,\
		gaussian_window.shape[1]/2 - inner_patch.size/2: gaussian_window.shape[1]/2 + inner_patch.size/2 + 1]

		assert gaussian_window.shape == (self.patch.size, self.patch.size), "outer gaussian_window size not correct"
		assert inner_gaussian_window.shape == (inner_patch.size, inner_patch.size), "inner gaussian_window size not correct"

		"""inner patch HOG"""
		self.outer_HOG = self.patch.computeSinglePatchHOG(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY).astype(np.int), gaussian_window)
		self.inner_HOG = inner_patch.computeSinglePatchHOG(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY).astype(np.int), inner_gaussian_window)
		
		"""border HOG"""
		self.border_HOG = self.patch.HOG_Uncirculated - inner_patch.HOG_Uncirculated
		max_ori = np.argmax(self.border_HOG) # use maximum
		self.border_HOG =  np.array(list(self.border_HOG[max_ori:len(self.border_HOG)]) + \
		list(self.border_HOG[0:max_ori])) # rotate circular hist

		self.hist = np.concatenate((self.inner_HOG, self.border_HOG), axis = 1)
		# comparePatches.drawPatchesOnImg(np.copy(img),[self.patch, inner_patch], True)
		return
	def fitParadigm(self, img):
		"""
		it's clicker's responsibility to make sure that the patch is having a shape in the center patch, but nothing in the border
		"""
		BORDER_HOG_FRACTION_THRESH = 0.4
		inner_patch_size = comparePatches.getGaussianScale(self.patch.size, self.GAUSSIAN_SCALE_FACTOR, -self.GAUSSIAN_SCALE)
		inner_patch = comparePatches.Patch(self.patch.x, self.patch.y, inner_patch_size)

		gaussian_window = comparePatches.gauss_kernels(self.patch.size, sigma = self.patch.size/self.GAUSSIAN_WINDOW_LENGTH_SIGMA)
		inner_gaussian_window = gaussian_window[ \
		gaussian_window.shape[0]/2 - inner_patch.size/2: gaussian_window.shape[0]/2 + inner_patch.size/2 + 1 ,\
		gaussian_window.shape[1]/2 - inner_patch.size/2: gaussian_window.shape[1]/2 + inner_patch.size/2 + 1]

		assert gaussian_window.shape == (self.patch.size, self.patch.size), "outer gaussian_window size not correct"
		assert inner_gaussian_window.shape == (inner_patch.size, inner_patch.size), "inner gaussian_window size not correct"

		"""inner patch HOG"""
		outer_HOG = self.patch.computeSinglePatchHOG(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY).astype(np.int), gaussian_window)
		inner_HOG = inner_patch.computeSinglePatchHOG(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY).astype(np.int), inner_gaussian_window)
		
		"""border HOG"""
		border_HOG = self.patch.HOG_Uncirculated - inner_patch.HOG_Uncirculated
		max_ori = np.argmax(border_HOG) # use maximum
		border_HOG =  np.array(list(border_HOG[max_ori:len(border_HOG)]) + \
		list(border_HOG[0:max_ori])) # rotate circular hist

		"""border should be quite plain, not high HOG response"""
		print "np.sum(inner_HOG) / np.sum(outer_HOG):", np.sum(inner_HOG) / np.sum(outer_HOG)
		print "np.sum(border_HOG) / np.sum(outer_HOG):", np.sum(border_HOG) / np.sum(outer_HOG)
		if (np.sum(border_HOG) / np.sum(outer_HOG) > BORDER_HOG_FRACTION_THRESH):
			return False
		self.computeFeatureModel(inner_HOG, border_HOG)
		return True
	def computeFeature(self, img, useGaussianSmoothing = True):
		img_hsv = cv2.cvtColor(img.astype(np.float32), cv2.COLOR_BGR2HSV)
		# print "hue channel:", img_hsv[:,:,0]
		# print "saturation channel:", img_hsv[:,:,1]
		inner_patch_size = comparePatches.getGaussianScale(self.patch.size, self.GAUSSIAN_SCALE_FACTOR, -3)
		inner_patch = comparePatches.Patch(self.patch.x, self.patch.y, inner_patch_size)

		gaussian_window = comparePatches.gauss_kernels(self.patch.size, sigma = self.patch.size/4.0)
		inner_gaussian_window = gaussian_window[ \
		gaussian_window.shape[0]/2 - inner_patch.size/2: gaussian_window.shape[0]/2 + inner_patch.size/2 + 1 ,\
		gaussian_window.shape[1]/2 - inner_patch.size/2: gaussian_window.shape[1]/2 + inner_patch.size/2 + 1]

		assert gaussian_window.shape == (self.patch.size, self.patch.size), "outer gaussian_window size not correct"
		assert inner_gaussian_window.shape == (inner_patch.size, inner_patch.size), "inner gaussian_window size not correct"

		"""Still need to compute the overall Hue, Saturation, since sigma is different now 4.0 instead of 6.0"""
		if (self.patch.outer_hue_hist_scale_3_gaus_4 is None):
			self.patch.outer_hue_hist_scale_3_gaus_4 = self.computeHueHist(img_hsv, self.patch, gaussian_window)
		if (self.patch.outer_saturation_hist_scale_3_gaus_4 is None):
			self.patch.outer_saturation_hist_scale_3_gaus_4 = self.computeSaturationHist(img_hsv, self.patch, gaussian_window)
		if (self.patch.inner_hue_hist_scale_3_gaus_4 is None):
			self.patch.inner_hue_hist_scale_3_gaus_4 = self.computeHueHist(img_hsv, inner_patch, inner_gaussian_window)
		if (self.patch.inner_saturation_hist_scale_3_gaus_4 is None):
			self.patch.inner_saturation_hist_scale_3_gaus_4 = self.computeSaturationHist(img_hsv, inner_patch, inner_gaussian_window)

		outer_hist_hue = self.patch.outer_hue_hist_scale_3_gaus_4
		outer_hist_saturation = self.patch.outer_saturation_hist_scale_3_gaus_4

		inner_hist_hue = self.patch.inner_hue_hist_scale_3_gaus_4
		inner_hist_saturation = self.patch.inner_saturation_hist_scale_3_gaus_4

		border_hist_hue = outer_hist_hue - inner_hist_hue
		border_hist_saturation = outer_hist_saturation - inner_hist_saturation

		# model_constructor_inner_saturation = np.zeros(len(inner_hist_saturation))
		# model_constructor_inner_saturation[self.SATURATION_START_INDEX:self.SATURATION_END_INDEX] = \
		# inner_hist_saturation[self.SATURATION_START_INDEX:self.SATURATION_END_INDEX]
		# print "model_constructor_inner_saturation:\n", model_constructor_inner_saturation

		# model_constructor_inner_hue = np.zeros(len(inner_hist_hue))
		# model_constructor_inner_hue[self.HUE_START_INDEX:self.HUE_END_INDEX] = \
		# inner_hist_hue[self.HUE_START_INDEX:self.HUE_END_INDEX]
		# print model_constructor_hue
		# print "model_constructor_inner_hue:\n", model_constructor_inner_saturation

		if(np.sum(border_hist_hue[self.HUE_START_INDEX:self.HUE_END_INDEX]) == 0 or \
			np.sum(border_hist_saturation[self.SATURATION_START_INDEX:self.SATURATION_END_INDEX]) == 0):
			border_hist = np.zeros(len(range(self.HUE_START_INDEX,self.HUE_END_INDEX)) + \
				len(range(self.SATURATION_START_INDEX,self.SATURATION_END_INDEX)))
		else:
			border_hist = np.concatenate((border_hist_hue[self.HUE_START_INDEX:self.HUE_END_INDEX], \
				border_hist_saturation[self.SATURATION_START_INDEX:self.SATURATION_END_INDEX]), axis = 1)
		self.hist = np.concatenate((inner_hist_hue, inner_hist_saturation, border_hist), axis = 1)
		self.hist = normalize(self.hist, norm='l1')[0] # normalize the histogram using l1
 def computeFeature(self, img, max_response, useGaussianSmoothing=True):
     gx, gy = cornerResponse.sobelConvolutionOpencv(
         cv2.cvtColor(img, cv2.COLOR_BGR2GRAY).astype(np.uint8))
     Ixx = np.multiply(gx, gx)
     Ixy = np.multiply(gx, gy)
     Iyy = np.multiply(gy, gy)
     self.hist = np.zeros(1)
     self.hist[0] = cornerResponse.getOnePatchHarrisCornerResponse(Ixx, Ixy, Iyy, self.patch, \
      comparePatches.gauss_kernels(self.patch.size, sigma = self.patch.size/6.0))
     self.max_response = max_response
     print "computeFeature for FeatureCornerness done"
Пример #6
0
	def computeFeature(self, img, useGaussianSmoothing = True):
		img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY).astype(np.uint8)
		inner_patch_size = comparePatches.getGaussianScale(self.patch.size, self.GAUSSIAN_SCALE_FACTOR, -2)
		inner_patch = comparePatches.Patch(self.patch.x, self.patch.y, inner_patch_size)
		gaussian_window = comparePatches.gauss_kernels(self.patch.size, sigma = self.patch.size/4.0)
		inner_gaussian_window = gaussian_window[ gaussian_window.shape[0]/2 - inner_patch.size/2: gaussian_window.shape[0]/2 + inner_patch.size/2 + 1 ,\
		 gaussian_window.shape[1]/2 - inner_patch.size/2: gaussian_window.shape[1]/2 + inner_patch.size/2 + 1]
		assert gaussian_window.shape == (self.patch.size, self.patch.size), "outer gaussian_window size not correct"
		assert inner_gaussian_window.shape == (inner_patch.size, inner_patch.size), "inner gaussian_window size not correct"

		outer_hist = self.computeIntensityHist(img_gray, self.patch, gaussian_window)
		inner_hist = self.computeIntensityHist(img_gray, inner_patch, inner_gaussian_window)
		donut_hist = outer_hist - inner_hist
		"""changed to sum of inner_hist of the starting few bins = 1"""
		self.hist = np.concatenate((np.array([np.sum(inner_hist[0:3])]), inner_hist[3:], donut_hist[0:3]), axis = 1) # donut_hist should not contain any value from bin 0,1,2
		self.hist = normalize(self.hist, norm='l1')[0] # normalize the histogram using l1
	def getSubPatchAndSubPatchGaussianFromSubPatchIndex(self, sub_patch_index):
		newLen = (self.patch.size+1)/2
		if(newLen % 2 == 0):
			newSize = newLen -1
		else:
			newSize = newLen
		gaussian_window = comparePatches.gauss_kernels(self.patch.size, sigma = self.patch.size/6.0)
		# newSize is the size of the sub patch
		if(sub_patch_index == self.TOP_LEFT_INDEX):
			sub_gaussian_window = gaussian_window[0:newSize,0:newSize]
			sub_patch = comparePatches.Patch(self.patch.x - newLen/2, self.patch.y - newLen/2, newSize, initialize_features = False)
		elif(sub_patch_index == self.TOP_RIGHT_INDEX):
			sub_gaussian_window = gaussian_window[0:newSize, gaussian_window.shape[1] - newSize:gaussian_window.shape[1]]
			sub_patch = comparePatches.Patch(self.patch.x - newLen/2, self.patch.y + newLen/2, newSize, initialize_features = False)
		elif(sub_patch_index == self.BOTTOM_LEFT_INDEX):
			sub_gaussian_window = gaussian_window[gaussian_window.shape[0] - newSize:gaussian_window.shape[0], 0:newSize]
			sub_patch = comparePatches.Patch(self.patch.x + newLen/2, self.patch.y - newLen/2, newSize, initialize_features = False)
		else:
			sub_gaussian_window = gaussian_window[gaussian_window.shape[0] - newSize:gaussian_window.shape[0], gaussian_window.shape[1] - newSize: gaussian_window.shape[1]]
			sub_patch = comparePatches.Patch(self.patch.x + newLen/2, self.patch.y + newLen/2, newSize, initialize_features = False)

		return sub_patch, sub_gaussian_window, gaussian_window
    def fitParadigm(self, img):
        """
		For each of the 4 square sub patch:
		1. checks the hue, saturation hist, finds the mode color and see whether that color constitutes the majority of that sub patch
		2. checks the other 3 sub patches' hue, saturation hist, make sure that they do not have the found hue color of the SUBPATCH_OF_INTEREST_INDEX
		returns true or false
		"""
        self.HUEFRACTION = 0.7
        self.SATURATIONFRACTION_INVERSE = 0.1  # maximum noise in other hists
        self.SHRINK_HUE_BIN_FRACTION = 0.9
        self.HISTBINNUM = 16
        MINIMUM_VALUE_CHANNEL_BIN = 4
        MAX_FIRST_BIN_SATURATION_PERCENT = 0.5

        img_hsv = cv2.cvtColor(img.astype(np.float32), cv2.COLOR_BGR2HSV)
        gaussian_window = comparePatches.gauss_kernels(
            self.patch.size,
            sigma=self.patch.size / self.GAUSSIAN_WINDOW_LENGTH_SIGMA)

        sub_gaussian_windows = []
        sub_patches = []

        newLen = (self.patch.size + 1) / 2
        # newSize is the size of the sub patch
        if (newLen % 2 == 0):
            newSize = newLen - 1
        else:
            newSize = newLen
        """TOP_LEFT subpatch"""
        sub_gaussian_windows.append(gaussian_window[0:newSize, 0:newSize])
        sub_patches.append(
            comparePatches.Patch(self.patch.x - newLen / 2,
                                 self.patch.y - newLen / 2,
                                 newSize,
                                 initialize_features=False))
        """TOP_RIGHT subpatch"""
        sub_gaussian_windows.append(
            gaussian_window[0:newSize, gaussian_window.shape[1] -
                            newSize:gaussian_window.shape[1]])
        sub_patches.append(
            comparePatches.Patch(self.patch.x - newLen / 2,
                                 self.patch.y + newLen / 2,
                                 newSize,
                                 initialize_features=False))
        """BOTTOM_LEFT subpatch"""
        sub_gaussian_windows.append(
            gaussian_window[gaussian_window.shape[0] -
                            newSize:gaussian_window.shape[0], 0:newSize])
        sub_patches.append(
            comparePatches.Patch(self.patch.x + newLen / 2,
                                 self.patch.y - newLen / 2,
                                 newSize,
                                 initialize_features=False))
        """BOTTOM_RIGHT subpatch"""
        sub_gaussian_windows.append(
            gaussian_window[gaussian_window.shape[0] -
                            newSize:gaussian_window.shape[0],
                            gaussian_window.shape[1] -
                            newSize:gaussian_window.shape[1]])
        sub_patches.append(
            comparePatches.Patch(self.patch.x + newLen / 2,
                                 self.patch.y + newLen / 2,
                                 newSize,
                                 initialize_features=False))

        found_feature_patch_flag = False
        for i in range(self.TOP_LEFT_INDEX, self.BOTTOM_RIGHT_INDEX + 1):
            idx = i - 1  # true idx for the lists
            # print "checking subpatch index:", idx
            this_patch = sub_patches[idx]
            this_sub_gaussian_window = sub_gaussian_windows[idx]

            this_hue = self.computeHueHist(img_hsv, this_patch,
                                           this_sub_gaussian_window)
            this_saturation = self.computeSaturationHist(
                img_hsv, this_patch, this_sub_gaussian_window)

            this_hue_density = np.zeros(self.HISTBINNUM)
            for j in range(0, self.HISTBINNUM):
                this_hue_density[j] = this_hue[j] + this_hue[(
                    (j + 1) % self.HISTBINNUM)]
            max_hue_bin = np.argmax(this_hue_density)

            # print "np.sum(this_hue):", np.sum(this_hue)
            # print "max response:", this_hue_density[max_hue_bin]

            # plotStatistics.plotOneGivenHist("", "potential_target_hue", this_hue, save = False, show = True)
            # plotStatistics.plotOneGivenHist("", "potential_target_saturation", this_saturation, save = False, show = True)

            if (this_hue_density[max_hue_bin] >=
                    self.HUEFRACTION * np.sum(this_hue)):
                """shrink hue bin, assign HUE_START_INDEX, HUE_END_INDEX, note that these two indexes need to mod self.HISTBINNUM before use"""
                if (this_hue[max_hue_bin] / this_hue_density[max_hue_bin] >
                        self.SHRINK_HUE_BIN_FRACTION):
                    # max_hue_bin itself is prominent
                    self.HUE_START_INDEX = max_hue_bin
                    self.HUE_END_INDEX = max_hue_bin + 1
                elif (this_hue[((max_hue_bin + 1) % self.HISTBINNUM)] /
                      this_hue_density[max_hue_bin] >
                      self.SHRINK_HUE_BIN_FRACTION):
                    # max_hue_bin + 1 itself is prominent
                    self.HUE_START_INDEX = (max_hue_bin + 1)
                    self.HUE_END_INDEX = (max_hue_bin + 1 + 1)
                else:
                    # need two bins
                    self.HUE_START_INDEX = max_hue_bin
                    self.HUE_END_INDEX = (max_hue_bin + 1 + 1)
                """Acquire Saturation Bin"""
                target_hue_bins = []
                for j in range(self.HUE_START_INDEX, self.HUE_END_INDEX):
                    target_hue_bins.append(j % self.HISTBINNUM)


                value_for_target_hue_bins = self.findValueHistForTargetHueBin(\
                img_hsv, this_patch, this_sub_gaussian_window, target_hue_bins)

                saturation_for_target_hue_bins = self.findSaturationHistForTargetHueBin(\
                img_hsv, this_patch, this_sub_gaussian_window, target_hue_bins)
                """Value Channel of the interest sub patch must have minimum thresh"""
                if (np.argmax(value_for_target_hue_bins) > MINIMUM_VALUE_CHANNEL_BIN and \
                 saturation_for_target_hue_bins[0]/ np.sum(saturation_for_target_hue_bins) < MAX_FIRST_BIN_SATURATION_PERCENT):
                    """SATURATION_START_INDEX, SATURATION_END_INDEX does not need to be Mod before use"""
                    self.SATURATION_START_INDEX, self.SATURATION_END_INDEX, \
                    self.SATURATION_FILTER_START_INDEX, self.SATURATION_FILTER_END_INDEX = \
                    self.findSaturationRangeForTargetHueBin( \
                     img_hsv, this_patch, target_hue_bins, this_sub_gaussian_window)
                    """Check other three hists, should not contain targeted hue"""
                    target_saturation_bins = range(self.SATURATION_START_INDEX,
                                                   self.SATURATION_END_INDEX)
                    # filtered_other_hue have the same size of target_hue_bins, which only contain bins of interest
                    filtered_other_hue = np.zeros(len(target_hue_bins))
                    other_hue = np.zeros(self.HISTBINNUM)
                    for j in range(self.TOP_LEFT_INDEX,
                                   self.BOTTOM_RIGHT_INDEX + 1):
                        if (j != i):
                            one_other_hue = self.computeHueHist(
                                img_hsv, sub_patches[j - 1],
                                sub_gaussian_windows[j - 1])
                            other_hue = other_hue + one_other_hue

                            one_filtered_other_hue = self.targetHueFilteredBySaturation( \
                             img_hsv, sub_patches[j - 1], sub_gaussian_windows[j - 1], target_hue_bins, target_saturation_bins)
                            filtered_other_hue = filtered_other_hue + one_filtered_other_hue

                    # print "filtered_other_hue:", filtered_other_hue
                    # print "np.sum(filtered_other_hue):", np.sum(filtered_other_hue)
                    # print "np.sum(other_hue):", np.sum(other_hue)

                    # plotStatistics.plotOneGivenHist("", "filtered_other_hue", filtered_other_hue, save = False, show = True)
                    # plotStatistics.plotOneGivenHist("", "other_hue", other_hue, save = False, show = True)

                    if (np.sum(filtered_other_hue) / np.sum(other_hue) <=
                            self.SATURATIONFRACTION_INVERSE):
                        """Found feature patch, break and return True"""
                        found_feature_patch_flag = True
                        self.SUBPATCH_OF_INTEREST_INDEX = i
                        break

        if (found_feature_patch_flag):
            print "successfully constructed FeatureSubSquareParadigm, self.HUE_START_INDEX:", self.HUE_START_INDEX, \
            "self.HUE_END_INDEX:", self.HUE_END_INDEX, \
            "self.SATURATION_START_INDEX:", self.SATURATION_START_INDEX, \
            "self.SATURATION_END_INDEX:", self.SATURATION_END_INDEX, \
            "self.SATURATION_FILTER_START_INDEX:", self.SATURATION_FILTER_START_INDEX, \
            "self.SATURATION_FILTER_END_INDEX:", self.SATURATION_FILTER_END_INDEX, \
            "self.SUBPATCH_OF_INTEREST_INDEX:", self.SUBPATCH_OF_INTEREST_INDEX

            self.computeFeatureModel(this_hue, this_saturation)

        return found_feature_patch_flag
Пример #9
0
    def computeFeature(self, img, useGaussianSmoothing=True):
        img_hsv = cv2.cvtColor(img.astype(np.float32), cv2.COLOR_BGR2HSV)
        # print "hue channel:", img_hsv[:,:,0]
        # print "saturation channel:", img_hsv[:,:,1]
        """TODO: only construct inner_patch if one of the required hists is None"""
        inner_patch_size = comparePatches.getGaussianScale(
            self.patch.size, self.GAUSSIAN_SCALE_FACTOR, -self.GAUSSIAN_SCALE)
        inner_patch = comparePatches.Patch(self.patch.x,
                                           self.patch.y,
                                           inner_patch_size,
                                           initialize_features=False)

        gaussian_window = comparePatches.gauss_kernels(
            self.patch.size,
            sigma=self.patch.size / self.GAUSSIAN_WINDOW_LENGTH_SIGMA)
        inner_gaussian_window = gaussian_window[ \
        gaussian_window.shape[0]/2 - inner_patch.size/2: gaussian_window.shape[0]/2 + inner_patch.size/2 + 1 ,\
        gaussian_window.shape[1]/2 - inner_patch.size/2: gaussian_window.shape[1]/2 + inner_patch.size/2 + 1]

        assert gaussian_window.shape == (
            self.patch.size,
            self.patch.size), "outer gaussian_window size not correct"
        assert inner_gaussian_window.shape == (
            inner_patch.size,
            inner_patch.size), "inner gaussian_window size not correct"
        """Still need to compute the overall Hue, Saturation, since sigma is different now 4.0 instead of 6.0"""
        if (self.patch.outer_hs_2d_gaus_4 is None):
            self.patch.outer_hs_2d_gaus_4 = self.computeHS2DWithGaussianWindow(
                img_hsv, self.patch, gaussian_window)

        key = "{gaus}_{scale}".format(gaus=int(
            self.GAUSSIAN_WINDOW_LENGTH_SIGMA),
                                      scale=int(self.GAUSSIAN_SCALE))
        if (not key in self.patch.gaus_scale_to_inner_hs_2d_dict):
            self.patch.gaus_scale_to_inner_hs_2d_dict[key] = self.computeHS2DWithGaussianWindow(\
             img_hsv, inner_patch, inner_gaussian_window)

        inner_hist_hue = self.derive1DHueFrom2D(
            self.patch.gaus_scale_to_inner_hs_2d_dict[key])
        inner_hist_saturation = self.derive1DSaturationFrom2D(
            self.patch.gaus_scale_to_inner_hs_2d_dict[key])

        outer_hist_hue = self.derive1DHueFrom2D(self.patch.outer_hs_2d_gaus_4)
        outer_hist_saturation = self.derive1DSaturationFrom2D(
            self.patch.outer_hs_2d_gaus_4)

        border_hist_hue = outer_hist_hue - inner_hist_hue
        border_hist_saturation = outer_hist_saturation - inner_hist_saturation
        """compute inner_error_hist"""
        inner_hist_hue_targetted = np.array([inner_hist_hue[i % self.HISTBINNUM] \
         for i in range(self.HUE_START_INDEX, self.HUE_END_INDEX)])
        if(np.sum(inner_hist_hue_targetted) == 0 or \
         np.sum(inner_hist_saturation[self.SATURATION_START_INDEX:self.SATURATION_END_INDEX]) == 0):
            inner_error_hist = np.zeros(len(range(self.HUE_START_INDEX,self.HUE_END_INDEX)) + \
             len(range(self.SATURATION_START_INDEX,self.SATURATION_END_INDEX)))
        else:
            inner_error_hist = np.concatenate((inner_hist_hue_targetted, \
             inner_hist_saturation[self.SATURATION_START_INDEX:self.SATURATION_END_INDEX]), axis = 1)

        target_hue_bins = []
        for i in range(self.HUE_START_INDEX, self.HUE_END_INDEX):
            target_hue_bins.append(i % self.HISTBINNUM)
        target_saturation_bins = range(self.SATURATION_START_INDEX,
                                       self.SATURATION_END_INDEX)
        """
		filter the border hist hue using saturation range, this version using tight saturation filter range
		"""
        filtered_border_hist_hue = self.deriveHueHistFilterOffHueWithWrongSaturationFrom2D(\
         self.patch.outer_hs_2d_gaus_4 - self.patch.gaus_scale_to_inner_hs_2d_dict[key], \
         target_saturation_bins, target_hue_bins)
        """aggregate the target_hue_bins"""
        target_hue_sum = 0.0
        for i in range(self.HUE_START_INDEX, self.HUE_END_INDEX):
            target_hue_sum += filtered_border_hist_hue[i % self.HISTBINNUM]

        if (self.HUE_END_INDEX > self.HISTBINNUM):
            aggregated_filtered_border_hist_hue = np.concatenate((\
             filtered_border_hist_hue[self.HUE_END_INDEX % self.HISTBINNUM:self.HUE_START_INDEX], \
             np.array([target_hue_sum]),\
             filtered_border_hist_hue[self.HUE_END_INDEX:]), axis = 1)
        else:
            aggregated_filtered_border_hist_hue = np.concatenate((\
             filtered_border_hist_hue[:self.HUE_START_INDEX], \
             np.array([target_hue_sum]),\
             filtered_border_hist_hue[self.HUE_END_INDEX:]), axis = 1)
        """Hue range filtered border_hist_saturation"""
        hue_filtered_border_hist_saturation = self.deriveSaturationHistFilterOffSaturationWithWrongHueFrom2D(\
         self.patch.outer_hs_2d_gaus_4 - self.patch.gaus_scale_to_inner_hs_2d_dict[key], \
         target_saturation_bins, target_hue_bins)
        """bring up the hists to sum to be 1 (np.sum(outer_hist_hue/outer_hist_saturation)), ideal case, might not sum to 1 actually"""
        self.hist = np.concatenate((\
         aggregated_filtered_border_hist_hue * np.sum(outer_hist_hue)/ np.sum(border_hist_hue), \
         hue_filtered_border_hist_saturation * np.sum(outer_hist_saturation)/ np.sum(border_hist_saturation), \
         inner_error_hist * np.sum(outer_hist_saturation)/np.sum(inner_hist_saturation)), axis = 1)
Пример #10
0
    def fitParadigm(self, img):
        """
		1. checks the inner hue, saturation hist, finds the mode color and see whether that color constitutes the majority of the inner patch
		2. checks the border hue, saturation hist, make sure that the border does not have the found inner hue color
		3. check for different inner GAUSSIAN_SCALE, default is 3
		returns true or false
		"""
        self.HUEFRACTION = 0.55
        self.SATURATIONFRACTION_INVERSE = 0.15  # maximum border hist
        self.SHRINK_HUE_BIN_FRACTION = 0.99
        MINIMUM_VALUE_CHANNEL_BIN = 4
        MAX_FIRST_BIN_SATURATION_PERCENT = 0.5

        img_hsv = cv2.cvtColor(img.astype(np.float32), cv2.COLOR_BGR2HSV)
        gaussian_window = comparePatches.gauss_kernels(
            self.patch.size,
            sigma=self.patch.size / self.GAUSSIAN_WINDOW_LENGTH_SIGMA)
        success_constructed = False

        for scale in xrange(3, 0, -1):
            self.GAUSSIAN_SCALE = scale
            print "current gaussian scale in border_paradigm detection:", self.GAUSSIAN_SCALE
            inner_patch_size = comparePatches.getGaussianScale(
                self.patch.size, self.GAUSSIAN_SCALE_FACTOR,
                -self.GAUSSIAN_SCALE)
            inner_patch = comparePatches.Patch(self.patch.x, self.patch.y,
                                               inner_patch_size)
            inner_gaussian_window = gaussian_window[ \
            gaussian_window.shape[0]/2 - inner_patch.size/2: gaussian_window.shape[0]/2 + inner_patch.size/2 + 1 ,\
            gaussian_window.shape[1]/2 - inner_patch.size/2: gaussian_window.shape[1]/2 + inner_patch.size/2 + 1]

            outer_hue = self.computeHueHist(img_hsv, self.patch,
                                            gaussian_window)
            outer_saturation = self.computeSaturationHist(
                img_hsv, self.patch, gaussian_window)

            inner_hue = self.computeHueHist(img_hsv, inner_patch,
                                            inner_gaussian_window)
            inner_saturation = self.computeSaturationHist(
                img_hsv, inner_patch, inner_gaussian_window)

            border_hue = outer_hue - inner_hue
            border_saturation = outer_saturation - inner_saturation

            border_hue_density = np.zeros(self.HISTBINNUM)
            for i in range(0, self.HISTBINNUM):
                border_hue_density[i] = border_hue[i] + border_hue[(
                    (i + 1) % self.HISTBINNUM)]
            max_hue_bin = np.argmax(border_hue_density)

            # comparePatches.drawPatchesOnImg(np.copy(img),[self.patch, inner_patch], True)
            plotStatistics.plotOneGivenHist("",
                                            "border_saturation",
                                            border_saturation,
                                            save=False,
                                            show=True)
            plotStatistics.plotOneGivenHist("",
                                            "border_hue",
                                            border_hue,
                                            save=False,
                                            show=True)

            print border_hue_density[max_hue_bin] / np.sum(border_hue)

            if (border_hue_density[max_hue_bin] >=
                    self.HUEFRACTION * np.sum(border_hue)):
                """shrink hue bin, assign HUE_START_INDEX, HUE_END_INDEX, note that these two indexes need to mod self.HISTBINNUM before use"""
                if (border_hue[max_hue_bin] / border_hue_density[max_hue_bin] >
                        self.SHRINK_HUE_BIN_FRACTION):
                    # max_hue_bin itself is prominent
                    self.HUE_START_INDEX = max_hue_bin
                    self.HUE_END_INDEX = max_hue_bin + 1
                elif (border_hue[((max_hue_bin + 1) % self.HISTBINNUM)] /
                      border_hue_density[max_hue_bin] >
                      self.SHRINK_HUE_BIN_FRACTION):
                    # max_hue_bin + 1 itself is prominent
                    self.HUE_START_INDEX = (max_hue_bin + 1)
                    self.HUE_END_INDEX = (max_hue_bin + 1 + 1)
                else:
                    # need two bins
                    self.HUE_START_INDEX = max_hue_bin
                    self.HUE_END_INDEX = (max_hue_bin + 1 + 1)

                if (self.HUE_START_INDEX >= self.HISTBINNUM):
                    self.HUE_START_INDEX = self.HUE_START_INDEX % self.HISTBINNUM
                    self.HUE_END_INDEX = self.HUE_END_INDEX % self.HISTBINNUM

                target_hue_bins = []
                for i in range(self.HUE_START_INDEX, self.HUE_END_INDEX):
                    target_hue_bins.append(i % self.HISTBINNUM)


                value_for_target_hue_bins = self.findBorderValueHistForTargetHueBin(\
                 img_hsv, self.patch, inner_patch, gaussian_window, target_hue_bins)

                saturation_for_target_hue_bins = self.findBorderSaturationHistForTargetHueBin(\
                 img_hsv, self.patch, inner_patch, gaussian_window, target_hue_bins)
                """
				Value Channel of the border must have minimum thresh and should not be all white (saturation bin 0)
				TODO: see if the features constructed without this constraint works or not
				"""
                if (np.argmax(value_for_target_hue_bins) > MINIMUM_VALUE_CHANNEL_BIN and \
                 saturation_for_target_hue_bins[0]/ np.sum(saturation_for_target_hue_bins) < MAX_FIRST_BIN_SATURATION_PERCENT):
                    """Acquire Saturation Bin"""
                    """
					SATURATION_START_INDEX, SATURATION_END_INDEX does not need to be Mod before use
					"""
                    self.SATURATION_START_INDEX, self.SATURATION_END_INDEX, self.SATURATION_FILTER_START_INDEX, self.SATURATION_FILTER_END_INDEX = \
                    self.findBorderSaturationRangeForTargetHueBin(img_hsv, self.patch, inner_patch, gaussian_window, target_hue_bins)

                    plotStatistics.plotOneGivenHist("",
                                                    "inner_saturation",
                                                    inner_saturation,
                                                    save=False,
                                                    show=True)
                    plotStatistics.plotOneGivenHist("",
                                                    "inner_hue",
                                                    inner_hue,
                                                    save=False,
                                                    show=True)
                    """Check inner hist, should not contain targeted hue"""
                    target_saturation_bins = range(self.SATURATION_START_INDEX,
                                                   self.SATURATION_END_INDEX)
                    filtered_inner_hue = \
                    self.targetHueFilteredBySaturation(img_hsv, inner_patch, inner_gaussian_window, target_hue_bins, target_saturation_bins)

                    plotStatistics.plotOneGivenHist("",
                                                    "filtered_inner_hue",
                                                    filtered_inner_hue,
                                                    save=False,
                                                    show=True)
                    plotStatistics.plotOneGivenHist("",
                                                    "inner_hue",
                                                    inner_hue,
                                                    save=False,
                                                    show=True)

                    print "inner error fraction:", np.sum(
                        filtered_inner_hue) / np.sum(inner_hue)

                    if (np.sum(filtered_inner_hue) / np.sum(inner_hue) <=
                            self.SATURATIONFRACTION_INVERSE):

                        print "successfully constructed border_paradigm, self.HUE_START_INDEX:", self.HUE_START_INDEX, \
                        "self.HUE_END_INDEX:", self.HUE_END_INDEX, \
                        "self.SATURATION_START_INDEX:", self.SATURATION_START_INDEX, \
                        "self.SATURATION_END_INDEX:", self.SATURATION_END_INDEX, \
                        "self.SATURATION_FILTER_START_INDEX:", self.SATURATION_FILTER_START_INDEX, \
                        "self.SATURATION_FILTER_END_INDEX:", self.SATURATION_FILTER_END_INDEX, \
                        "at scale:", self.GAUSSIAN_SCALE

                        self.computeFeatureModel(border_hue, border_saturation)
                        success_constructed = True
                        break

        return success_constructed
Пример #11
0
    def computeFeature(self, img, useGaussianSmoothing=True):
        img_hsv = cv2.cvtColor(img.astype(np.float32), cv2.COLOR_BGR2HSV)
        # print "hue channel:", img_hsv[:,:,0]
        # print "saturation channel:", img_hsv[:,:,1]
        """TODO: only construct inner_patch if one of the required hists is None"""
        inner_patch_size = comparePatches.getGaussianScale(
            self.patch.size, self.GAUSSIAN_SCALE_FACTOR, -self.GAUSSIAN_SCALE)
        inner_patch = comparePatches.Patch(self.patch.x,
                                           self.patch.y,
                                           inner_patch_size,
                                           initialize_features=False)

        gaussian_window = comparePatches.gauss_kernels(
            self.patch.size,
            sigma=self.patch.size / self.GAUSSIAN_WINDOW_LENGTH_SIGMA)
        inner_gaussian_window = gaussian_window[ \
        gaussian_window.shape[0]/2 - inner_patch.size/2: gaussian_window.shape[0]/2 + inner_patch.size/2 + 1 ,\
        gaussian_window.shape[1]/2 - inner_patch.size/2: gaussian_window.shape[1]/2 + inner_patch.size/2 + 1]

        assert gaussian_window.shape == (
            self.patch.size,
            self.patch.size), "outer gaussian_window size not correct"
        assert inner_gaussian_window.shape == (
            inner_patch.size,
            inner_patch.size), "inner gaussian_window size not correct"
        """Still need to compute the overall Hue, Saturation, since sigma is different now 4.0 instead of 6.0"""
        if (self.patch.inner_hue_hist_scale_3_gaus_4_centre_paradigm is None):
            # self.patch.inner_hue_hist_scale_3_gaus_4_centre_paradigm = self.computeHueHist(img_hsv, inner_patch, inner_gaussian_window)
            self.patch.inner_hue_hist_scale_3_gaus_4_centre_paradigm = self.computeHueHistSaturationWeighted(
                img_hsv, inner_patch, inner_gaussian_window)

        if (self.patch.outer_hue_hist_scale_3_gaus_4_centre_paradigm is None):
            # self.patch.outer_hue_hist_scale_3_gaus_4_centre_paradigm = self.computeHueHist(img_hsv, self.patch, gaussian_window)
            self.patch.outer_hue_hist_scale_3_gaus_4_centre_paradigm = self.computeHueHistSaturationWeighted(
                img_hsv, self.patch, gaussian_window)

        if (self.patch.outer_hs_2d_gaus_4 is None):
            self.patch.outer_hs_2d_gaus_4 = self.computeHS2DWithGaussianWindow(
                img_hsv, self.patch, gaussian_window)

        key = "{gaus}_{scale}".format(gaus=int(
            self.GAUSSIAN_WINDOW_LENGTH_SIGMA),
                                      scale=int(self.GAUSSIAN_SCALE))
        if (not key in self.patch.gaus_scale_to_inner_hs_2d_dict):
            self.patch.gaus_scale_to_inner_hs_2d_dict[key] = self.computeHS2DWithGaussianWindow(\
             img_hsv, inner_patch, inner_gaussian_window)

        inner_hist_hue = self.patch.inner_hue_hist_scale_3_gaus_4_centre_paradigm
        inner_hist_saturation = self.derive1DSaturationFrom2D(
            self.patch.gaus_scale_to_inner_hs_2d_dict[key])

        outer_hist_hue = self.patch.outer_hue_hist_scale_3_gaus_4_centre_paradigm
        outer_hist_saturation = self.derive1DSaturationFrom2D(
            self.patch.outer_hs_2d_gaus_4)

        border_hist_hue = outer_hist_hue - inner_hist_hue
        border_hist_saturation = outer_hist_saturation - inner_hist_saturation
        """compute border_hist"""
        border_hist_hue_targetted = np.array([border_hist_hue[i % self.HISTBINNUM] \
         for i in range(self.HUE_START_INDEX, self.HUE_END_INDEX)])
        border_hist = border_hist_hue_targetted
        # if(np.sum(border_hist_hue_targetted) == 0 or \
        # 	np.sum(border_hist_saturation[self.SATURATION_FILTER_START_INDEX:self.SATURATION_FILTER_END_INDEX]) == 0):
        # 	border_hist = np.zeros(len(range(self.HUE_START_INDEX,self.HUE_END_INDEX)) + \
        # 		len(range(self.SATURATION_FILTER_START_INDEX,self.SATURATION_FILTER_END_INDEX)))
        # else:
        # 	border_hist = np.concatenate((border_hist_hue_targetted, \
        # 		border_hist_saturation[self.SATURATION_FILTER_START_INDEX:self.SATURATION_FILTER_END_INDEX]), axis = 1)

        target_hue_bins = []
        for i in range(self.HUE_START_INDEX, self.HUE_END_INDEX):
            target_hue_bins.append(i % self.HISTBINNUM)
        target_saturation_bins = []
        for i in range(self.SATURATION_FILTER_START_INDEX,
                       self.SATURATION_FILTER_END_INDEX):
            target_saturation_bins.append(i)
        """compute border_hist alternative: make border hist to be target border_hue with target saturation filtered"""
        # border_hist_full = self.borderTargetHueFilteredBySaturation(img_hsv, self.patch, inner_patch, \
        # 	gaussian_window, target_hue_bins, target_saturation_bins)

        # border_hist = np.array([border_hist_full[hue_bin] for hue_bin in target_hue_bins])
        # if(np.sum(border_hist) == 0):
        # 	border_hist = np.concatenate((border_hist, \
        # 		np.zeros(len(range(self.SATURATION_FILTER_START_INDEX, self.SATURATION_FILTER_END_INDEX)))), axis = 1)
        # else:
        # 	border_hist = np.concatenate((border_hist, \
        # 		border_hist_saturation[self.SATURATION_FILTER_START_INDEX:self.SATURATION_FILTER_END_INDEX]), axis = 1)
        """aggregate the target_hue_bins"""
        target_hue_sum = 0.0
        for i in range(self.HUE_START_INDEX, self.HUE_END_INDEX):
            target_hue_sum += inner_hist_hue[i % self.HISTBINNUM]

        if (self.HUE_END_INDEX > self.HISTBINNUM):
            aggregated_inner_hist_hue = np.concatenate((\
             inner_hist_hue[self.HUE_END_INDEX % self.HISTBINNUM:self.HUE_START_INDEX], \
             np.array([target_hue_sum]),\
             inner_hist_hue[self.HUE_END_INDEX:]), axis = 1)
        else:
            aggregated_inner_hist_hue = np.concatenate((\
             inner_hist_hue[:self.HUE_START_INDEX], \
             np.array([target_hue_sum]),\
             inner_hist_hue[self.HUE_END_INDEX:]), axis = 1)
        """Hue filtered inner_hist_saturation"""
        hue_filtered_inner_hist_saturation = self.deriveSaturationHistFilterOffSaturationWithWrongHueFrom2D(\
         self.patch.gaus_scale_to_inner_hs_2d_dict[key], target_saturation_bins, target_hue_bins)
        """
		Try: normalizing border hist so that the weightage of border effect is comparable to that of the inner patch
		Do not normalize aggregated_inner_hist_hue as it is saturation weighted now
		"""
        # self.hist = np.concatenate((inner_hist_hue, inner_hist_saturation, normalize(border_hist, norm = "l1")[0]), axis = 1)
        # self.hist = np.concatenate((inner_hist_hue, inner_hist_saturation, border_hist), axis = 1)
        self.hist = np.concatenate((\
         aggregated_inner_hist_hue, \
         hue_filtered_inner_hist_saturation * np.sum(outer_hist_saturation)/ np.sum(inner_hist_saturation), \
         border_hist * np.sum(outer_hist_saturation)/np.sum(border_hist_saturation)), axis = 1)
        # self.hist = np.concatenate((aggregated_inner_hist_hue, normalize(border_hist, norm = "l1")[0] * \
        # 	np.sum(border_hist_hue)), axis = 1)

        self.inner_hist_hue = normalize(inner_hist_hue, norm='l1')[0]
        self.inner_hist_saturation = normalize(inner_hist_saturation,
                                               norm='l1')[0]
        self.border_hist_hue = normalize(border_hist_hue, norm='l1')[0]
        self.border_hist_saturation = normalize(border_hist_saturation,
                                                norm='l1')[0]
        self.border_hist = border_hist
Пример #12
0
    def fitParadigm(self, img):
        """
		1. checks the inner hue, saturation hist, finds the mode color and see whether that color constitutes the majority of the inner patch
		2. checks the border hue, saturation hist, make sure that the border does not have the found inner hue color
		3. check for different inner GAUSSIAN_SCALE, default is 3
		returns true or false
		"""
        self.HUEFRACTION = 0.7
        self.SATURATIONFRACTION_INVERSE = 0.1  # maximum border hist
        self.SHRINK_HUE_BIN_FRACTION = 0.99

        img_hsv = cv2.cvtColor(img.astype(np.float32), cv2.COLOR_BGR2HSV)
        gaussian_window = comparePatches.gauss_kernels(
            self.patch.size,
            sigma=self.patch.size / self.GAUSSIAN_WINDOW_LENGTH_SIGMA)

        success_flag = False

        for scale in xrange(3, 0, -1):
            self.GAUSSIAN_SCALE = scale
            print "current gaussian scale in centre_paradigm detection:", self.GAUSSIAN_SCALE
            inner_patch_size = comparePatches.getGaussianScale(
                self.patch.size, self.GAUSSIAN_SCALE_FACTOR,
                -self.GAUSSIAN_SCALE)
            inner_patch = comparePatches.Patch(self.patch.x, self.patch.y,
                                               inner_patch_size)
            inner_gaussian_window = gaussian_window[ \
            gaussian_window.shape[0]/2 - inner_patch.size/2: gaussian_window.shape[0]/2 + inner_patch.size/2 + 1 ,\
            gaussian_window.shape[1]/2 - inner_patch.size/2: gaussian_window.shape[1]/2 + inner_patch.size/2 + 1]

            outer_hue = self.computeHueHistSaturationWeighted(
                img_hsv, self.patch, gaussian_window)
            outer_saturation = self.computeSaturationHist(
                img_hsv, self.patch, gaussian_window)

            inner_hue = self.computeHueHistSaturationWeighted(
                img_hsv, inner_patch, inner_gaussian_window)
            inner_saturation = self.computeSaturationHist(
                img_hsv, inner_patch, inner_gaussian_window)

            inner_hue_density = np.zeros(self.HISTBINNUM)
            for i in range(0, self.HISTBINNUM):
                inner_hue_density[i] = inner_hue[i] + inner_hue[(
                    (i + 1) % self.HISTBINNUM)]
            max_hue_bin = np.argmax(inner_hue_density)
            if (inner_hue_density[max_hue_bin] <
                    self.HUEFRACTION * np.sum(inner_hue)):
                continue
            """shrink hue bin, assign HUE_START_INDEX, HUE_END_INDEX, note that these two indexes need to mod self.HISTBINNUM before use"""
            if (inner_hue[max_hue_bin] / inner_hue_density[max_hue_bin] >
                    self.SHRINK_HUE_BIN_FRACTION):
                # max_hue_bin itself is prominent
                self.HUE_START_INDEX = max_hue_bin
                self.HUE_END_INDEX = max_hue_bin + 1
            elif (inner_hue[((max_hue_bin + 1) % self.HISTBINNUM)] /
                  inner_hue_density[max_hue_bin] >
                  self.SHRINK_HUE_BIN_FRACTION):
                # max_hue_bin + 1 itself is prominent
                self.HUE_START_INDEX = (max_hue_bin + 1)
                self.HUE_END_INDEX = (max_hue_bin + 1 + 1)
            else:
                # need two bins
                self.HUE_START_INDEX = max_hue_bin
                self.HUE_END_INDEX = (max_hue_bin + 1 + 1)
            if (self.HUE_START_INDEX >= self.HISTBINNUM):
                self.HUE_START_INDEX = self.HUE_START_INDEX % self.HISTBINNUM
                self.HUE_END_INDEX = self.HUE_END_INDEX % self.HISTBINNUM
            """Acquire Saturation Bin"""
            target_hue_bins = []
            for i in range(self.HUE_START_INDEX, self.HUE_END_INDEX):
                target_hue_bins.append(i % self.HISTBINNUM)
            """
			SATURATION_START_INDEX, SATURATION_END_INDEX does not need to be Mod before use
			"""
            self.SATURATION_START_INDEX, self.SATURATION_END_INDEX, self.SATURATION_FILTER_START_INDEX, self.SATURATION_FILTER_END_INDEX = \
            self.findSaturationRangeForTargetHueBin(img_hsv, inner_patch, target_hue_bins, inner_gaussian_window)
            plotStatistics.plotOneGivenHist("",
                                            "inner_saturation",
                                            inner_saturation,
                                            save=False,
                                            show=True)
            plotStatistics.plotOneGivenHist("",
                                            "inner_hue",
                                            inner_hue,
                                            save=False,
                                            show=True)
            """Check border hist, should not contain targeted hue"""
            target_saturation_bins = range(self.SATURATION_START_INDEX,
                                           self.SATURATION_END_INDEX)
            filtered_border_hue = self.borderTargetHueFilteredBySaturation(
                img_hsv, self.patch, inner_patch, gaussian_window,
                target_hue_bins, target_saturation_bins)
            border_hue = outer_hue - inner_hue

            plotStatistics.plotOneGivenHist("",
                                            "filtered_border_hue",
                                            filtered_border_hue,
                                            save=False,
                                            show=True)
            plotStatistics.plotOneGivenHist("",
                                            "border_hue",
                                            border_hue,
                                            save=False,
                                            show=True)

            if (np.sum(filtered_border_hue) / np.sum(border_hue) >
                    self.SATURATIONFRACTION_INVERSE):
                continue

            print "successfully constructed feature centre_paradigm, self.HUE_START_INDEX:", self.HUE_START_INDEX, \
            "self.HUE_END_INDEX:", self.HUE_END_INDEX, \
            "self.SATURATION_START_INDEX:", self.SATURATION_START_INDEX, \
            "self.SATURATION_END_INDEX:", self.SATURATION_END_INDEX, \
            "self.SATURATION_FILTER_START_INDEX:", self.SATURATION_FILTER_START_INDEX, \
            "self.SATURATION_FILTER_END_INDEX:", self.SATURATION_FILTER_END_INDEX

            self.computeFeatureModel(inner_hue, inner_saturation)
            success_flag = True
            break

        return success_flag