def edges_det(img, min_val, max_val): """ Preprocessing (gray, thresh, filter, border) + Canny edge detection """ img = cv2.cvtColor(resize(img), cv2.COLOR_BGR2GRAY) # Applying blur and threshold img = cv2.bilateralFilter(img, 9, 75, 75) img = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 115, 4) implt(img, 'gray', 'Adaptive Threshold') # Median blur replace center pixel by median of pixels under kelner # => removes thin details img = cv2.medianBlur(img, 11) # Add black border - detection of border touching pages # Contour can't touch side of image img = cv2.copyMakeBorder(img, 5, 5, 5, 5, cv2.BORDER_CONSTANT, value=[0, 0, 0]) implt(img, 'gray', 'Median Blur + Border') return cv2.Canny(img, min_val, max_val)
def edges_det(img, min_val, max_val): """ Preprocessing (gray, thresh, filter, border) + Canny edge detection """ kernel = np.ones((2, 2), np.uint8) img = cv2.cvtColor(resize(img), cv2.COLOR_BGR2GRAY) # img = cv2.bilateralFilter(img, 9, 75, 75) img = cv2.GaussianBlur(img, (5, 5), 0) # img = cv2.GaussianBlur(img, (5, 5), 0) implt(img, 'gray', 'blur') img = cv2.adaptiveThreshold(img, 175, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 115, 1) implt(img, 'gray', 'Adaptive Threshold') img = cv2.erode(img, kernel, iterations=1) implt(img, 'gray', 'erode') img = cv2.dilate(img, kernel, iterations=1) implt(img, 'gray', 'dilate') img = cv2.medianBlur(img, 1) # img = cv2.blur(img,(10,10)) img = cv2.copyMakeBorder(img, 5, 5, 5, 5, cv2.BORDER_CONSTANT, value=[0, 0, 0]) implt(img, 'gray', 'Median Blur + Border') return cv2.Canny(img, min_val, max_val)
def del_lines(gray): """ Delete page lines """ linek = np.ones((1, 11), np.uint8) x = cv2.morphologyEx(gray, cv2.MORPH_OPEN, linek, iterations=1) i = gray - x closing = cv2.morphologyEx(dil, cv2.MORPH_CLOSE, np.ones((17, 17), np.uint8)) implt(closing, 'gray', 'Del Lines') return closing
def hyster(self): r, c = self.img.shape for ri in range(r): for ci in range(c): if (self.img[ri, ci] >= self.high): self.im[ri, ci] = 255 self.img[ri, ci] = 255 self.hyster_rec(ri, ci) implt(self.im, 'gray', 'Hister Thresh')
def idxImage(self, index): """ Getting next image from the array """ if index < len(self.boxes): b = self.boxes[index] x1, y1, x2, y2 = b # Cuting out the word image img = self.image[y1:y2, x1:x2] implt(img, t='Index: ' + str(index)) self.recognise(img)
def edges_det(img, min_val, max_val): img = cv2.cvtColor(resize(img), cv2.COLOR_BGR2GRAY) img = cv2.bilateralFilter(img, 9, 75, 75) img = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 115, 4) implt(img, 'gray', 'Adaptive Threshold') img = cv2.medianBlur(img, 11) img = cv2.copyMakeBorder(img, 5, 5, 5, 5, cv2.BORDER_CONSTANT, value =[0, 0, 0]) implt(img, 'gray', 'Median Blur + Border') return cv2.Canny(img, min_val, max_val)
def text_detect(img, original): """ Text detection using contours """ # Resize image small = resize(img, 2000) image = resize(original, 2000) # Finding contours mask = np.zeros(small.shape, np.uint8) im2, cnt, hierarchy = cv2.findContours(np.copy(small), cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE) implt(img, 'gray') # Variables for contour index and words' bounding boxes index = 0 boxes = [] # CCOMP hierarchy: [Next, Previous, First Child, Parent] # cv2.RETR_CCOMP - contours into 2 levels # Go through all contours in first level while (index >= 0): x, y, w, h = cv2.boundingRect(cnt[index]) # Get only the contour cv2.drawContours(mask, cnt, index, (255, 255, 255), cv2.FILLED) maskROI = mask[y:y + h, x:x + w] # Ratio of white pixels to area of bounding rectangle r = cv2.countNonZero(maskROI) / (w * h) # Limits for text (white pixel ratio, width, height) # TODO Test h/w and w/h ratios if r > 0.1 and 2000 > w > 10 and 1600 > h > 10 and h / w < 3 and w / h < 10: boxes += [[x, y, w, h]] # Index of next contour index = hierarchy[0][index][0] # Group intersecting rectangles boxes = group_rectangles(boxes) bounding_boxes = np.array([0, 0, 0, 0]) for (x, y, w, h) in boxes: cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 8) bounding_boxes = np.vstack( (bounding_boxes, np.array([x, y, x + w, y + h]))) implt(image, t='Bounding rectangles') # Recalculate coordinates to original scale boxes = bounding_boxes.dot(ratio(image, small.shape[0])).astype(np.int64) return boxes[1:]
def evalLetters(feed): predict_, target_, predict_lengths_, target_lengths_ = sess.run( [letter_prediction_infer, letter_targets, final_seq_lengths, letter_targets_length], feed) for i, (inp, pred) in enumerate(zip(target_, predict_)): print("Expected images:", target_lengths_[i]) for x in range(len(inp)): implt(inp[x].reshape((64, 64)), 'gray') print("Predicted images:", predict_lengths_[i]) for x in range(len(pred)): implt(pred[x].reshape((64, 64)), 'gray') if i >= 0: break
def elastic_transform(image, alpha, sigma, alpha_affine, random_state=None): if random_state is None: random_state = np.random.RandomState(None) shape = image.shape shape_size = shape[:2] blur_size = int(4 * sigma) | 1 dx = alpha * cv2.GaussianBlur((random_state.rand(*shape) * 2 - 1), ksize=(blur_size, blur_size), sigmaX=sigma) dy = alpha * cv2.GaussianBlur((random_state.rand(*shape) * 2 - 1), ksize=(blur_size, blur_size), sigmaX=sigma) x, y = np.meshgrid(np.arange(shape[1]), np.arange(shape[0])) indices = np.reshape(y + dy, (-1, 1)), np.reshape(x + dx, (-1, 1)) image = map_coordinates(image, indices, order=1, mode='constant').reshape(shape) implt(image, 'gray') # Random affine center_square = np.float32(shape_size) // 2 square_size = min(shape_size) // 3 pts1 = np.float32([ center_square + square_size, [center_square[0] + square_size, center_square[1] - square_size], center_square - square_size ]) pts2 = pts1 + random_state.uniform( -alpha_affine, alpha_affine, size=pts1.shape).astype(np.float32) M = cv2.getAffineTransform(pts1, pts2) image = cv2.warpAffine(image, M, shape_size[::-1], borderMode=cv2.BORDER_CONSTANT) return image
def process_image(imag): # %matplotlib inline IMG = imag plt.rcParams['figure.figsize'] = (15.0, 10.0) """### Global Variables""" """## Load image""" image = cv2.cvtColor(cv2.imread(IMG), cv2.COLOR_BGR2RGB) implt(image) # Crop image and get bounding boxes crop = page.detection(image) implt(crop) boxes = words.detection(crop) lines = words.sort_words(boxes) implt(crop) output_file = open("templates/output.html", 'w+') output_file.write("") output_file.close() output_file = open("templates/output.html", 'a+') for line in lines: print(" ".join( [recognise(crop[y1:y2, x1:x2]) for (x1, y1, x2, y2) in line])) for (x1, y1, x2, y2) in line: text_det = recognise(crop[y1:y2, x1:x2]) output_file.write(text_det + " ") output_file.write("\n") output_file.close()
def normalization1(img): ret, th = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) th = 255 - th img = 255 - img implt(th, 'gray') # CLAHE (Contrast Limited Adaptive Histogram Equalization) clahe = cv2.createCLAHE(clipLimit=3., tileGridSize=(8, 8)) # convert from BGR to LAB color space lab = cv2.cvtColor(cv2.cvtColor(img, cv2.COLOR_GRAY2RGB), cv2.COLOR_RGB2LAB) l, a, b = cv2.split(lab) # split on 3 different channels l2 = clahe.apply(l) # apply CLAHE to the L-channel lab = cv2.merge((l2, a, b)) # merge channels img2 = cv2.cvtColor(lab, cv2.COLOR_LAB2BGR) # convert from LAB to B img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY) ret, th2 = cv2.threshold(img2, 0, 255, cv2.THRESH_TRUNC + cv2.THRESH_OTSU) implt(th2, 'gray') kernel = np.ones((2, 2), np.uint8) dilation = cv2.dilate(th, kernel, iterations=1) dilation = cv2.GaussianBlur(th, (3, 3), 0) res = cv2.bitwise_and(th2, th2, mask=dilation) implt(res, 'gray')
def main(file_name): # print(open(FilePaths.fnAccuracy).read()) decoderType = Model.DecoderType.BestPath model = Model.Model(open(FilePaths.fnCharList).read(), decoderType, mustRestore=True) filelist=glob.glob("new1/*.png") filename = file_name+'.txt' f=open(filename,'w') for file in filelist: os.remove(file) for i in FilePaths.fnInfer: if i[-5]=='e': f.write('\n') else: print("processing ",i) img=preprocessimg(i) implt(img) #img=cv2.imread(i) #img=contrast(img) #implt(img) cv2.imwrite("out123.png",img) FilePaths.index = FilePaths.index + 1 infer(model,"out123.png", f) f.close()
def del_big_areas(img): """ Find and remove contours too big for a word """ gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # ret, gray = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) gray = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 101, 3) implt(gray, 'gray') gray2 = gray.copy() mask = np.zeros(gray.shape, np.uint8) im2, contours, hierarchy = cv2.findContours(gray, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) for cnt in contours: if (200 < cv2.contourArea(cnt) < 5000): cv2.drawContours(img, [cnt], 0, (0, 255, 0), 2) cv2.drawContours(mask, [cnt], 0, 255, -1) implt(mask) implt(img)
def textDetectWatershed(thresh, original): """ Text detection using watershed algorithm """ # According to: http://docs.opencv.org/trunk/d3/db4/tutorial_py_watershed.html img = resize(original, 3000) thresh = resize(thresh, 3000) # noise removal kernel = np.ones((3, 3), np.uint8) opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=3) # sure background area sure_bg = cv2.dilate(opening, kernel, iterations=3) # Finding sure foreground area dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5) ret, sure_fg = cv2.threshold(dist_transform, 0.01 * dist_transform.max(), 255, 0) # Finding unknown region sure_fg = np.uint8(sure_fg) unknown = cv2.subtract(sure_bg, sure_fg) # Marker labelling ret, markers = cv2.connectedComponents(sure_fg) # Add one to all labels so that sure background is not 0, but 1 markers += 1 # Now, mark the region of unknown with zero markers[unknown == 255] = 0 markers = cv2.watershed(img, markers) implt(markers, t='Markers') image = img.copy() gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Creating result array boxes = [] for mark in np.unique(markers): # mark == 0 --> background if mark == 0: continue # Draw it on mask and detect biggest contour mask = np.zeros(gray.shape, dtype="uint8") mask[markers == mark] = 255 cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2] c = max(cnts, key=cv2.contourArea) # Draw a bounding rectangle if it contains text x, y, w, h = cv2.boundingRect(c) cv2.drawContours(mask, c, 0, (255, 255, 255), cv2.FILLED) maskROI = mask[y:y + h, x:x + w] # Ratio of white pixels to area of bounding rectangle r = cv2.countNonZero(maskROI) / (w * h) # Limits for text if r > 0.1 and 2000 > w > 15 and 1500 > h > 15: boxes += [[x, y, w, h]] # Group intersecting rectangles boxes = group_rectangles(boxes) bounding_boxes = np.array([0, 0, 0, 0]) for (x, y, w, h) in boxes: cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 8) bounding_boxes = np.vstack( (bounding_boxes, np.array([x, y, x + w, y + h]))) implt(image) # Recalculate coordinates to original size boxes = bounding_boxes.dot(ratio(original, img.shape[0])).astype(np.int64) return boxes[1:]
import sys import numpy as np import pandas as pd import matplotlib.pyplot as plt import cv2 sys.path.append('../src') from ocr.helpers import implt, resize, ratio import pytesseract #%matplotlib inline plt.rcParams['figure.figsize'] = (9.0, 9.0) image = cv2.cvtColor( cv2.imread('E:/NLP-master/images/claim_Byju member vst_0.jpg'), cv2.COLOR_BGR2RGB) implt(image) def edges_det(img, min_val, max_val): """ Preprocessing (gray, thresh, filter, border) + Canny edge detection """ kernel = np.ones((2, 2), np.uint8) img = cv2.cvtColor(resize(img), cv2.COLOR_BGR2GRAY) # img = cv2.bilateralFilter(img, 9, 75, 75) img = cv2.GaussianBlur(img, (5, 5), 0) # img = cv2.GaussianBlur(img, (5, 5), 0) implt(img, 'gray', 'blur') img = cv2.adaptiveThreshold(img, 175, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 115, 1) implt(img, 'gray', 'Adaptive Threshold') img = cv2.erode(img, kernel, iterations=1) implt(img, 'gray', 'erode')
# ### Global Variables # In[5]: IMG = "form_digit" # Image name/number # In[6]: # Loading images and ploting it (converting to RGB from BGR) image = cv2.cvtColor(cv2.imread("../data/form/%s.jpg" % IMG), cv2.COLOR_BGR2RGB) implt(image) # In[7]: def edges_det(img, min_val, max_val): """ Preprocessing (gray, thresh, filter, border) + Canny edge detection """ img = cv2.cvtColor(resize(img), cv2.COLOR_BGR2GRAY) # Applying blur and threshold img = cv2.bilateralFilter(img, 9, 75, 75) img = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 115, 4) implt(img, 'gray', 'Adaptive Threshold') # Median blur replace center pixel by median of pixels under kelner
import numpy as np import pandas as pd import matplotlib.pyplot as plt import cv2 from ocr.helpers import implt, resize, ratio plt.rcParams['figure.figsize'] = (12.0, 12.0) IMG = "check2.jpg" image = cv2.cvtColor(cv2.imread(IMG), cv2.COLOR_BGR2RGB) implt(image) def fourCornersSort(pts): diff = np.diff(pts, axis=1) summ = pts.sum(axis=1) return np.array([ pts[np.argmin(summ)], pts[np.argmax(diff)], pts[np.argmax(summ)], pts[np.argmin(diff)] ]) def contourOffset(cnt, offset): cnt += offset cnt[cnt < 0] = 0 return cnt def findPageContours(edges, img): im2, contours, hierarchy = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
import cv2 from scipy.ndimage.interpolation import map_coordinates from scipy.ndimage.filters import gaussian_filter import matplotlib.pyplot as plt sys.path.append('../src') from ocr.helpers import implt from ocr.datahelpers import load_words_data get_ipython().run_line_magic('matplotlib', 'inline') plt.rcParams['figure.figsize'] = (6.0, 5.0) # In[2]: raw_images, _ = load_words_data('../data/raw/breta/words/') implt(random.choice(raw_images), 'gray', t='Original') # ## Testing normalization # In[3]: def normalization1(img): ret, th = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) th = 255 - th img = 255 - img implt(th, 'gray') # CLAHE (Contrast Limited Adaptive Histogram Equalization) clahe = cv2.createCLAHE(clipLimit=3., tileGridSize=(8, 8)) # convert from BGR to LAB color space
import matplotlib.pyplot as plt import tensorflow as tf import cv2 from PIL import Image import pytesseract import os from ocr.helpers import implt, resize from ocr import page from ocr import words IMG = '1' # 1, 2, 3 filename = "test/2.jpg" save_filename = "test/2_1.jpg" image = cv2.cvtColor(cv2.imread(filename), cv2.COLOR_BGR2RGB) implt(image) crop = page.detection(image) implt(crop) gray = cv2.cvtColor(crop, cv2.COLOR_BGR2GRAY) gray = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1] gray = cv2.medianBlur(gray, 3) implt(gray) cv2.imwrite(save_filename, gray) text = pytesseract.image_to_string(Image.open(save_filename)) os.remove(save_filename) print(text)
def normalization2(img): implt(255 - img, 'gray', 'Original') implt(255 - bilateral_norm(img), 'gray', 'Bilateral') implt(255 - binary_otsu_norm(img), 'gray', 'Binary OTSU') implt(histogram_norm(img), 'gray', 'Binary OTSU + (Filter + TO_ZERO)') HysterThresh(cv2.bilateralFilter(img, 10, 10, 30))
def text_detect(img, original): """ Text detection using contours """ # Resize image small = resize(img, 2000) image = resize(original, 2000) # Finding contours mask = np.zeros(small.shape, np.uint8) im2, cnt, hierarchy = cv2.findContours(np.copy(small), cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE) # implt(img, 'gray') # Variables for contour index and words' bounding boxes index = 0 boxes = [] test_digits = np.array(np.zeros((1,784))) i = 0 # CCOMP hierarchy: [Next, Previous, First Child, Parent] # cv2.RETR_CCOMP - contours into 2 levels # Go through all contours in first level while (index >= 0): x,y,w,h = cv2.boundingRect(cnt[index]) # Get only the contour cv2.drawContours(mask, cnt, index, (255, 255, 255), cv2.FILLED) maskROI = mask[y:y+h, x:x+w] # Ratio of white pixels to area of bounding rectangle r = cv2.countNonZero(maskROI) / (w * h) # Limits for text (white pixel ratio, width, height) # TODO Test h/w and w/h ratios # if r > 0.1 and 2000 > w > 10 and 1600 > h > 10 and h/w < 3 and w/h < 10: if r > 0.1 and 40 > w > 1 and 1600 > h > 10 and (h/w < 3 or w/h < 10): boxes += [[x, y, w, h]] roi = image[y:y+h, x:x+w] digit = cv2.cvtColor(roi, cv2.COLOR_RGB2GRAY) digit, j = digit_preprocessing(digit) cv2.imwrite("../data/form/output{0}.jpg".format(i), digit) digit_row = np.resize(digit,(1,784)) test_digits = np.append(test_digits,digit_row,axis=0) i += 1 # Index of next contour index = hierarchy[0][index][0] # Group intersecting rectangles boxes = group_rectangles(boxes) bounding_boxes = np.array([0,0,0,0]) for (x, y, w, h) in boxes: cv2.rectangle(image, (x, y),(x+w,y+h), (0, 255, 0), 8) bounding_boxes = np.vstack((bounding_boxes, np.array([x, y, x+w, y+h]))) implt(image, t='Bounding rectangles') # Recalculate coordinates to original scale boxes = bounding_boxes.dot(ratio(image, small.shape[0])).astype(np.int64) return test_digits, boxes[1:]
IMG = 'check' # 1, 2, 3 LANG = 'cz' # cz, en MODEL_LOC = 'models/char-clas/' + LANG + '/CharClassifier' # ## Load Trained Model # In[3]: charClass = Graph(MODEL_LOC) # ## Load image # In[4]: image = cv2.cvtColor(cv2.imread("test/%s.jpg" % IMG), cv2.COLOR_BGR2RGB) implt(image) # In[5]: # Crop image and get bounding boxes crop = page.detection(image) implt(crop) bBoxes = words.detection(crop) # # Simple UI using widgets # In[6]: class Cycler: """ Cycle through the words and recognise them """
import pytesseract import os sys.path.append('E:\Text_model\src') from ocr.helpers import implt, resize from ocr import page from ocr import words IMG = '1' # 1, 2, 3 filename = 'E:/Medical-Prescription-OCR-master/Model-2/test/3.png' #save_filename = "E:/Medical-Prescription-OCR-master/Model-2/test/2_1.jpg" image = cv2.imread(filename) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) implt(image) #crop = page.detection(image) #implt(crop) #cv2.imwrite('E:\Text_model\images\hhha.jpg',crop) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) gray = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1] gray = cv2.medianBlur(gray, 3) implt(gray) cv2.imwrite("E:\Text_model\images\dfsdf.jpg", gray) text = pytesseract.image_to_string(gray) #os.remove(save_filename) print(text)
def fun(list1): import numpy as np import pandas as pd import matplotlib.pyplot as plt import tensorflow as tf import cv2 import random # Import costume functions, corresponding to notebooks from ocr.normalization import imageNorm, letterNorm from ocr import page, words #from ocr import charSeg from ocr.helpers import implt, resize from ocr.tfhelpers import Graph from ocr.datahelpers import idx2char from src import gsmain import glob import os # ### Global Variables for x_file in list1: tf.reset_default_graph() str1 = ''.join(x_file) # Settings IMG = str1 # 1, 2, 3 # ## Load image image = cv2.cvtColor(cv2.imread(IMG), cv2.COLOR_BGR2RGB) implt(image) # Crop image and get bounding boxes crop = page.detection(image) implt(crop) bBoxes = words.detection(crop) lines = words.sort_words(bBoxes) filelist = glob.glob("./new3/*.png") for file in filelist: os.remove(file) indeximg = 0 nl = 0 for line in lines: for (x1, y1, x2, y2) in line: cv2.imwrite("new3/" + str(indeximg) + ".png", crop[y1:y2, x1:x2]) #implt(cv2.imread("outcheck.png")) indeximg = indeximg + 1 #gsmain.FilePaths.fnInfer = ["outcheck.png"] #wordreco = gsmain.main() #file.write(wordreco + ' ') cv2.imwrite("new3/" + str(nl) + "space.png", crop[y1:y2, x1:x2]) nl = nl + 1 #Get all segmented words list2 = glob.glob("./new3/*.png") list2.sort(key=os.path.getmtime) '''list2=list() for ii in range(0,indeximg): list2.append("")''' #all files which have to be infer are loaded rand_num = random.randint(100, 1000) cv2.imwrite('final_output/' + str(rand_num) + '.jpg', image) for i in range(0, len(list2)): gsmain.FilePaths.fnInfer = gsmain.FilePaths.fnInfer + [list2[i]] gsmain.main('final_output/' + str(rand_num))
# ### Global Variables # In[3]: IMG = "page09" # Image name/number # # Finding the text areas and words # In[4]: # Loading image (converting to RGB) image = cv2.cvtColor(cv2.imread("../data/pages/%s.jpg" % IMG), cv2.COLOR_BGR2RGB) image = page.detection(image) img = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) implt(img, 'gray') # In[5]: def sobel(channel): """ The Sobel Operator""" sobelX = cv2.Sobel(channel, cv2.CV_16S, 1, 0) sobelY = cv2.Sobel(channel, cv2.CV_16S, 0, 1) # Combine x, y gradient magnitudes sqrt(x^2 + y^2) sobel = np.hypot(sobelX, sobelY) sobel[sobel > 255] = 255 return np.uint8(sobel) def edge_detect(im):