def compositeThreshold(gray, mode='com'): if mode == 'otsu': otsu = threshold_otsu(gray) otsu_bin = gray > otsu otsu_bin = otsu_bin.astype(np.uint8) * 255 return otsu_bin elif mode == 'yen': yen = threshold_yen(gray) yen_bin = gray > yen yen_bin = yen_bin.astype(np.uint8) * 255 return yen_bin elif mode == 'li': li = threshold_li(gray) li_bin = gray > li li_bin = li_bin.astype(np.uint8) * 255 return li_bin elif mode == 'niblack': niblack = threshold_niblack(gray, window_size=13, k=0.8) niblack_bin = gray > niblack niblack_bin = niblack_bin.astype(np.uint8) * 255 return niblack_bin elif mode == 'sauvola': sauvola = threshold_sauvola(gray, window_size=13) sauvola_bin = gray > sauvola sauvola_bin = sauvola_bin.astype(np.uint8) * 255 return sauvola_bin elif mode == 'com': li = threshold_li(gray) li_bin = gray > li li_bin = li_bin.astype(np.uint8) * 255 otsu = threshold_otsu(gray) otsu_bin = gray > otsu otsu_bin = otsu_bin.astype(np.uint8) * 255 yen = threshold_yen(gray) yen_bin = gray > yen yen_bin = yen_bin.astype(np.uint8) * 255 return cv2.min(cv2.min(otsu_bin, li_bin), yen_bin) elif mode == "niblack-multi": thr = np.zeros((gray.shape), dtype=np.uint8) thr[thr >= 0] = 255 for k in np.linspace(-0.8, 0.2, 5): #(-1.8,0.2,5) thresh_niblack = threshold_niblack(gray, window_size=25, k=k) binary_niblack = gray > thresh_niblack binary_niblack = binary_niblack.astype(np.uint8) * 255 showResult("binary_niblack", binary_niblack) thr = cv2.min(thr, binary_niblack) return thr else: sauvola = threshold_sauvola(gray, window_size=25, k=0.25) sauvola_bin = gray > sauvola sauvola_bin = sauvola_bin.astype(np.uint8) * 255 niblack = threshold_niblack(gray, window_size=25, k=0.25) niblack_bin = gray > niblack niblack_bin = niblack_bin.astype(np.uint8) * 255 return cv2.max(sauvola, niblack)
def SauvolaModBinarization(image, n1=51, n2=51, k1=0.3, k2=0.3, default=True): ''' Binarization using Sauvola's algorithm @name : SauvolaModBinarization parameters @param image (numpy array of shape (3/1) of type np.uint8): color or gray scale image optional parameters @param n1 (int) : window size for running sauvola during the first pass @param n2 (int): window size for running sauvola during the second pass @param k1 (float): k value corresponding to sauvola during the first pass @param k2 (float): k value corresponding to sauvola during the second pass @param default (bool) : bollean variable to set the above parameter as default. @param default is set to True : thus default values of the above optional parameters (n1,n2,k1,k2) are set to n1 = 5 % of min(image height, image width) n2 = 10 % of min(image height, image width) k1 = 0.5 k2 = 0.5 Returns @return A binary image of same size as @param image @cite https://drive.google.com/file/d/1D3CyI5vtodPJeZaD2UV5wdcaIMtkBbdZ/view?usp=sharing ''' if (default): n1 = int(0.05 * min(image.shape[0], image.shape[1])) if (n1 % 2 == 0): n1 = n1 + 1 n2 = int(0.1 * min(image.shape[0], image.shape[1])) if (n2 % 2 == 0): n2 = n2 + 1 k1 = 0.5 k2 = 0.5 if (image.ndim == 3): gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) else: gray = np.copy(image) T1 = threshold_sauvola(gray, window_size=n1, k=k1) max_val = np.amax(gray) min_val = np.amin(gray) C = np.copy(T1) C = C.astype(np.float32) C[gray > T1] = (gray[gray > T1] - T1[gray > T1]) / (max_val - T1[gray > T1]) C[gray <= T1] = 0 C = C * 255.0 new_in = np.copy(C.astype(np.uint8)) T2 = threshold_sauvola(new_in, window_size=n2, k=k2) binary = np.copy(gray) binary[new_in <= T2] = 0 binary[new_in > T2] = 255 return binary
def sauvola(grayimg, w=51, k=0.2, scaledown=None, reverse=False): mask =None if scaledown is not None: mask = cv2.resize(grayimg,None,fx=scaledown,fy=scaledown) w = int(w * scaledown) if w % 2 == 0: w += 1 mask = threshold_sauvola(mask, w, k) mask = cv2.resize(mask,(grayimg.shape[1],grayimg.shape[0]),fx=scaledown,fy=scaledown) else: if w % 2 == 0: w += 1 mask = threshold_sauvola(grayimg, w, k) if reverse: return where(grayimg > mask, uint8(0), uint8(1)) else: return where(grayimg > mask, uint8(1), uint8(0))
def processBinarization(self, algorithm=ImageAlgorithm.SAUVOLA): if algorithm == ImageAlgorithm.SAUVOLA: image = skimage.io.imread(fname=self.pathImg, as_gray=True) thresh_sauvola = threshold_sauvola(image, window_size=81) self.binary_sauvola = image > thresh_sauvola """ self.binary_sauvola = invert(self.binary_sauvola) chull = convex_hull_image(self.binary_sauvola) [rows, columns] = np.where(chull) EPS = 50 row1 = min(rows) - EPS row2 = max(rows) + EPS col1 = min(columns) - EPS col2 = max(columns) + EPS self.binary_sauvola = self.binary_sauvola[row1:row2, col1:col2] self.binary_sauvola = invert(self.binary_sauvola) """ self.binary_sauvola = invert(self.binary_sauvola) #selem = disk(6) self.binary_sauvola = thin(self.binary_sauvola, np.int(15)) self.binary_sauvola = np.invert(self.binary_sauvola) #thresh_sauvola = threshold_sauvola(self.binary_sauvola, window_size=21) #self.binary_sauvola = self.binary_sauvola > thresh_sauvola self.binary_sauvola = erosion(self.binary_sauvola) #self.binary_sauvola = gaussian(self.binary_sauvola) elif algorithm == ImageAlgorithm.OTSU: self.otsuBinarization()
def get_leaf_venation(gray_img): # using the sauvola algorithm threshold = threshold_sauvola(image=gray_img, window_size=11, k=0.04) venation_img = gray_img > threshold plt.imshow(venation_img) plt.show() return venation_img
def binarize(image: np.ndarray, holes_threshold: float = 20) -> np.ndarray: """ Binarize image using Sauvola algorithm. Parameters ---------- image : np.ndarray RGB image to binarize. holes_threshold : float, optional Pixel areas covering less than the given number of pixels are removed in the process, by default 20. Returns ------- binarized : np.ndarray Binarized and filtered image. """ # Extract brightness channel from HSV-converted image image_gray = rgb2hsv(image)[:,:,2] # Enhance contrast image_gray = equalize_adapthist(image_gray, kernel_size=100) # Threshold using Sauvola algorithm thresh_sauvola = threshold_sauvola(image_gray, window_size=51, k=0.25) binary_sauvola = image_gray > thresh_sauvola # Remove small objects binary_cleaned = 1.0 * remove_small_holes(binary_sauvola, area_threshold=holes_threshold) # Remove thick black border (introduced during thresholding) binary_cleaned = flood_fill(binary_cleaned, (0, 0), 0) binary_cleaned = flood_fill(binary_cleaned, (0, 0), 1) return binary_cleaned.astype(np.bool)
def binarise_sauvola(image, window_size = 59, k = 0.5, r = 128): thresh_sauvola = threshold_sauvola(image, window_size=window_size, k=k, r=r) binarised_sauvola = image > thresh_sauvola binarised_sauvola = img_as_ubyte(binarised_sauvola) return binarised_sauvola
def fit(self, X=None, y=None): if self.threshold_type == "otsu": threshold_function = lambda data: filters.threshold_otsu(data) elif self.threshold_type == "local_otsu": threshold_function = lambda data: filters.rank.otsu(data, morphology.square(self.block_size)) elif self.threshold_type == "local": threshold_function = lambda data: filters.threshold_local(data, self.block_size) elif self.threshold_type == "niblack": threshold_function = lambda data: filters.threshold_niblack(data, self.block_size) elif self.threshold_type == "sauvola": threshold_function = lambda data: filters.threshold_sauvola(data, self.block_size) elif self.threshold_type is None: threshold_function = None else: raise ValueError("Unknown threshold type: {}".format(self.threshold_type)) self.ocr_reader_ = screen_ocr.Reader.create_reader( backend=self.backend, threshold_function=threshold_function, correction_block_size=self.correction_block_size, margin=self.margin, resize_factor=self.resize_factor, resize_method=self.resize_method, convert_grayscale=self.convert_grayscale, shift_channels=self.shift_channels, label_components=self.label_components, debug_image_callback=None)
def main(img, ws): image = img binary_global = image > threshold_otsu(image) window_size = ws thresh_niblack = threshold_niblack(image, window_size=window_size, k=0.8) thresh_sauvola = threshold_sauvola(image, window_size=window_size) binary_niblack = image > thresh_niblack binary_sauvola = image > thresh_sauvola plt.figure(figsize=(8, 7)) plt.subplot(2, 2, 1) plt.imshow(image, cmap=plt.cm.gray) plt.title('Original') plt.axis('off') plt.subplot(2, 2, 2) plt.title('Global Threshold') plt.imshow(binary_global, cmap=plt.cm.gray) plt.axis('off') plt.subplot(2, 2, 3) plt.imshow(binary_niblack, cmap=plt.cm.gray) plt.title('Niblack Threshold') plt.axis('off') plt.subplot(2, 2, 4) plt.imshow(binary_sauvola, cmap=plt.cm.gray) plt.title('Sauvola Threshold') plt.axis('off') return plt, binary_global, binary_niblack, binary_sauvola
def threshold(image, *, sigma=0., radius=0, offset=0., method='sauvola', smooth_method='Gaussian'): """Use scikit-image filters to "intelligently" threshold an image. Parameters ---------- image : array, shape (M, N, ...[, 3]) Input image, conformant with scikit-image data type specification [1]_. sigma : float, optional If positive, use Gaussian filtering to smooth the image before thresholding. radius : int, optional If given, use local median thresholding instead of global. offset : float, optional If given, reduce the threshold by this amount. Higher values result in fewer pixels above the threshold. method: {'sauvola', 'niblack', 'median'} Which method to use for thresholding. Sauvola is 100x faster, but median might be more accurate. smooth_method: {'Gaussian', 'TV'} Which method to use for smoothing. Choose from Gaussian smoothing and total variation denoising. Returns ------- thresholded : image of bool, same shape as `image` The thresholded image. References ---------- .. [1] http://scikit-image.org/docs/dev/user_guide/data_types.html """ if sigma > 0: if smooth_method.lower() == 'gaussian': image = filters.gaussian(image, sigma=sigma) elif smooth_method.lower() == 'tv': image = restoration.denoise_tv_bregman(image, weight=sigma) if radius == 0: t = filters.threshold_otsu(image) + offset else: if method == 'median': footprint = hyperball(image.ndim, radius=radius) t = ndi.median_filter(image, footprint=footprint) + offset elif method == 'sauvola': w = 2 * radius + 1 t = threshold_sauvola(image, window_size=w, k=offset) elif method == 'niblack': w = 2 * radius + 1 t = threshold_niblack(image, window_size=w, k=offset) else: raise ValueError('Unknown method %s. Valid methods are median,' 'niblack, and sauvola.' % method) thresholded = image > t return thresholded
def threshold(img): cpy = img.copy() blk = max(cpy.shape[0], cpy.shape[1]) blk = int(blk * 0.03) + 1 if int(blk * 0.03) % 2 == 0 else int(blk * 0.03) thresh_sauvola = threshold_sauvola(cpy, blk) binary_sauvola = cpy > thresh_sauvola return binary_sauvola
def main(): image = cv2.imread("./counter_images/01305.png", cv2.IMREAD_GRAYSCALE) # image = cv2.imread("../venv/lib/python3.7/site-packages/skimage/data/page.png", cv2.IMREAD_GRAYSCALE) image = 255 - image image = cv2.medianBlur(image, 7) binary_global = image > threshold_otsu(image) binary_global = np.uint8(binary_global * 255) window_size = 41 thresh_niblack = threshold_niblack(image, window_size=window_size, k=0.8) thresh_sauvola = threshold_sauvola(image, window_size=window_size, k=.1) binary_niblack = image > thresh_niblack binary_niblack = np.uint8(binary_niblack * 255) binary_sauvola = image > thresh_sauvola binary_sauvola = np.uint8(binary_sauvola * 255) imshowWait(image=image, binary_global=binary_global, binary_niblack=binary_niblack, binary_sauvola=binary_sauvola)
def transform_img(img, img_rows, img_cols, mnist=False): # Binarize thresh = threshold_sauvola(img, window_size=13, k=0.025, r=0.5) img = (img < thresh) [h, w] = img.shape # Pad if w > h: factor = img_cols / w img = rescale(img, factor, mode='constant', cval=0) diff = (img_rows - img.shape[0]) / 2 img = np.pad(img, ((int(ceil(diff)), int(floor(diff))), (0, 0)), 'constant', constant_values=((0, ))) else: factor = img_rows / h img = rescale(img, factor, mode='constant', cval=0) diff = (img_cols - img.shape[1]) / 2 img = np.pad(img, ((0, 0), (int(ceil(diff)), int(floor(diff)))), 'constant', constant_values=((0, ))) # Binarize again if mnist: ret = (img > 0.4).astype(int) else: ret = binary_dilation(img) ret = ret.astype(int) return ret
def preprocessImage(img_path): # preprocess and load input image img = cv2.imread(img_path) resized_image = cv2.resize(img, (250, 250)) # removing noise form colored images denoised_image = cv2.fastNlMeansDenoisingColored(resized_image, None, 10, 10, 7, 21) denoised_img_name = imgName() cv2.imwrite("online_data_collection/image_processing/" + denoised_img_name, denoised_image) # Since denoiseing converts BGR image to CELAB, converting CELAB to BGR bgr_image = cv2.cvtColor(denoised_image, cv2.COLOR_Lab2BGR) bgr_img_name = imgName() cv2.imwrite("online_data_collection/image_processing/" + bgr_img_name, bgr_image) # Converion of BGR to Grayscale gray_image = cv2.cvtColor(bgr_image, cv2.COLOR_BGR2GRAY) gray_img_name = imgName() cv2.imwrite("online_data_collection/image_processing/" + gray_img_name, gray_image) # Binarization thres_sauvola = threshold_sauvola(gray_image, window_size=17) binary_sauvola = gray_image > thres_sauvola binary_sauvola = img_as_ubyte(binary_sauvola) binary_img_name = imgName() cv2.imwrite("online_data_collection/image_processing/" + binary_img_name, binary_sauvola) # Smoothing image # smooth_image = cv2.medianBlur(binary_sauvola, 3) smooth_image = cv2.bilateralFilter(binary_sauvola, 9, 75, 75) smooth_img_name = imgName() cv2.imwrite("online_data_collection/image_processing/" + smooth_img_name, smooth_image) return denoised_img_name, bgr_img_name, gray_img_name, binary_img_name, smooth_img_name
def preprocess_image(img, pipeline_id="baseline"): if pipeline_id == "direct_bit_extract": # No preprocessing wanted return img # dpi = img.info["dpi"] # Edge enhance img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) # Thresholding img = skimage.img_as_ubyte(img) # Tests # from skimage.filters import (try_all_threshold, threshold_sauvola, # threshold_local, threshold_niblack) # import matplotlib.pyplot as plt # tmp = skimage.img_as_ubyte(img > threshold_local(img, 15)) # Image.fromarray(tmp).show() # tmp = skimage.img_as_ubyte(img > threshold_niblack(img)) # Image.fromarray(tmp).show() # tmp = skimage.img_as_ubyte(img > threshold_sauvola(img)) # Image.fromarray(tmp).show() # fig, ax = try_all_threshold(img, verbose=False) # plt.show() img = skimage.img_as_ubyte(img > threshold_sauvola(img)) img = Image.fromarray(img) # img.info["dpi"] = dpi return img
def thresh(image,threshtype='local', make_binary=True, simple=False): im=image.copy() if simple==True: im[im<0]=0 return im if threshtype=='global': from skimage.filters import threshold_otsu try: thresh = threshold_otsu(im) except ValueError: thresh=0 binary= im>thresh if make_binary==False: return binary return binary.astype(int) if threshtype=='local': from skimage.filters import threshold_sauvola thresh = threshold_sauvola(im) binary = im< thresh if make_binary==False: return binary return binary.astype(int)
def binarize_sauvola(image): #binarized_filename = input_image_filename.split(".")[0] + "_bin.png" # image = page() # image binarized_filename # image = io.imread(input_image_filename) # opening and grayscaling the image #image = cv2.imread(input_image_filename, cv2.IMREAD_GRAYSCALE) #thresh_niblack = threshold_niblack(image, k=0.8) thresh_sauvola = threshold_sauvola(image) #binary_niblack = image > thresh_niblack binary_sauvola = image > thresh_sauvola #binary_niblack = binary_niblack.astype(int) binary_sauvola = binary_sauvola.astype(int) #binary_niblack *= 255 binary_sauvola *= 255 # applying the binarization # image_bin = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1] #cv2.imwrite("niblack.png", binary_niblack) cv2.imwrite("sauvola.png", binary_sauvola) #print("Binarization completed! Binarized image saved into ", binarized_filename) #return binarized_filename
def __sauvola_method(image: Union[np.ndarray, Iterable, np.uint8], stream, progres) -> np.ndarray: th = threshold_sauvola(image, window_size=45) im = image <= th # imshow(im, cmap='gray') # plt.show() progres.progress(33) # stream[1].append(im) # stream[0].image(stream[1], width=300) # if im.shape[0] > 1000: # gaus = 7 # elif im.shape[0] > 650: # gaus = 3 # else: # gaus = 1 if im.shape[0] > 400: gaus = int(0.00330957 * im.shape[0] - 0.13687352) else: gaus = 1 result = gaussian(im, gaus) # imshow(result) # plt.show() progres.progress(66) stream[1].append(result) stream[0].image(stream[1], width=300) # result = minimum(maximum(result, disk(5)), disk(12)) # imshow(result) # plt.show() return result
def blob_detection2(post_masked_processed, draw): """ Funtion that performs blob detection to localize electrodes. Does not include dilation and erosion. For use in problematic images where blobs are hard to locate. Inputs : Processed post oeprative image, draw (Bool) Outputs : If draw is True, outputs an image with the blobs drawn If draw is False, outputs the coordinates of the centers of the blobs """ # Initial set up; no erosion or dilationn img = cv2.normalize(post_masked_processed, None, 0, 255, cv2.NORM_MINMAX) img = img.astype('uint8') img = cv2.medianBlur(img, 11) th2 = filters.threshold_sauvola(img) th2 = 255 - th2 th2 = th2.astype("uint8") # Set our filtering parameters # Initialize parameter settiing using cv2.SimpleBlobDetector params = cv2.SimpleBlobDetector_Params() # Set Area filtering parameters params.filterByArea = True params.minArea = 10 # Set Circularity filtering parameters params.filterByCircularity = False params.minCircularity = 0.1 # Set Convexity filtering parameters params.filterByConvexity = True params.minConvexity = 0.1 # Set inertia filtering parameters params.filterByInertia = True params.minInertiaRatio = 0.01 # Create a detector with the parameters detector = cv2.SimpleBlobDetector_create(params) # Detect blobs keypoints = detector.detect(th2) if draw == True: # Draw blobs on our image as red circles blank = np.zeros((1, 1)) blobs = cv2.drawKeypoints(th2, keypoints, blank, (0, 0, 255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS) number_of_blobs = len(keypoints) text = "Number of Circular Blobs: " + str(len(keypoints)) cv2.putText(blobs, text, (20, 550), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 100, 255), 2) return blobs else: result = [] for point in keypoints: x = point.pt[0] y = point.pt[1] result.append([x, y]) return result
def ThresholdSauvola(img): ## based on observation using these values of k,r work best (default k=0.2) thresh_sauvola = threshold_sauvola(img.copy(), window_size=31, k=0.1, r=45) binary_sauvola = img > thresh_sauvola image = binary_sauvola.astype('uint8')*255 ## Sauvola is edge sensitive and prone to creating thick borders around image. Try remove them based on size contours, _ = cv2.findContours(255-image.copy(),cv2.RETR_LIST,cv2.CHAIN_APPROX_NONE) mask = np.ones(img.shape[:2], dtype="uint8") * 255 mask_remove = cv2.imread('image.jpg', cv2.IMREAD_ANYCOLOR) mask_retain = cv2.imread('image.jpg', cv2.IMREAD_ANYCOLOR) # loop over the contours for c in contours: # if the contour is bad, draw it on the mask if is_good_contour_for_line_segmentation(c, 255-image.copy())==True: r = cv2.boundingRect(c) cv2.rectangle(mask, (r[0],r[1]), (r[0]+r[2],r[1]+r[3]), color=0, thickness=-1) cv2.drawContours(mask_retain, [c], 0, color=(0,255,0), thickness=1) else: #r = cv2.boundingRect(c) cv2.drawContours(mask_remove, [c], 0, color=(0,0,255), thickness=-1) showimage(mask_retain, 'retaining-this') showimage(mask_remove, 'removing-this') # remove the contours from the image and show the resulting images showimage(255-mask,'contour-removal-mask') ## AARGH! someone please simplify this! X is the correct form, it has already been inverted so text is white. x = cv2.bitwise_and(255-image.copy(),255-mask, mask=255-mask) return x
def process_regions(image, blur_sigma=3, opening_size=3, orientation_deviation=15, overlap_minimum=0.8): ''' Attempt to find any possible marker corner regions in a given image Inputs: - image: grayscale image that may contain a marker - blur_sigma: parameter for Gaussian blur to use on image - opening_size: parameter for morphological opening to use on image - orientation_deviation: see orientation parameter used by region_filter_heuristic(...) - overlap_minimum: see similarity parameter used by region_filter_heuristic(...) Returns: a 2-tuple of: - the image after pre-processing steps like blurring, thresholding, etc. - the list of regionprops that may be possible marker corners ''' # Blur and equalize the image image = exposure.equalize_hist(image) image = filters.gaussian(image, sigma=blur_sigma) # Use local thresholding image = (image <= filters.threshold_sauvola(image, k=0.1)) image = morphology.opening(image, selem=morphology.disk(opening_size)) # Label components in the image labeled = measure.label(image, connectivity=2) components = measure.regionprops(labeled, intensity_image=image) # Sort the components by our rectangle heuristic return image, labeled, [r for r in components if region_filter_heuristic(r, orientation_deviation, overlap_minimum)]
def thickness_score(im, window_size=5, threshold=10, name=None): if im.ndim == 3: im = cv2.cvtColor(im.astype(np.uint8), cv2.COLOR_BGR2GRAY) cv2.imwrite('raw_' + name, im) edge = cv2.Canny(im,50,100) cv2.imwrite('edge_' + name, edge) e_pixel_count = 0 for i in range(edge.shape[0]): for j in range(edge.shape[1]): if edge[i][j] == 255: e_pixel_count += 1 # 计算感兴趣的区域(文字区域) # threshold_val, _ = cv2.threshold(im, -1, 255, cv2.THRESH_OTSU) threshold_val = threshold_sauvola(im, window_size=15, k=0.15) roi = np.zeros_like(im) roi = np.array(im < threshold_val + 10).astype(np.int32) # roi范围扩大一些? roi_pixel_count = 0 for i in range(roi.shape[0]): for j in range(roi.shape[1]): if roi[i][j] == 1: roi_pixel_count += 1 cv2.imwrite('roi_' + name, roi*255) stroke_width = 0 if e_pixel_count == 0: stroke_width = -1 else: stroke_width = float(roi_pixel_count / e_pixel_count) print('stroke width:', stroke_width) return stroke_width
def cod16(image): # hint: increase contrast. window_size = 3 # image = cv.imread("sample2.jpg") # image = cv.cvtColor(image, cv.COLOR_RGB2GRAY) # ix = lambda i: cv.cvtColor(i, cv.COLOR_RGB2GRAY) # print(type(image),image.shape) # print(image) image = clahe_demo(image) # must use gray. # print("spliter") # that is f*****g insane. thresh_niblack = ( toReal(threshold_niblack(image, window_size=window_size, k=3)) * 255.0).astype(np.uint8) thresh_sauvola0 = ( toReal(threshold_sauvola(image, window_size=3, k=1.303)) * 255.0).astype(np.uint8) # for full scan? # perfect inverse of the one above thresh_sauvola1 = (toReal( threshold_sauvola(image, window_size=3, k=0.999999999999999999)) * 255.0).astype(np.uint8) # for button detection? # just filter those things out. # thresh_niblack = threshold_niblack(image, window_size=window_size, k=12).astype(np.uint8) # thresh_sauvola0 = threshold_sauvola(image, window_size=3, k=1.103).astype(np.uint8) # for full scan? # # perfect inverse of the one above # thresh_sauvola1 = threshold_sauvola(image, window_size=3, k=1.523).astype(np.uint8) # for button detection? # print(type(thresh_niblack), thresh_niblack.shape) # print(type(thresh_niblack[0][0])) # ndarray. # it just cannot be right. give it up? # the shape can differ. # calcMe(thresh_niblack) # calcMe(thresh_sauvola0) # calcMe(thresh_sauvola1) # cv.imshow("grayimage",thresh_niblack) # cv.waitKey(0) # cv.imshow("thresholdimage", thresh_sauvola0) # cv.waitKey(0) # cv.imshow("thresholdimage", thresh_sauvola1) # cv.waitKey(0) # cv.destroyAllWindows() # return # # use floor function? # # just what the f**k? return thresh_niblack, thresh_sauvola0, thresh_sauvola1
def doThresholding(method, window_size, k, img): if method == 'niblack': th_mask = threshold_niblack(img, window_size=window_size, k=k) if method == 'sauvola': th_mask = threshold_sauvola(img, window_size=window_size) binary_mask = img < th_mask return(binary_mask)
def binarize(img, window_size=35): # cv_image = img_as_ubyte(img) # img = cv2.adaptiveThreshold(cv_image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, window_size, 0) thresh = filters.threshold_sauvola(img, window_size) img = img > thresh img = np.array(img * 255, dtype=np.uint8) return img
def sauvola(img, window_size=25, min_threshold=0.02): k = 0.25 r = 0.5 t = threshold_sauvola(img, window_size=window_size, k=k, r=r) if min_threshold is not None: t[t <= min_threshold] = min_threshold return t
def extract_feature(arr): radius = 1 n_points = radius * 8 arr = cv2.cvtColor(arr, cv2.COLOR_BGR2GRAY) distances = [1, 5] angles = [0, np.pi / 4, np.pi / 2, 3 * np.pi / 4] glcm = greycomatrix(arr, distances=distances, angles=angles, levels=256, symmetric=False, normed=False) # properties = ['dissimilarity', 'homogeneity', 'contrast', 'ASM', 'energy', 'correlation'] # glcm_feats = np.hstack([greycoprops(glcm, prop=prop).ravel() for prop in properties]) glcm_feats = np.hstack( [adadoc.greycoprops(glcm[:, :, i, :]) for i in range(0, 2)]).ravel() hog_feats = hog(arr, orientations=9, pixels_per_cell=(8, 8), cells_per_block=(1, 1), block_norm='L2-Hys', feature_vector=True) ent = entropy(arr) # # prepare filter bank kernels # kernels = [] # for theta in range(4): # theta = theta / 4. * np.pi # for sigma in (1, 3): # for frequency in (0.05, 0.25): # kernel = np.real(gabor_kernel(frequency, theta=theta, # sigma_x=sigma, sigma_y=sigma)) # kernels.append(kernel) # gabor_feat = compute_feats(arr, kernels).ravel() thresh_sauvola = threshold_sauvola(arr, window_size=31, k=0.2) arr = arr > thresh_sauvola arr = (255 - arr * 255).astype('uint8') # arr = adadoc.adath(arr, method=adadoc.ADATH_SAUVOLA | adadoc.ADATH_INVTHRESH, # xblock=21, yblock=21, k=0.2, dR=64, C=0) lbp_code = local_binary_pattern(arr, n_points, radius, 'uniform') # n_bins = int(lbp_code.max() + 1) n_bins = 16 lbp_feats, _ = np.histogram(lbp_code, normed=True, bins=n_bins, range=(0, n_bins)) data_feat = np.hstack([lbp_feats, ent, glcm_feats, hog_feats]) return data_feat
def threshold_sauvola(arr1d): """ doesnt work: TypeError: ndarray() missing required argument 'shape' (pos 1) :param arr1d: :return: """ import skimage.filters as sf thresh = sf.threshold_sauvola(arr1d, window_size=15, k=0.2, r=None) return thresh
def binarization(image): binarized_image = copy.deepcopy(image) window_size = 33 #Parameter window_size determines the size of the window that contains the surrounding pixels, window size must be odd and greater than 1 thresh_matrix = threshold_sauvola( image, window_size=window_size) #Return matrix of thresholds sauvola_image = image > thresh_matrix #Comparing pixel value with the threshold binarized_image[sauvola_image == False] = 0 binarized_image[sauvola_image == True] = 255 return binarized_image
def estimate_dominant_fontsize(img, dark_text=None, verbose=0): ih, iw = img.shape[:2] kernel = np.array([1, 2, 3, 4, 5, 4, 3, 2, 1], dtype=np.float32) kernel = kernel / np.sum(kernel) paper_name, _ = parse_paper_size(ih, iw) est_lh = compute_fontsize_in_pixels_for_paper(max(ih, iw), font_size=10, paper_name=paper_name) # binarize image if (img.ndim == 2): gimg = img else: gimg = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) #mimg = threshold_otsu( gimg ) mimg = threshold_sauvola(gimg, window_size=min( min(ih, iw) // 20 * 2 + 1, int(est_lh * 5) // 2 * 2 + 1)) if (dark_text is not None): if (dark_text): text = (gimg < mimg).astype('uint8') * 255 else: text = (gimg > mimg).astype('uint8') * 255 else: bimg = (gimg < mimg) if (np.sum(bimg) < bimg.size // 2): text = bimg.astype('uint8') * 255 verbose_print( verbose, "INFO: estimated case = DARK TEXT on bright background") else: text = (1 - bimg.astype('uint8')) * 255 verbose_print( verbose, "INFO: estimated case = BRIGHT TEXT on dark background") cvCCA = cv2.connectedComponentsWithStats(text, 8, cv2.CV_32S) num_regs, labels, reg_stats, centroids = cvCCA # estimate dominated fontsize rel_lut = dict() for label in range(num_regs): # retrieving the width of the bounding box of the component width = reg_stats[label, cv2.CC_STAT_WIDTH] # retrieving the height of the bounding box of the component height = reg_stats[label, cv2.CC_STAT_HEIGHT] if (height > est_lh * .75) and (height < est_lh * 10): if (height not in rel_lut): rel_lut[height] = 0 rel_lut[height] += width keys = list(rel_lut) vals = list(rel_lut.values()) vall = np.sum(vals) obs = np.zeros(np.max(keys) + 1) for k, v in zip(keys, vals): obs[k] = float(v) / vall n_obs = np.convolve(obs, kernel, mode='same') dominant_fontsize = np.argmax(n_obs) return dominant_fontsize
import matplotlib.pyplot as plt from skimage.data import page from skimage.filters import (threshold_otsu, threshold_niblack, threshold_sauvola) matplotlib.rcParams['font.size'] = 9 image = page() binary_global = image > threshold_otsu(image) window_size = 25 thresh_niblack = threshold_niblack(image, window_size=window_size, k=0.8) thresh_sauvola = threshold_sauvola(image, window_size=window_size) binary_niblack = image > thresh_niblack binary_sauvola = image > thresh_sauvola plt.figure(figsize=(8, 7)) plt.subplot(2, 2, 1) plt.imshow(image, cmap=plt.cm.gray) plt.title('Original') plt.axis('off') plt.subplot(2, 2, 2) plt.title('Global Threshold') plt.imshow(binary_global, cmap=plt.cm.gray) plt.axis('off')