def calc_threshold(hist, min_value, max_value): max_variance = 0 N = 0.0 for hist_bin in range(min_value, max_value + 1): # Calculate N N += cv.QueryHistValue_1D(hist, hist_bin) ipi = [] for hist_bin in range(min_value, max_value + 1): # Calculate i*pi values ipi.append(hist_bin * cv.QueryHistValue_1D(hist, hist_bin) / N) mean_t = sum(ipi) # Calculate total mean w0 = 0 sum_ipi = 0 for hist_bin in range(min_value, max_value + 1): # For all possible thresholds w0 = w0 + cv.QueryHistValue_1D(hist, hist_bin) / N # Find w0 w1 = 1 - w0 # Find w1 sum_ipi = sum_ipi + (hist_bin * cv.QueryHistValue_1D(hist, hist_bin) / N) # Find sum of i*pi try: mean0 = sum_ipi / w0 # Find mean of class 1 except ZeroDivisionError: mean0 = 0 # Except when w0=0, then mean will be 0 try: mean1 = (mean_t - sum_ipi) / w1 # Find mean of class 0 except ZeroDivisionError: mean1 = 0 # Except when w1=0, then mean will be 0 var_b = w0 * w1 * pow( (mean0 - mean1), 2) # Find between class variance if var_b > max_variance: # Check if this is maximum variance so far max_variance = var_b # If yes, save it best_threshold = hist_bin # and remember the threshold return best_threshold, max_variance # Return the best threshold and corresponding variance
def normalize_plane(plane, aggressive=0): if aggressive: # smooth = image_empty_clone(plane) # cv.Smooth(plane, smooth, cv.CV_GAUSSIAN, 13, 13) hist = get_gray_histogram(plane, bins=255) _, max_value, _, max_color = cv.GetMinMaxHistValue(hist) thr_value = max_value * aggressive down_threshold, up_threshold = None, None for k in range(256): down_val = cv.QueryHistValue_1D(hist, k) up_val = cv.QueryHistValue_1D(hist, 254 - k) if down_threshold is None and down_val >= thr_value: down_threshold = k if up_threshold is None and up_val >= thr_value: up_threshold = k if down_threshold is not None and up_threshold is not None: break sub_plane = None if down_threshold > 0: sub_plane = image_empty_clone(plane) cv.SubS(plane, down_threshold, sub_plane) add_plane = None if down_threshold + up_threshold > 0: add_plane = image_empty_clone(plane) cv.AddS(sub_plane or plane, down_threshold + up_threshold, add_plane) plane = add_plane or plane norm_plane = image_empty_clone(plane) cv.Normalize(plane, norm_plane, 0, 255, cv.CV_MINMAX) return norm_plane
def otsu_get_threshold(src): ''' Find the optimal threshold value for a grey level image using Otsu's method. This is baised on Otsu's original paper published in IEEE Xplore: "A Threshold Selection Method from Gray-Level Histograms" ''' if src.nChannels != 1: raise ValueError("Image must have one channel.") # Compute Histogram hist = cv.CreateHist([256], cv.CV_HIST_ARRAY, [[0, 255]], 1) cv.CalcHist([src], hist) # Convert to Probability Histogram cv.NormalizeHist(hist, 1) overall_moment = 0 for t in xrange(256): overall_moment += t * cv.QueryHistValue_1D(hist, t) # Find the threshold t that gives the highest variance # Suffixes _b and _f mean background and foreground num_pixels = src.width * src.height weight_b = 0 moment_b = 0 highest_variance = 0 best_threshold = 0 for t in xrange(256): hist_value = cv.QueryHistValue_1D(hist, t) weight_b += hist_value weight_f = 1 - weight_b if weight_b == 0: continue if weight_f == 0: break moment_b += t * hist_value moment_f = overall_moment - moment_b mean_b = moment_b / weight_b mean_f = moment_f / weight_f variance_between = weight_b * weight_f * \ (mean_b - mean_f) ** 2 if variance_between >= highest_variance: highest_variance = variance_between best_threshold = t return best_threshold
def calc_expected_value(hist, num_bins=256): sum = 0 num_datapoints = 0 for i in xrange(num_bins): value = cv.QueryHistValue_1D(hist, i) num_datapoints += value sum += value * i return sum / num_datapoints
def channel_to_image(self, chan, scale_x=3, scale_y=3, y_range=64): """ Creates an iplimage displaying histogram results after its computation """ if ((type(chan) != int) or (chan <= 0)): raise TypeError("(%s) Positive integer expected!" % (sys._getframe().f_code.co_name)) elif chan > self.channels: raise ValueError("(%s) Incoherent channel selected!" % (sys._getframe().f_code.co_name)) if ((type(scale_x) != int) or (scale_x <= 0)): raise TypeError("(%s) Positive integer expected!" % (sys._getframe().f_code.co_name)) if ((type(scale_y) != int) or (scale_y <= 0)): raise TypeError("(%s) Positive integer expected!" % (sys._getframe().f_code.co_name)) if ((type(y_range) != int) or (y_range <= 0)): raise TypeError("(%s) Positive integer expected!" % (sys._getframe().f_code.co_name)) max_range = self.ranges[1] - 1 (_, hist_max, _, _) = cv.GetMinMaxHistValue(self.cvhist[chan - 1]) hist_img = cv.CreateImage((max_range * scale_x, y_range * scale_y), self.depth, 1) cv.Zero(hist_img) # resets image values for i in range(max_range): # 0 to max_range hist_value = cv.QueryHistValue_1D(self.cvhist[chan - 1], i) next_value = cv.QueryHistValue_1D(self.cvhist[chan - 1], i + 1) pt1 = (int(i * scale_x), int(y_range * scale_y)) pt2 = (int(i * scale_x + scale_x), int(y_range * scale_y)) pt3 = (int(i * scale_x + scale_x), int((y_range - (next_value * y_range / hist_max)) * scale_y)) pt4 = (int(i * scale_x), int((y_range - (hist_value * y_range / hist_max)) * scale_y)) pts = (pt1, pt2, pt3, pt4) cv.FillConvexPoly(hist_img, pts, 255, lineType=8, shift=0) return hist_img
def calcularHistograma(self): cv.CalcArrHist([self.imagem_destino], self.histograma) valorMaximoMinimo = cv.GetMinMaxHistValue(self.histograma) cv.Rectangle(self.imagemHistograma, (0, 0), (512, 100), cv.CV_RGB(0, 0, 0), -1) for i in range(512): valor = cv.QueryHistValue_1D(self.histograma, i) normalizado = cv.Round(valor * 100 / valorMaximoMinimo[1]) cv.Line(self.imagemHistograma, (i, 100), (i, 100 - normalizado), cv.CV_RGB(255, 255, 255))
def calc_variance(hist, expected_value=None, num_bins=256): if expected_value is None: expected_value = calc_expected_value(hist, num_bins) variance = 0 sum = 0 for i in xrange(num_bins): value = cv.QueryHistValue_1D(hist, i) variance += value * (i - expected_value) ** 2 sum += value return variance / sum
def cdf(channel): # -- find cum dist func for individual channel # -- find cumulative histogram and calculate hist to find # which bin (between 0,255) corresponds to what value # and store in refHist hist = cv.CreateHist([256], cv.CV_HIST_ARRAY, [[0, 256]], 1) cv.CalcHist([cv.GetImage(channel)], hist) refHist = [cv.QueryHistValue_1D(hist, x) for x in range(0, 256)] # -- calculate cdf cdf = [v / np.sum(refHist[:]) for v in refHist[:]] for x in range(1, 256): cdf[x] += cdf[x - 1] return cdf
def histogram_image(hist, color=(255, 255, 255), background_color=(0, 0, 0), num_bins=256): '''Returns an image displaying the the given histogram.''' max_value = int(cv.GetMinMaxHistValue(hist)[1]) img = cv.CreateImage((num_bins, num_bins), 8, 3) cv.Set(img, background_color) for i in xrange(num_bins): height = int(cv.QueryHistValue_1D(hist, i) / max_value * num_bins) cv.Line(img, (i, num_bins), (i, num_bins - height), color) return img
def mapper(key, value): # Read in the data and decode... imgbytes = np.fromstring(value,dtype='uint8') imarr = cv2.imdecode(imgbytes,cv2.CV_LOAD_IMAGE_COLOR) im = cv.fromarray(imarr) # Convert and split data to get hue... hsv = cv.CreateImage(cv.GetSize(im),8,3) hue = cv.CreateImage(cv.GetSize(im),8,1) cv.CvtColor(im,hsv,cv.CV_BGR2HSV) cv.Split(hsv, hue, None, None, None) # Calculate colour (hue) histogram... hue_bins = 180 hue_range = [0,180] # n.b. opencv hue range hist = cv.CreateHist([hue_bins], cv.CV_HIST_ARRAY, [hue_range], 1) cv.CalcHist([hue],hist,0,None) # Yield count of colour... for h in range(hue_bins): yield int(h),cv.QueryHistValue_1D(hist,h)
def asMatrix(self): if self.nbins2 == None: result = np.zeros([self.nbins1]) for i in range(self.nbins1): result[i] = cv.QueryHistValue_1D(self.hist,i) return result elif self.nbins3 == None: result = np.zeros([self.nbins1,self.nbins2]) for i in range(self.nbins1): for j in range(self.nbins2): result[i,j] = cv.QueryHistValue_2D(self.hist,i,j) return result else: result = np.zeros([self.nbins1,self.nbins2,self.nbins3]) for i in range(self.nbins1): for j in range(self.nbins2): for k in range(self.nbins3): result[i,j,k] = cv.QueryHistValue_3D(self.hist,i,j,k) return result
def get_hist_image(hist, bins, width=500): height = 255 white = cv.RGB(255, 255, 255) black = cv.RGB(0, 0, 0) img_size = (width, height) hist_img = cv.CreateImage(img_size, 8, 1) cv.Rectangle(hist_img, (0, 0), img_size, white, cv.CV_FILLED) (_, max_value, _, _) = cv.GetMinMaxHistValue(hist) scale = width / float(bins) x = 0 for s in range(bins): bin_val = cv.QueryHistValue_1D(hist, s) y = cv.Round(bin_val * height / max_value) cv.Rectangle(hist_img, (x, height - y), (x + scale, height), black, cv.CV_FILLED) x += scale return hist_img
def classify(basedir, category_names): all_images = get_images(basedir) all_classified_images = [] classified = {} for c in category_names: pimg = get_png_images(basedir + '/' + c) classified[c] = pimg for im in pimg: all_classified_images.append(im) # now need to find the images which are not classified yet unclassified = [] for i in all_images: if i not in all_classified_images: unclassified.append(i) # make histograms of all images hmap = make_histograms(basedir, all_images) clf = learn(classified, hmap) usamples = [] for u in unclassified: hist = hmap[u] row = [] for j in range(NUM_BINS): row.append(cv.QueryHistValue_1D(hist, j)) usamples.append(row) data = VectorDataSet(usamples, patternID=unclassified) results = clf.test(data) patterns = results.getPatternID() labels = results.getPredictedLabels() # make map of image name to predicted label lmap = {} for i in range(len(patterns)): lmap[patterns[i]] = labels[i] return lmap
def learn(classified, histograms): clf = SVM() total_samples = 0 for c in classified.keys(): cim = classified[c] total_samples = total_samples + len(cim) samples = [] labels = [] for c in classified.keys(): cim = classified[c] for im in cim: hist = histograms[im] row = [] for j in range(NUM_BINS): row.append(cv.QueryHistValue_1D(hist, j)) samples.append(row) labels.append(c) data = VectorDataSet(samples, L=labels) print str(data) clf.train(data) return clf
max_value) # Find best threshold using otsu # Run multiple times if required if texture_method != 1: if loopVar1 != 0: channels[loopVar1], th, hist = otsu(channels[loopVar1], 0, th) channels[loopVar1], th, hist = otsu(channels[loopVar1], 0, th) pass else: channels[loopVar1], th, hist = otsu(channels[loopVar1], 0, th) #channels[loopVar1],th,hist=otsu(channels[loopVar1], 0, th) pass # Plot the histogram for analysis hist_data = [] for hist_bin in range(min_value, max_value + 1): hist_data.append(cv.QueryHistValue_1D(hist, hist_bin)) plt.plot(hist_data) plt.ylabel('frequencies') plt.show() # Convert them to binary images using the obtained threshold bin_img = cv.CreateMat(channels[loopVar1].height, channels[loopVar1].width, cv.CV_8UC1) cv.Convert(channels[loopVar1], bin_img) binary_imgs.append(conv_to_binary(bin_img, th)) cv.ShowImage( 'Blue_segmented', binary_imgs[0] ) # Show the segmented image for blue channel or 3x3 variance channel cv.ShowImage( 'Green_segmented', binary_imgs[1]
def __calculate_histogram(self, src): hist = cv.CreateHist([self.n_bins], cv.CV_HIST_ARRAY, [self.hist_range], 1) cv.CalcHist([src], hist) return [cv.QueryHistValue_1D(hist, n) for n in range(self.n_bins)]
def calc_1dhisto(inframe, nbin=256, scale=2, histh=200, hist=None, histimg=None): """ Calculate 1D intensity histogram of a iplimage, and return the histogram (as cv2.cv.cvhistogram) and an image representing this histogram (as 8bit unsigned iplimage) Use **hist** and **histimg** if they are provided, otherwise create them from scratch. To re-use the allocated memory, simply pass the output as input for input **hist** and **histimg**. Histogram bar height is calculated as follows: bin_height = int( bin_count*1.0 / (npix/nbin) * 0.2 * histh ) where bin_height is in pixels, bin_count is the number of pixels in this bin, npix the total number of pixels in the image, nbin the total bins, such that (npix/nbin) is the average bin count. 0.2 is a factor that sets the average bin height to 20% and histh scales the bin normalized bin height to pixels. @param [in] inframe Input frame, as iplimage @param [in] nbin Number of intensity bins @param [in] scale Histogram image bar width in pixels @param [in] histh Histogram image height in pixels @param [in] hist Previously allocated cv2.cv.cvhistogram to use @param [in] histimg Previously allocated iplimage to use @return Tuple of (histogram, histogram image) """ if (inframe.depth == cv.IPL_DEPTH_32F): hranges = [[0, 1]] elif (inframe.depth in [ cv.IPL_DEPTH_8U, cv.IPL_DEPTH_8S, cv.IPL_DEPTH_16U, cv.IPL_DEPTH_16S, cv.IPL_DEPTH_32S ]): hranges = None else: raise ValueError("Unsupported datatype for histogram ('%s')" % (str(inframe.depth))) if (not hist): hist = cv.CreateHist([nbin], cv.CV_HIST_ARRAY, ranges=[[0, 1]], uniform=1) if (not histimg): histimg = cv.CreateImage((nbin * scale, histh), cv.IPL_DEPTH_8U, 1) cv.CalcHist([cv.GetImage(inframe)], hist) #hmin, hmax, __, __ = cv.GetMinMaxHistValue(hist) # White noise histogram height should be be 0.2 npix = np.product(cv.GetDims(inframe)) histogram = [ cv.QueryHistValue_1D(hist, i) * 1.0 / (npix / nbin) * 0.2 * histh for i in range(nbin) ] histimg = plot_1dhisto(histogram, scale=scale, histh=histh, histimg=histimg) return hist, histimg
import anpr from quick_show import quick_show files = os.listdir('data/examples') counter = 0 for f in files: image = cv.LoadImage('data/examples/' + f) for plate in anpr.detect_plates(image): plate_grey = anpr.greyscale(plate) hist = cv.CreateHist([256], cv.CV_HIST_ARRAY, [[0, 255]]) cv.CalcHist([plate_grey], hist) total_pixels = plate_grey.width * plate_grey.height accum = 0 threshold = 0 for i in range(0, 256): accum += cv.QueryHistValue_1D(hist, i) if accum > total_pixels * .45: threshold = i break print threshold plate_mono = cv.CreateImage((plate.width, plate.height), cv.IPL_DEPTH_8U, 1) cv.Threshold(plate_grey, plate_mono, threshold, 255.0, cv.CV_THRESH_BINARY) for x in range(0, plate.width): c = 0 for y in range(0, plate.height): if cv.Get2D(plate_mono, y, x)[0]: c += 1 print "=" * c cv.SaveImage('output%02d.png' % counter, plate_mono)
def count(self, value): if isinstance(value, slice): return [self.count(i) for i in range(*value.indices(len(self)))] if self.kind == 'numpy': return self.hist[value] return cv.QueryHistValue_1D(self.hist, value)
def cv_hist_to_list(h, bins): return [cv.QueryHistValue_1D(h, i) for i in xrange(bins)]