def shift_acc_center_of_mass(img): img = cv2.bitwise_not(img) # centralize according to center of mass shiftx, shifty = get_best_shift(img) shifted = shift(img, shiftx, shifty) img = shifted img = cv2.bitwise_not(img) return img
def image_processing(imageA, img0, lang, csv_file): count = 0 img = imageA.copy() # prepare image quality for OCR img = cv2.bitwise_not(img) _, img_recog = cv2.threshold(img, 210, 255, cv2.THRESH_BINARY) _, img = cv2.threshold(img, 224, 255, cv2.THRESH_BINARY) #find text areas imgBi = cv2.bitwise_not(imageA) _, binary2 = cv2.threshold(imgBi, 0, 255, cv2.THRESH_BINARY) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (21, 20)) eroded = cv2.erode(binary2, kernel, iterations=1) erodedBi = cv2.bitwise_not(eroded) contours2, hierarchy2 = cv2.findContours(erodedBi, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # find head area for OCR text with color headArea = img_recog[104:204, 319:1493] erodedHead = cv2.erode(headArea, kernel, iterations=1) erodedHead = cv2.bitwise_not(erodedHead) contours, hierarchy = cv2.findContours(erodedHead, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for i in range(len(contours)): x, y, w, h = cv2.boundingRect(contours[i]) if w < 1000: count += 1 cv2.rectangle(img0, (x + 319, y + 104), (x + 319 + w, y + 104 + h), (0, 255, 0), 2) crop_img = headArea[y:y + h, x:x + w] cv2.imwrite('ref.png', crop_img) text = tesserocr.image_to_text(Image.open('ref.png'), lang) text = text.replace(" ", "") text = text.replace("\n", " ") csv_file.write('{}:,{},{},{},{},{}\n'.format( count, x, y, w, h, text.encode('utf-8'))) for j in range(len(contours2)): cnt2 = contours2[j] x2, y2, w2, h2 = cv2.boundingRect(cnt2) if x2 > 120 and y2 > 200 and 2 < w2 and 2 < h2 < 450: count += 1 cv2.rectangle(img0, (x2, y2), (x2 + w2, y2 + h2), (0, 255, 0), 2) crop_img = img_recog[y2:y2 + h2, x2:x2 + w2] cv2.imwrite('ref.png', crop_img) text = tesserocr.image_to_text(Image.open('ref.png'), lang) text = text.replace(" ", "") text = text.replace("\n", " ") csv_file.write('{}:,{},{},{},{},{}\n'.format( count, x2, y2, w2, h2, text.encode('utf-8'))) else: pass
def method2(): while c.isOpened(): rd, image = c.read() if rd: # ---------> 前處理 <---------- m1 = image[:, :, 2] # 取 紅色通道 # ---------> 二值化 <---------- th, m2 = cv2.threshold(m1, 50, 255, cv2.THRESH_BINARY) m3 = cv2.bitwise_not(m2) # ---------> 最小方框點 <---------- x, y, w, h = cv2.boundingRect(m3) # ---------> 畫方框在原始圖片上 <---------- cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 255), 3) cv2.imshow("image", image) cv2.imshow("m1", m1) cv2.imshow("m2", m2) cv2.imshow("m3", m3) else: break if cv2.waitKey(10) != -1: break
def method6(): while c.isOpened(): rd, image = c.read() if rd: # ---------> 前處理 <---------- m1 = image[:, :, 0] # 取 藍色通道 m2 = image[:, :, 2] # 取 紅色通道 m3 = cv2.subtract(m1, m2) # 紅色通道 - 藍色通道 # ---------> 二值化 <---------- th, m3 = cv2.threshold(m3, 50, 255, cv2.THRESH_BINARY) m4 = cv2.bitwise_not(m3) m5 = cv2.Canny(m4, 100, 30) # ---------> 最小方框點 <---------- x, y, w, h = cv2.boundingRect(m5) # ---------> 畫方框在原始圖片上 <---------- cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 255), 3) cv2.imshow("image", image) cv2.imshow("m1", m1) cv2.imshow("m2", m2) cv2.imshow("m3", m3) cv2.imshow("m4", m4) cv2.imshow("m5", m5) else: break if cv2.waitKey(10) != -1: break
def extract(image): hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) low = np.array([0, 100, 250]) high = np.array([179, 255, 255]) mask_fore = cv2.inRange(hsv, low, high) mask_back = cv2.bitwise_not(mask_fore) kernel = np.ones((11, 11), np.float32) / 121 fltr1_f_dil = cv2.dilate(mask_fore, kernel, iterations=1) fltr1_f_bor = cv2.bitwise_and(mask_back, mask_back, mask=fltr1_f_dil) contours, hierarchy = cv2.findContours(fltr1_f_bor, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) contours = sorted(contours, key=lambda ctr: cv2.boundingRect(ctr)[0]) i = 0 save_path = os.path.join(os.getcwd(), IMG_DES) if not os.path.exists(save_path): os.makedirs(save_path) for cnt in contours: x, y, w, h = cv2.boundingRect(cnt) if w > 50 and h > 50: p = os.path.join(save_path, "{}.png".format(str(i))) cv2.imwrite(p, pad_image(fltr1_f_bor[y:y + h, x:x + w])) i = i + 1
def identify_countors(image): stations = [] image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) image_invert = cv2.bitwise_not(image_gray) contours, _ = cv2.findContours(image_invert, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) for cnt in contours: approx = cv2.approxPolyDP(cnt, 0.02 * cv2.arcLength(cnt, True), True) M = cv2.moments(cnt) cx = int(M["m10"] / M["m00"]) cy = int(M["m01"] / M["m00"]) x, y, w, h = cv2.boundingRect(cnt) # detect if the square is rotationed # TODO: detect in some other way tilted = cnt.ravel()[0] == cx station = { "type": get_type_by_edges(len(approx), tilted), "pos": (x, y), "centroid": (cx, cy), "size": (w, h), "contour": cnt } stations.append(station) return stations
def rm_otsu_sunshade(img, roi, config): shadow = get_shadow(img, roi) img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # get threshold for shadow region # print('thr_in_shadow') thr_in_shadow = masked_otsu_threshold(img_gray, shadow) # get road markings in shadow _, rm_in_shadow = cv2.threshold(img_gray, thr_in_shadow, 255, cv2.THRESH_BINARY) # kernel_erode = np.ones((7,7), np.uint8) # shadow_eroded = cv2.erode(roi_shadow, kernel_erode) rm_in_shadow = cv2.bitwise_and(rm_in_shadow, rm_in_shadow, mask=shadow) # get threshold for sunlight region shadow_inv = cv2.bitwise_not(shadow) shadow_inv = cv2.bitwise_and(shadow_inv, shadow_inv, mask=roi) thr_out_shadow = masked_otsu_threshold(img_gray, shadow_inv) # get road markings not in shadow _, rm_out_shadow = cv2.threshold(img_gray, int( (thr_out_shadow * 1.5) % 255), 255, cv2.THRESH_BINARY) # rm_out_shadow = cv2.bitwise_and(rm_out_shadow, rm_out_shadow, mask=shadow_inv) # combine markings in shadow and not in shadow rm = cv2.bitwise_or(rm_in_shadow, rm_out_shadow) rm = cv2.bitwise_and(rm, rm, mask=roi) return rm
def denoising(im, original, ime_firme): morph = im.copy() kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 1)) morph = cv2.morphologyEx(morph, cv2.MORPH_CLOSE, kernel) morph = cv2.morphologyEx(morph, cv2.MORPH_OPEN, kernel) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2)) # split the gradient image into channels image_channels = np.split(np.asarray(morph), 3, axis=2) channel_height, channel_width, _ = image_channels[0].shape # apply Otsu threshold to each channel for i in range(0, 3): _, image_channels[i] = cv2.threshold( image_channels[i], 0, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY) image_channels[i] = np.reshape(image_channels[i], newshape=(channel_height, channel_width, 1)) # merge the channels image_channels = np.concatenate( (image_channels[0], image_channels[1], image_channels[2]), axis=2) gray = cv2.cvtColor(image_channels, cv2.COLOR_BGR2GRAY) gray = cv2.bitwise_not(gray) bw = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, \ cv2.THRESH_BINARY, 15, -2) text = dilation(bw, original, ime_firme) return text
def addTwoImgs(self, img1_RGBA, face_param): #将贴纸贴到图片上 self.img = cv2.imread(self.path) self.img = cv2.resize(self.img, (int(face_param[2] / 1), int(face_param[2] / 1)), interpolation=cv2.INTER_CUBIC) try: self.rows, self.cols = self.img.shape[:2] except: NoteLabel.config(text='Fail in loading sticker!') self.getStickerPosition(face_param) if self.x1 >= 0 and self.x2 <= img1_RGBA.shape[ 1] and self.y1 >= 0 and self.y2 <= img1_RGBA.shape[0]: #制作掩膜 roi = img1_RGBA[self.y1:self.y2, self.x1:self.x2] sticker_gray = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY) ret, mask = cv2.threshold(sticker_gray, 10, 255, cv2.THRESH_BINARY) del ret #没什么意义,不想出现黄色报错而已 mask_inv = cv2.bitwise_not(mask) img1_bg = cv2.bitwise_and(roi, roi, mask=mask_inv) self.img = cv2.cvtColor(self.img, cv2.COLOR_BGR2RGBA) dst = cv2.add(img1_bg, self.img) img1_RGBA[self.y1:self.y2, self.x1:self.x2] = dst return True, img1_RGBA else: NoteLabel.config(text="No enough space for stickers!") return False, None
def logic_demo(m1, m2): dst1 = cv.bitwise_and(m1, m2) dst2 = cv.bitwise_or(m1, m2) dst3 = cv.bitwise_not(m1) cv.imshow("and", dst1) cv.imshow("or", dst2) cv.imshow("not", dst3)
def input_data_74k_digits(): train_imgs = [] train_digits = [] test_imgs = [] test_digits = [] SPLIT_PERCENT = 80 # 80% train, 20% test for i in range(10): pics_filenames = glob.glob('digits_model/training/char74k_digits/' + str(i) + '/*.png') max_train_inputs = int(len(pics_filenames) * (SPLIT_PERCENT / 100)) counter = 1 for filename in pics_filenames: imgsample = Image.open(filename) image = np.array(imgsample) image = cv2.bitwise_not(image) image = cv2.resize(image, (28, 28)) if counter < max_train_inputs: train_imgs.append(image) train_digits.append(i) else: test_imgs.append(image) test_digits.append(i) counter += 1 return process_input_data(np.array(train_imgs), train_digits, np.array(test_imgs), test_digits)
def imgSkeleton(original_img): ret, binary_img = cv2.threshold(original_img, 0, 1, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU) extracted_img = skeletonize(binary_img) skeleton = extracted_img.astype(np.uint8) * 255 skeleton = cv2.bitwise_not(skeleton) return skeleton
def imgReadAndConvert(imgfilename): original_img = cv2.imread(imgfilename) # inspect error object img_copy = original_img.copy() height = img_copy.shape[0] width = img_copy.shape[1] #Image resize(prevent overflow) if (height * width * 1000) > 2 ^ 31: resize = img_copy elif (height * width > 2 ^ 31): resize = cv2.resize(img_copy, dsize=(0.0001, int(0.01 * height / width)), interpolation=cv2.INTER_AREA) else: resize = cv2.resize(img_copy, dsize=(1000, int(1000 * height / width)), interpolation=cv2.INTER_AREA) #GaussianBlur blur = cv2.GaussianBlur(resize, (5, 5), 0) #Image graying: reduce the influence of color gray = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY) #Noises removal from outside the contours kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)) img_open = cv2.morphologyEx(gray, cv2.MORPH_OPEN, kernel) #Covert image into binary bin_img = cv2.adaptiveThreshold(img_open, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 21, 20) #Reverse image color bin_img = cv2.bitwise_not(bin_img) return bin_img
def deskew(img): skew_img = cv2.bitwise_not(img) # Invert image # grab the (x, y) coordinates of all pixel values that # are greater than zero, then use these coordinates to # compute a rotated bounding box that contains all # coordinates coords = np.column_stack(np.where(skew_img > 0)) angle = cv2.minAreaRect(coords)[-1] # the `cv2.minAreaRect` function returns values in the # range [-90, 0); as the rectangle rotates clockwise the # returned angle trends to 0 -- in this special case we # need to add 90 degrees to the angle if angle < -45: angle = -(90 + angle) # otherwise, just take the inverse of the angle to make # it positive else: angle = -angle # rotate the image to deskew it (h, w) = img.shape[:2] center = (w // 2, h // 2) M = cv2.getRotationMatrix2D(center, angle, 1.0) rotated = cv2.warpAffine(img, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE) return angle, rotated
def find_game_frame(screen): global game_frame img = np.array(screen) thresh = cv2.inRange(img, WINDOW_BORDER_COLOR, WINDOW_BORDER_COLOR) contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if len(contours) == 0: return window_border = max(contours, key=cv2.contourArea) x0, y0, w, h = cv2.boundingRect(window_border) window_crop = thresh[y0:y0 + h, x0:x0 + w] window_thresh = cv2.bitwise_not(window_crop) contours, _ = cv2.findContours(window_thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if len(contours) == 0: return game_border = max(contours, key=cv2.contourArea) x1, y1, w, h = cv2.boundingRect(game_border) if w * h < 540 * 405: return game_frame = (x0 + x1, y0 + y1, w, h)
def rotate_90(self, image): #cv2.resize(image, (800, 800)) #cv2.imshow('dddimage', image) #cv2.waitKey(0) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) gray = cv2.bitwise_not(gray) thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1] coords = np.column_stack(np.where(thresh > 0)) angle = cv2.minAreaRect(coords)[-1] if angle < -45: angle = -(90 + angle) else: angle = -angle angle = 90 (h, w) = image.shape[:2] #print(h, w) center = (w / 2, h / 2) M = cv2.getRotationMatrix2D(center, angle, 1.0) rotated = cv2.warpAffine(image, M, (w, h)) #cv2.resize(rotated, (800, 1000)) #cv2.imshow('rotated', rotated) #cv2.waitKey(0) file_path_name = 'img/rotate_img.jpg' cv2.imwrite(file_path_name, rotated) return file_path_name
def _preprocess(self, warped_img): ''' Preprocess the warped and rotated image. @warped_img: np.array, it should be the output of self._polar_warp_and_rotate(). @return: (s_mask, output_img), saturation mask and image after preprocessing. ''' warped_img = cv.GaussianBlur(warped_img, (3, 3), 1.5) hsv = cv.cvtColor(warped_img, cv.COLOR_BGR2HSV) warped_img = cv.cvtColor(warped_img, cv.COLOR_BGR2GRAY) warped_img = cv.equalizeHist(warped_img) # Enhance contrast _, s, _ = cv.split(hsv) _, s = cv.threshold(s, 0, 255, cv.THRESH_OTSU) s = cv.morphologyEx(s, cv.MORPH_ERODE, np.ones((5, 5))) _, contours, _ = cv.findContours(s, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE) contours = sorted(contours, key=lambda ctr: cv.contourArea(ctr) ) # Sort to choose the largest area mask = cv.drawContours(np.zeros((warped_img.shape), np.uint8), contours, len(contours) - 1, (255, 255, 255), thickness=1) box = cv.boundingRect(get_points(mask)) # Largest area box-bouding mask = cv.rectangle(mask, (box[0], box[1]), (box[0] + box[2], box[1] + box[3]), (255, 255, 255), cv.FILLED) # Fill the area that is to be removed mask = cv.bitwise_not(mask) # Ensure tooth existing area return mask, warped_img
def generateNewMap(self, map_raw, visualize=True): if visualize: cv2.imshow('Originial Image', map_raw) map_bw = cv2.threshold(map_raw, self._bw_thresh, 255, cv2.THRESH_BINARY)[1] map_bw = cv2.bitwise_not(map_bw) if visualize: cv2.imshow('Image threshold black and white', map_bw) # try to clean up noise in the map kernel = np.ones((5, 5), np.uint8) map_bw = cv2.morphologyEx(map_bw, cv2.MORPH_CLOSE, kernel) map_bw = cv2.morphologyEx(map_bw, cv2.MORPH_CLOSE, kernel) if visualize: cv2.imshow('filtered image', map_bw) # shrink image to get desired scale height, width = map_bw.shape new_height = int(height * self._scale_px2m / self._scale) new_width = int(width * self._scale_px2m / self._scale) map_shrunk = cv2.resize(map_bw, (new_width, new_height)) / 255 if visualize: cv2.imshow('resized map', map_shrunk) map_mat = np.array(map_shrunk) if visualize: # shut down when done print("Check generated map, press ESC to continue") k = cv2.waitKey(0) if k == 27: # wait for ESC key to exit cv2.destroyAllWindows() return map_mat
def generate(self, text): plate = self.draw(text) plate = cv2.bitwise_not(plate) #黑底白字 plate = cv2.bitwise_or(plate, self.bg) #加入背景 plate = rotRandrom(plate, 15, (plate.shape[1], plate.shape[0])) plate = Add_Env(plate, self.env_path) plate = GaussBlur(plate, 1 + R(7)) return plate
def mask_image2(self, img, contours): img2 = img.copy() contours = contours.reshape((contours.shape[0], 1, contours.shape[1])) mask = np.zeros(img.shape[:-1], np.uint8) cv.fillPoly(mask, [contours], 255, cv.LINE_AA) mask_inv = cv.bitwise_not(mask) img2[mask_inv == 0] = (255, 255, 255) return img2
def extract(img, left, right): dim_y = len(img) dim_x = len(img[0]) # cv2.imshow('', img) # cv2.waitKey(0) final_mask = np.zeros((dim_y, dim_x, 3), np.uint8) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # cv2.imshow('gray', gray) # cv2.waitKey(0) _, thresh = cv2.threshold(gray, 75, 255, cv2.THRESH_BINARY_INV) # cv2.imshow('thresh', thresh) # cv2.waitKey(0) l, r = 0, 0 t = 0 max_cnt = [] print("_____________") while r - l < right - left: t += 1 cnt = copy.deepcopy(thresh) # cv2.imshow('cnt', cnt) # cv2.waitKey(0) contours, hierarchy = cv2.findContours(cnt, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) cv2.drawContours(cnt, contours, -1, 255, t) # cv2.imshow('cnt', cnt) # cv2.waitKey(0) contours, hierarchy = cv2.findContours(cnt, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) max_cnt = max(contours, key=cv2.contourArea) # print(max_cnt) # for tmp in max_cnt: # print(tmp) l = min(max_cnt[:, :, 0]) r = max(max_cnt[:, :, 0]) # print(l, r) cv2.drawContours(final_mask, [max_cnt], 0, (255, 255, 255), -1) # cv2.imshow('final_mask', final_mask) # cv2.waitKey(0) bit_and = cv2.bitwise_and(img, final_mask) bit_not = cv2.bitwise_not(final_mask) final = cv2.bitwise_or(bit_and, bit_not) # cv2.imshow('final', final) # cv2.waitKey(0) contrast = cv2.addWeighted(final, 1.5, final, 0, 0) # cv2.imshow('contrast', contrast) # cv2.waitKey(0) return contrast
def overlay_images(img1, img2, mask): # img2gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY) # ret, mask = cv2.threshold(img2gray, 10, 255, cv2.THRESH_BINARY) mask_inv = cv2.bitwise_not(mask) img1_bg = cv2.bitwise_and(img1, img1, mask=mask_inv) img2_fg = cv2.bitwise_and(img2, img2, mask=mask) dst = cv2.add(img1_bg, img2_fg) return dst
def read_image(image_path, inverted=False): if inverted: print("Inverted") return cv2.bitwise_not(cv2.imread(image_path)) a = cv2.imread(image_path) if a is None: msg = "Couldn't load image from %s" % image_path raise Exception(msg) return a
def _merge_pics(original_frame, solution_warped): ret, warp = cv2.threshold(solution_warped, 10, 255, cv2.THRESH_BINARY) mask_inv = cv2.bitwise_not(warp) background = cv2.bitwise_and(original_frame, original_frame, mask=mask_inv) foreground = cv2.cvtColor(solution_warped, cv2.COLOR_GRAY2BGR) foreground[solution_warped > 0] = (255, 55, 0) dst = cv2.add(background, foreground) return dst
def removeLines(path, imgPath): img = cv2.imread(imgPath, 0) img = 255 - img _, thres = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) cv2.imwrite(path + "removed//thres.jpg", thres) horizontal = thres vertical = thres cols = horizontal.shape[1] h_kernel = cols // 30 horizontalStructure = cv2.getStructuringElement(cv2.MORPH_RECT, (h_kernel, 1)) horizontal = cv2.erode(horizontal, horizontalStructure) horizontal = cv2.dilate(horizontal, horizontalStructure) cv2.imwrite(path + "removed//horizontal.jpg", horizontal) rows = vertical.shape[0] v_kernel = rows // 30 verticalStructure = cv2.getStructuringElement(cv2.MORPH_RECT, (1, v_kernel)) vertical = cv2.erode(vertical, verticalStructure) vertical = cv2.dilate(vertical, verticalStructure) cv2.imwrite(path + "removed//vertical.jpg", vertical) _, edges = cv2.threshold(vertical, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) cv2.imwrite(path + "removed//edges.jpg", edges) kernel = np.ones((2, 2), dtype="uint8") dilated = cv2.dilate(edges, kernel) cv2.imwrite(path + "removed//dilated.jpg", dilated) mask = cv2.bitwise_not(vertical + horizontal) kernel = np.ones((2, 2), np.uint8) mask = cv2.erode(mask, kernel, iterations=3) cv2.imwrite(path + "removed//invh.jpg", mask) masked_img = cv2.bitwise_and(img, img, mask=mask) masked_img_inv = cv2.bitwise_not(masked_img) cv2.imwrite(path + "removed_result.jpg", masked_img_inv) return masked_img_inv
def grab_digits(img: object, file_name: str) -> list: """A partir de uma imagem processada previamente irá realizar o seguinte: 1) Inverte os pixels com bitwise. 2) Encontra os contornos que delimitam os dígitos. 3) Realiza o corte caso vários dígitos sejam interpretados juntos 4) Retorna os dígitos na ordem em que aparecem na imagem.""" adjusted_img = cv2.resize(img, (0, 0), fx=2, fy=2) processed_img = cv2.bitwise_not(adjusted_img) contours, _ = cv2.findContours( processed_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE ) interpreted_digits = [] labels = [] for contour in contours: x, y, w, h = cv2.boundingRect(contour) if w > 10 and h > 10: labels.append((x, y, w, h)) # Ordenando com base nas maiores larguras w e desconsiderando o dígito de maior largura: sorted_labels = sorted(labels, key=lambda e: e[2])[:-1] size_sorted_labels = len(sorted_labels) # Caso tenham sido interpretados somente 3 dígitos, usa a largura mínima no lugar da média if size_sorted_labels >= 3: average = sum(i for _, _, i, _ in sorted_labels) / size_sorted_labels elif size_sorted_labels >= 2: average = min(labels, key=lambda e: e[2])[2] else: logger.debug( f"Imagem {file_name}: Não foi possível isolar os dígitos na imagem." ) return [] for element in labels: x, y, w, h = element if w / average > 1.5: logger.debug(f"Imagem {file_name}: Realizados cortes adicionais na imagem.") interpreted_digits = interpreted_digits + _trim_digits( element, average, picture=processed_img ) else: # Cortando com um pixel de margem para cada lado interpreted_digits.append( (processed_img[y - 1 : y + h + 1, x - 1 : x + w + 1], x) ) # Retorna os digitos interpretados e na ordem em que ocorrem na imagem logger.info(f"Imagem {file_name}: Processada com sucesso.") return [digits for digits, x in sorted(interpreted_digits, key=lambda e: e[1])]
def get_corners(painting_roi, draw=False): gray = cv2.cvtColor(painting_roi, cv2.COLOR_BGR2GRAY) blur = cv2.bilateralFilter(gray, 9, 75, 75) erosion = cv2.erode(blur, np.ones((9, 9), np.uint8), iterations=2) dilation = cv2.dilate(erosion, np.ones((9, 9), np.uint8), iterations=2) _, thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) # edges = auto_canny(thresh) h, w = thresh.shape[:2] mask = np.zeros((h + 2, w + 2), np.uint8) flood = thresh.copy() cv2.floodFill(flood, mask, (0, 0), 255) im_floodfill_inv = cv2.bitwise_not(flood) im_out = thresh | im_floodfill_inv contours, _ = cv2.findContours(im_out, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # find the biggest countour (c) by the area c = max(contours, key=cv2.contourArea) x, y, w, h = cv2.boundingRect(c) bbox = x, y, w, h corners = cv2.goodFeaturesToTrack(im_out[y - 10:y + h + 10, x:x + w + 10], 4, 0.01, painting_roi.shape[0] / 3, useHarrisDetector=True) corners = np.int0(corners) corners = np.squeeze(corners) corners_img = painting_roi.copy() # draw the biggest contour (c) in green cv2.rectangle(corners_img, (x, y), (x + w + 10, y + h + 10), (0, 255, 0), 2) if draw: for i, corner in enumerate(corners): x_corner, y_corner = corner.ravel() cv2.circle(corners_img, (x_corner, y_corner), 3, 255, -1) cv2.putText(corners_img, f'{i}', (x_corner + 3, y_corner + 3), cv2.FONT_HERSHEY_SIMPLEX, 0.75, color=(255, 0, 0)) cv2.imshow("corners", corners_img) # for corner in corners: # corner[0] += x # corner[1] += y return corners, bbox
def _crop_by_hue(self, img): ''' ### Now deprecated! ### ''' lower_bound = 5 upper_bound = 175 inv_mask = cv.inRange(img, lower_bound, upper_bound) red_mask = cv.bitwise_not(inv_mask) # Crop for red zone in hue dst = cv.bitwise_and(red_mask, img) dst = cv.GaussianBlur(dst, (5, 5), 10) _, dst = cv.threshold(dst, 0, 255, cv.THRESH_OTSU) return dst
def Fill_Holes(image): im_fill = image.copy() h, w = image.shape[:2] mask = np.zeros((h + 2, w + 2), np.uint8) cv2.floodFill(im_fill, mask, (0, 0), 255) im_fill_inv = cv2.bitwise_not(im_fill) filled_image = cv2.bitwise_or(im_fill_inv, image) return filled_image
def preprocess_image(image, target_size): gray = image.convert('L') bw = gray.point(lambda x: 0 if x < 100 else 255, '1') bw.save("bw_image.jpg") img_array = cv2.imread("bw_image.jpg", cv2.IMREAD_GRAYSCALE) img_array = cv2.bitwise_not(img_array) new_array = cv2.resize(img_array, target_size) user_test = tensorflow.keras.utils.normalize(new_array, axis=1) user_test = user_test.reshape((1, 28, 28)) predicted = model.predict([user_test]) return predicted