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"
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
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)
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
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
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