def zoom_number(image, cont): inverted_threshold = filter_squares(image) contours = contours_numbers(inverted_threshold) largest_area = 0 x = 0 y = 0 w = 0 h = 0 curve = 0 for i, c in enumerate(contours): xTemp, yTemp, wTemp, hTemp = cv2.boundingRect(c) if( cv2.contourArea(c) > largest_area and \ (hTemp < image.shape[0]*.9 and wTemp < image.shape[1]*.9)\ and hTemp > 10 and wTemp > 10): #limites definidos, numero no es menor a 10 ni debe largest_area = cv2.contourArea(c) # medir el 90% de la imagen curve = cv2.arcLength(c, True) x, y, w, h = cv2.boundingRect(c) # print("contourArea for",cont," is: ",curve,"image h:",image.shape[0],"image w:",image.shape[1]) # print("contour h:",h," and w: ",w) # cv2.rectangle(image,(x,y),(x+w,y+h),(0,255,0),2) if (curve != 0): top_left_point = (x, y) top_right_point = (x + w, y) bottom_left_point = (x, y + h) bottom_right_point = (x + w, y + h) corners = np.float32([ top_left_point, top_right_point, bottom_left_point, bottom_right_point ]) result = transform(image, corners, 50, 50) else: result = image return result
def detect_faces(col_img, img): dilated_img = dilate_image(img) img_gray = cv2.cvtColor(dilated_img, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(img_gray, 127, 255, 0) contours, hierachy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) max_points_contour = 0 max_contour_index = 0 for i in range(0, len(contours)): if (len(contours[i]) > max_points_contour): max_points_contour = len(contours[i]) max_contour_index = i for contour in contours: (x, y, w, h) = cv2.boundingRect(contour) width = cv2.boundingRect(contour)[2] height = cv2.boundingRect(contour)[3] if ((cv2.contourArea(contour) < 200) or (width > height * 2)): continue cv2.rectangle(col_img, (x, y), (x + w, y + h), (0, 255, 0), 2) cv2.imshow('Colored image', col_img) cv2.waitKey(0) cv2.destroyAllWindows()
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 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 process_image(img): image = data_uri_to_cv2_img(img) # greyscale gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # binary (__, img_bw) = cv2.threshold(gray, 128, 255, cv2.THRESH_BINARY_INV) # dilation # find contours ctrs, __ = cv2.findContours(img_bw.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # sort contours char_ctr = sorted(ctrs, key=lambda ctr: (cv2.boundingRect(ctr)[2] * cv2.boundingRect(ctr)[3]), reverse=True)[0] # Get bounding box x, y, w, h = cv2.boundingRect(char_ctr) # Getting ROI roi = img_bw[y:y + h, x:x + w] return skeletize(crop(roi, IMAGE_SIZE))
def find_anchor_point(img, ww, hh): crop = img[:, :img.shape[1] // 2] crop = aug(crop) crop = cv2.GaussianBlur(crop, (5, 5), 0) def get_white(src): # # 白色 lower_white = np.array([0, 0, 170]) upper_white = np.array([180, 45, 255]) hsv = cv2.cvtColor(src, cv2.COLOR_BGR2HSV) mask = cv2.inRange(hsv, lower_white, upper_white) return mask wmask = get_white(crop) ero = eroded(wmask) cnts, _ = cv2.findContours(ero, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) new_cnts = [] def cnt_area(cnt): area = cv2.contourArea(cnt) return area for cnt in cnts: x, y, w, h = cv2.boundingRect(cnt) if cnt_area(cnt) > 2500 and cnt_area( cnt) < 5500 and w < 150 and h < 120 and h > w: new_cnts.append(cnt) if len(new_cnts) > 1: new_cnts.sort(key=cnt_area, reverse=True) y0 = 0 cnt0 = new_cnts[0] for ncnt in new_cnts: x, y, w, h = cv2.boundingRect(ncnt) if y0 > y and x > 240 and x < 300: cnt0 = ncnt y0 = y new_cnts = cnt0 cv2.drawContours(img, new_cnts, -1, (0, 0, 255), 2) #cv2.imshow('imggg', img) def get_bound(cnts): allarea = np.concatenate(cnts) x, y, w, h = cv2.boundingRect(allarea) return x, y, w, h cut_img = img if len(new_cnts) > 0: # print(len(new_cnts)) x1, y1, w1, h1 = get_bound(new_cnts) #print('***************',x1,y1) return x1, y1 # cut_img = img[y1 + h1 - 25 - hh:y1 + h1 - hh, x1 + w1 - 52 - ww:x1 + w1 - ww] # new # return cut_img return None
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 check_angle(self, contours): no1x, no1y, no1w, no1h, no2x, no2y, no2w, no2h = 0, 0, 0, 0, 0, 0, 0, 0 for cnt in contours: x, y, w, h = cv2.boundingRect(cnt) if no1w < w: no1w, no1x, no1y = w, x, y if no1h < h: no1h, no1x, no1y = w, x, h for cnt in contours: x, y, w, h = cv2.boundingRect(cnt) if no1w > w and no2w < w: no2w, no2x, no2y = w, x, y if no1h > w and no2h < h: no2h, no2x, no2y = h, x, y return no1x, no1y, no1w, no1h, no2x, no2y, no2w, no2h
def scan_number(image): arrayImage_num =[] edged = cv2.Canny(image, 10, 250) (cnts, _) = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) sorted_ctrs = sorted(cnts, key=lambda cnts: cv2.boundingRect(cnts)[0]) idx=0 for i, ctr in enumerate(sorted_ctrs): x, y, w, h = cv2.boundingRect(ctr) if w>35 and h>45 : if w<50 and h<60 : idx+=1 new_img=image[y:y+h,x:x+w] arrayImage_num.append(new_img) return arrayImage_num
def get_painting_from_roi(self, cntrs, img): """ It takes the contours of a painting and returns the painting extracted from the given image :param cntrs: contours of the image :param img: image containing paintings :return: painting extracted from the image """ # find the biggest countour (c) by the area c = max(cntrs, key=cv2.contourArea) rc = cv2.minAreaRect(c) box = cv2.boxPoints(rc) for p in box: pt = (p[0], p[1]) # print(pt) # cv2.circle(frame, pt, 5, (200, 0, 0), 2) # approximate the contour (approx) with 10% tolerance epsilon = 0.1 * cv2.arcLength(c, True) approx = cv2.approxPolyDP(c, epsilon, True) x, y, w, h = cv2.boundingRect(approx) # draw the biggest contour (c) in green # cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) extracted_painting = img[y:y + h, x:x + w] return extracted_painting
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 detect_holes(grey_frame, original_frame, trackbars, count): thresh = cv.adaptiveThreshold(grey_frame, *trackbars) contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_NONE) for contour in contours: # approx = cv.approxPolyDP(contour, 0.01 * cv.arcLength(contour, True), True) # area = cv.contourArea(contour) perimeter = cv.arcLength(contour, True) if len(contour) > 100 and 100 < perimeter < 300: # if len(contour) > 5 and 200 < area < 1000: x, y, w, h = cv.boundingRect(contour) img_c = original_frame[y:y + h, x:x + w] # if count % 30 == 0: # cv.imwrite(new_dir + '/' + str(time.time()) + str(random()) + '.jpg', img_c) img = cv.resize(img_c, IMAGE_SIZE) img_array = img_to_array(img) img_array = img_array.reshape((1,) + img_array.shape) # Converting into 4 dimension array interpreter.set_tensor(input_details[0]['index'], img_array) interpreter.invoke() predictions = interpreter.get_tensor(output_details[0]['index']) if predictions[0][0] > 0.9: # print(predictions[0][1]) # if count % 30 == 0: cv.imwrite(new_dir + '/' + str(time.time()) + str(random()) + '.jpg', img_c) cv.rectangle(original_frame, (x, y), (x + w, y + h), (0, 0, 255), 2) # cv.drawContours(original_frame, [contour], 0, (0, 255, 0), 2) return original_frame
def convex1(ImgNo, defThr=127): img = cv2.imread(impDef.select_img(ImgNo)) imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, thr = cv2.threshold(imgray, defThr, 255, 0) contours, _ = cv2.findContours(thr, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 원본 이미지의 6번째 contour인 contours[5]가 단풍잎 모양의 외곽을 에워싸고 있는 contour cnt = contours[5] # contour에 외접하는 똑바로 세워진 사각형을 얻기 위해 cv2.boundingRect() 함수를 이용합니다. x, y, w, h = cv2.boundingRect(cnt) #cv2.boudingRect()함수는 인자로 받은 contour에 외접하고 똑바로 세워진 직사각형의 # 좌상단 꼭지점 좌표 (x, y)와 가로 세로 폭을 리턴합니다. # 이렇게 얻은 좌표를 이용해 원본 이미지에 빨간색으로 사각형을 그립니다. cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 3) rect = cv2.minAreaRect(cnt) #cv2.minAreaRect() 함수는 인자로 입력한 contour에 외접하면서 면적이 가장 작은 직사각형을 구하는데 활용됩니다. # 이 함수의 리턴값은 좌상단 꼭지점 좌표 (x, y), 가로 세로 폭과 이 사각형이 기울어진 각도입니다. box = cv2.boxPoints(rect) #v2.boxPoints() 함수는 cv2.minAreaRect() 함수로 얻은 직사각형의 꼭지점 4개의 좌표를 얻기 위해 사용됩니다. box = np.int0(box) #좌표는 float형으로 리턴되므로 np.int0()로 정수형 값으로 전환한 후, 원본 이미지에 초록색 사각형을 그리는 겁니다. cv2.drawContours(img, [box], 0, (0, 255, 2), 3) cv2.imshow('retangle', img) impDef.close_window()
def getContours(img,cThr=[100,100],showCanny=False,minArea=1000,filter=0,draw =False): imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) imgBlur = cv2.GaussianBlur(imgGray,(5,5),1) imgCanny = cv2.Canny(imgBlur,cThr[0],cThr[1]) kernel = np.ones((5,5)) imgDial = cv2.dilate(imgCanny,kernel,iterations=3) imgThre = cv2.erode(imgDial,kernel,iterations=2) if showCanny:cv2.imshow('Canny',imgThre) contours,hiearchy = cv2.findContours(imgThre,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) finalCountours = [] for i in contours: area = cv2.contourArea(i) if area > minArea: peri = cv2.arcLength(i,True) approx = cv2.approxPolyDP(i,0.02*peri,True) bbox = cv2.boundingRect(approx) if filter > 0: if len(approx) == filter: finalCountours.append([len(approx),area,approx,bbox,i]) else: finalCountours.append([len(approx),area,approx,bbox,i]) finalCountours = sorted(finalCountours,key = lambda x:x[1] ,reverse= True) if draw: for con in finalCountours: cv2.drawContours(img,con[4],-1,(0,0,255),3) return img, finalCountours
def identifyChunks(blobs, RECTpadding=2, OCRpadding=3, drawRect=True, ocr=False, textType=False): regions = [] # index, coordinates, density contours, _ = cv2.findContours(blobs.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) mask = np.zeros(blobs.shape, np.uint8) textType = "" text = "" i = 0 for contour in range(len(contours)): i = i + 1 (x, y, w, h) = cv2.boundingRect(contours[contour]) mask[y:y + h, x:x + w] = 0 # mask around bounding rectangle cv2.drawContours(mask, contours, contour, (255, 255, 255), -1) # white fill to bounding rectangle area # cv2.imwrite(path+"sample//result" + str(i) + ".jpg",mask) white = np.sum(mask[y:y + h, x:x + w] == 255) density = float(white / (w * h)) regions.append([i, (x, y, w, h), density, text, textType]) return regions
def line_slice(roi_kreuzung, dieser_frame, offset): """ Zeichnet auf auf einem Schnit am gegebenen Y-Offset im Kamerabild die gefundenen Linienstückchen als grüne Rechtecke ein. Wird die eine Linie zu breit, wird das Rechteck rot eingefärbt. Das Zentrum aller Linienstückchen in einem Schnitt wird mit einem Punkt markiert. """ yoffset = PIXEL_HOEHE - (PIXEL_HOEHE - 200) - 20 - offset # Horizontalen Streifen an y-Position "offset" herausschneiden roi_line = dieser_frame[PIXEL_HOEHE - 20 - offset:PIXEL_HOEHE - 1 - offset, 0:PIXEL_BREITE - 1] # in HSV-Farbschema umwandeln hsv = cv2.cvtColor(roi_line, cv2.COLOR_BGR2HSV) # Maske erstellen (Monochromes Bild: Linie weiß, alles andere schwarz) black_mask = cv2.inRange(hsv, black_lower_limit, black_upper_limit) # Konturen extrahieren _, konturen, _ = cv2.findContours(black_mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cx = 0 cy = yoffset + 5 cnt = 0 farbe = GRUEN # Liste der X-Positionen der Zentren der gefundenen Linienstücke ret = [] is_kreuzung = False for kontur in konturen: # Rechteck um die Kontur erhalten x, y, w, h = cv2.boundingRect(kontur) # zu kleine Konturen wegfiltern if w > 10: # zu große Konturen rot einfärben if w > 150: farbe = ROT is_kreuzung = True # sonst grün einfärben else: farbe = GRUEN # Rechteck um die Kontur zeichnen cv2.rectangle(roi_kreuzung, (x, y + yoffset), (x + w, y + yoffset + h), farbe, 2) # Summe aller x-Positionen der Zentren der gefundenen Rechtecke bilden cx = cx + int(x + w / 2) # Anzahl der gefundenen Rechecke mitzählen cnt = cnt + 1 # Rote Rechtecke: X-Position ist 0 (Mitte des Kamerabildes) if is_kreuzung: ret.append(0) # Grüne Rechtecke: Abweichung von Bildmitte an Liste anfügen else: ret.append(cx - PIXEL_BREITE / 2) # keine Linienstücke gefunden: Durchnitt aller X-Positionen ist Bildmitte if cx is 0: cx = (PIXEL_BREITE - 1) / 2 # Linienstückchen gefunden: Durchschnitt aller X-Positionen errechnen else: cx = cx / cnt # Kreis zeichnen an durchschnittlicher X-Position aller gefundenen Linienstückchen cv2.circle(roi_kreuzung, (int(cx), int(cy)), 5, farbe, -1) # Ergebnisliste zurückgeben: Liste der Abweichung der Linie von Mitte in Pixel return ret
def detectshape(c): # initialize the shape name and approximate the contour shape = "unidentified" peri = cv2.arcLength(c, True) approx = cv2.approxPolyDP(c, 0.04 * peri, True) # if the shape is a triangle, it will have 3 vertices if len(approx) == 3: shape = "triangle" # if the shape has 4 vertices, it is either a square or # a rectangle elif len(approx) == 4: # compute the bounding box of the contour and use the # bounding box to compute the aspect ratio (x, y, w, h) = cv2.boundingRect(approx) ar = w / float(h) # a square will have an aspect ratio that is approximately # equal to one, otherwise, the shape is a rectangle shape = "square" if ar >= 0.95 and ar <= 1.05 else "rectangle" # if the shape is a pentagon, it will have 5 vertices elif len(approx) == 5: shape = "pentagon" # otherwise, we assume the shape is a circle else: shape = "circle" # return the name of the shape return shape
def image_input(path): problem_grid = np.zeros([9, 9]) img = cv2.imread(path) imgGry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) _, thrash = cv2.threshold(imgGry, 127, 255, cv2.CHAIN_APPROX_NONE) contours, _ = cv2.findContours(thrash, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) for contour in contours: approx = cv2.approxPolyDP(contour, 0.01 * cv2.arcLength(contour, True), True) perimeter = cv2.arcLength(contour, True) if perimeter > 900: x, y, w, h = cv2.boundingRect(approx) puzzle = img[y:y + h, x:x + w] # Return cropped image. cv2.drawContours(img, [approx], 0, (0, 143, 255), 1) return puzzle else: print('Return original image') return img return problem_grid
def to_counters(self, _img=None): # # 检测轮廓 边缘分割 _img = _img if _img is not None else self.img # # 灰度和二值 _gray = cv2.cvtColor(_img, cv2.COLOR_BGR2GRAY) _, _binary = cv2.threshold(_gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) # cv_show(_binary, "binary test") # # Canny边缘检测 # edges = cv2.Canny(_img, 50, 150, ) # cv_show(edges) # # 轮廓检测, 画出轮廓 _contours, _ = cv2.findContours(_binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) _draw_img = _img.copy() # # 计算轮廓的大小, 选定阈值 对轮廓进行选择 _greatest_contour_idx = np.argmax([cv2.contourArea(_contour) for _contour in _contours]) # # 求轮廓的外接矩形 _greatest_contour = _contours[_greatest_contour_idx] _x, _y, _w, _h = cv2.boundingRect(_greatest_contour) _ret = cv2.rectangle(_img, (_x, _y), (_x + _w, _y + _h), color=(0, 255, 255), thickness=1) # # 上下 _ret[0: _y, :] = (0, 0, 0) _ret[_y + _h: -1, :] = (0, 0, 0) # # 左右 _ret[:, 0: _x] = (0, 0, 0) _ret[:, _x + _w: -1] = (0, 0, 0) # _ret = cv2.drawContours(_draw_img, _contours, _greatest_contour_idx, (255, 0, 255), 2) cv_show(_ret)
def extract_text_chars(img, output_dir): """ img - image from which the individual chars are extracted output_dir - directory where the extracted lines should be saved """ gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) blur = cv2.medianBlur(gray, 7) thresh = cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 7, 11) kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 7)) dilate = cv2.dilate(thresh, kernel, iterations=1) cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if len(cnts) == 2: cnts = cnts[0] else: cnts = cnts[1] chars_path = os.path.join(output_dir, 'chars') if not os.path.exists(chars_path): os.makedirs(chars_path) for char_idx, character in enumerate(cnts, start=-len(cnts)): x, y, w, h = cv2.boundingRect(character) roi = img[y:y + h, x:x + w] filename = 'char' + str(char_idx) + '.jpg' save_img(chars_path, filename=filename, img=roi)
def crop_photo(image): rsz_img = cv2.resize(np.float32(image), None, fx=0.25, fy=0.25) # resize since the image may be huge # We get the resized version in a array npArrayIm = np.array(rsz_img) # We test if the image is already in 1D (grayscale) or still in 3D # We make sure to get a 1D grayscale image shapeLength = len(npArrayIm.shape) if shapeLength > 2: gray = cv2.cvtColor(rsz_img, cv2.COLOR_BGR2GRAY) # convert to grayscale else: gray = rsz_img # We are sure that we got a 1D grayscale image so we can crop it now # We use opencv threshold to get just the face of the person retval, thresh_gray = cv2.threshold(gray, thresh=100, maxval=255, type=cv2.THRESH_BINARY) # find where the face is and make a cropped region points = np.argwhere(thresh_gray< 200) # find where the pixels in the face of the person are points = np.fliplr(points) # store them in x,y coordinates instead of row,col indices x, y, w, h = cv2.boundingRect(points) # create a rectangle around those points x, y, w, h = x-10, y-10, w+20, h+20 # make the box a little bigger crop = gray[y:y+h, x:x+w] # create a cropped region of the gray image return image_show(crop, "croppedPhoto")
def detect_holes(grey_frame, original_frame, frame_copy): thresh = cv.adaptiveThreshold(grey_frame, 1, 0, 0, 61, 10) contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_NONE) for contour in contours: # area = cv.contourArea(contour) perimeter = cv.arcLength(contour, True) if len(contour) > 100 and 100 < perimeter < 300: # if len(contour) > 5 and 200 < area < 1000: x, y, w, h = cv.boundingRect(contour) img_c = frame_copy[y:y + h, x:x + w] img = cv.resize(img_c, IMAGE_SIZE) img_array = img_to_array(img) img_array = img_array.reshape( (1, ) + img_array.shape) # Converting into 4 dimension array interpreter.set_tensor(input_details[0]['index'], img_array) interpreter.invoke() predictions = interpreter.get_tensor(output_details[0]['index']) if predictions[0][0] > 0.9: cv.rectangle(original_frame, (x, y), (x + w, y + h), (0, 0, 255), 2) cv.imwrite( new_dir + '/' + str(time.time()) + str(random()) + '.jpg', img_c) return original_frame
def identifyChunks(blobs, padding=2): contours, hierarchy = cv2.findContours(blobs.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # create mask layer with black background mask = np.zeros(blobs.shape, np.uint8) for contour in range(len(contours)): (x, y, w, h) = cv2.boundingRect(contours[contour]) # mask around bounding rectangle mask[y:y + h, x:x + w] = 0 # white fill to bounding rectangle area cv2.drawContours(mask, contours, contour, (255, 255, 255), -1) # calculate ratio of non-black ratio = float(cv2.countNonZero(mask[y:y + h, x:x + w])) / (w * h) if ratio > 0.5 and w > 5 and h > 5: # cv2.rectangle(img, (x-padding, y-padding), (x+w+padding, y+h+padding), (0, 0, 255)) textExtract(img[y - 3:y + h + 3, x - 3:x + w + 3]) cv2.imwrite(path + "sample//result.jpg", img) return img
def draw_box(binary_image, init_image): # 產生等高線 _, contours, hierarchy = cv2.findContours(binary_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 建立除錯用影像 img_debug = init_image.copy() # 線條寬度 line_width = int(init_image.shape[1] / 255) # 以藍色線條畫出所有的等高線 # cv2.drawContours(img_debug, contours, -1, (255, 0, 0), line_width) # 找出面積最大的等高線區域 c = max(contours, key=cv2.contourArea) # 找出可以包住面積最大等高線區域的方框,並以綠色線條畫出來 x, y, w, h = cv2.boundingRect(c) outs = cv2.rectangle(img_debug, (x, y), (x + w, y + h), (0, 255, 0), line_width) cv2.imwrite('../images/Segmet_Images/box_Green.png', outs) # 嘗試在各種角度,以最小的方框包住面積最大的等高線區域,以紅色線條標示 rect = cv2.minAreaRect(c) box = cv2.boxPoints(rect) box = np.int0(box) Fin_image = cv2.drawContours(img_debug, [box], 0, (0, 0, 255), line_width) cv2.imwrite('../images/Segmet_Images/box_Rad.png', Fin_image)
def find_sudoku(image): # preprocessing gray_sudoku = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) blurred_sudoku = cv2.GaussianBlur(gray_sudoku, (7, 7), 0) thresh = cv2.adaptiveThreshold(blurred_sudoku, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) # find contours contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # get the sudoku contour sudoku_area = 0 sudoku_contour = contours[0] for cnt in contours: area = cv2.contourArea(cnt) x, y, w, h = cv2.boundingRect(cnt) if (0.7 < float(w) / h < 1.3 # aspect ratio and area > 150 * 150 # minimal area and area > sudoku_area # biggest area on screen and area > .5 * w * h): # fills bounding rect sudoku_area = area sudoku_contour = cnt perimeter = cv2.arcLength(sudoku_contour, True) # define the accuracy here epsilon = 0.05 * perimeter approx = cv2.approxPolyDP(sudoku_contour, epsilon, True) # if it is not a sudoku board, just return the frame without doing anything if len(approx) != 4: return None return sudoku_contour
def select_region(self, event): r_idx = self.region_list_box.curselection() if len(r_idx) == 0: self.current_reg_idx = None return self.current_reg_idx = r_idx[0] label = self.current_label.get() region = self.img_region_lut[self.current_img][label][r_idx[0]] self.clear_drawn_regions() if len(region) == 0: return for point in region: e = tk.Event() e.x, e.y = point self.draw_point(e, override_focus=True) min_x, min_y, reg_w, reg_h = cv2.boundingRect(region) min_x = min_x + (reg_w / 2.0) min_y = min_y + (reg_h / 2.0) c_h = self.canvas.winfo_height() / 2 c_w = self.canvas.winfo_width() / 2 self.canvas.xview_moveto((min_x - c_w) / self.image_dims[1]) self.canvas.yview_moveto((min_y - c_h) / self.image_dims[0])
def extract_text_lines(img, output_dir): """ img - image from which the text lines are extracted output_dir - directory where the extracted lines should be saved """ gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) blur = cv2.medianBlur(gray, 5) thresh = cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 5, 5) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (16, 2)) dilate = cv2.dilate(thresh, kernel, iterations=2) rotated, rot_dilated = find_text_angle(dilate, img) cnts = cv2.findContours(rot_dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if len(cnts) == 2: cnts = cnts[0] else: cnts = cnts[1] lines_path = os.path.join(output_dir, 'lines') if not os.path.exists(lines_path): os.makedirs(lines_path) for line_idx, line in enumerate(cnts, start=-len(cnts)): x, y, w, h = cv2.boundingRect(line) roi = rotated[y:y + h, x:x + w] filename = 'line' + str(line_idx) + '.jpg' save_img(lines_path, filename=filename, img=roi)
def linie_erkennen(dieser_frame, schwarze_maske, offset): yoffset = PIXEL_HOEHE - SLICE_HOEHE_FUER_SCHWARZ - offset - 1 roi_line = schwarze_maske[yoffset:yoffset + SLICE_HOEHE_FUER_SCHWARZ, 0:PIXEL_BREITE - 1] _, konturen, _ = cv2.findContours(roi_line, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cx = 0 cy = yoffset + SLICE_HOEHE_FUER_SCHWARZ / 2 cnt = 0 farbe = GRUEN linien = [] for kontur in konturen: x, y, w, h = cv2.boundingRect(kontur) if w > 50: if w >= PIXEL_BREITE - 50: farbe = ROT ist_kreuzung = True else: farbe = GELB ist_kreuzung = False cv2.rectangle(dieser_frame, (x, y + yoffset), (x + w, y + yoffset + h), farbe, 2) cx = cx + int(x + w / 2) cnt = cnt + 1 if ist_kreuzung: linien.append((True, cx - PIXEL_BREITE / 2)) else: linien.append((False, cx - PIXEL_BREITE / 2)) if cx is 0: cx = (PIXEL_BREITE - 1) / 2 else: cx = cx / cnt cv2.circle(dieser_frame, (int(cx), int(cy)), 5, farbe, -1) return linien
def main(argv): results = img_cmp(argv[1], argv[2]) score = results[0] diff = results[1] diff = (diff * 255).astype("uint8") print("Structural Similarity Index: {}".format(score)) thresh = cv2.threshold(diff, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1] cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = imutils.grab_contours(cnts) image_orig = cv2.imread(argv[1]) image_mod = cv2.imread(argv[2]) resized_orig = cv2.resize(image_orig, (300, 200)) resized_mod = cv2.resize(image_mod, (300, 200)) for c in cnts: (x, y, w, h) = cv2.boundingRect(c) cv2.rectangle(resized_orig, (x, y), (x + w, y + h), (0, 0, 255), 2) cv2.rectangle(resized_mod, (x, y), (x + w, y + h), (0, 0, 255), 2) cv2.imshow("Original", resized_orig) cv2.imshow("Modified", resized_mod) cv2.imshow("Diff", diff) #cv2.imshow("Thresh", thresh) cv2.waitKey(0) plt.show()
def captcha_character_detach(captcha_img_path, characters_save_path='./', captcha_len=4): captcha_img_basename = os.path.basename( captcha_img_path) # 从路径中提取带后缀文件名,如 '0415.png' captcha_text = os.path.splitext(captcha_img_basename)[0] # ['0415', 'png'] img_gray = cv.imread(captcha_img_path, cv.IMREAD_GRAYSCALE) # 灰度图读入 img_binary = genNeedImg(captcha_img_path, img_type='binary', binary_therhold=127, binary_reverse=True) # 直接调用genNeedImg生成二值图 contours, hierarchy = cv.findContours(img_binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) # 划分字符轮廓 # 由于直接划分的轮廓太多了(我换了字体后好像不会划分很多),这里考虑记录每个每个轮廓的数据,然后取 wxh (长x宽,即面积)的top4 boundings = [cv.boundingRect(contour) for contour in contours ] # 获取每个轮廓的信息,(x,y,width,height) x,y为轮廓最左上角坐标 boundings.sort(key=lambda tuple_x: tuple_x[2] * tuple_x[3], reverse=True) # lamdba传入的就是计算每个轮廓的面积,然后按面积大小降序排序 if len(boundings) < captcha_len: # 获取到的轮廓小于4,则说明没有把4个字符都区分开来 print('Bondings less then 4, captcha discarded!') return # 直接结束,丢弃这个验证码样本 ''' # 下面开始画矩形分割框,这部分其实用不到,只是为了调试看画的样子 # ----------------------------------------------------------------------------------------- temp_img = cv.imread(captcha_img_path, cv.IMREAD_UNCHANGED) # 以原始格式读入图片 temp_img = bgr2rgb(temp_img) # 通道转换 for bounding in boundings[:4]: # 取面积最大的前4个轮廓 x, y, width, height = bounding img_addBox = cv.rectangle(temp_img, (x,y), (x + width, y + height), (0, 255, 0), 1) plt.imshow(img_addBox, cmap='gray') # ------------------------------------------------------------------------------------------ ''' boundings_save = sorted(boundings[:captcha_len], key=lambda tuple_x: tuple_x[0] ) # 按轮廓的x坐标大小排序,tuple_x=(x,y,width,height) character_splited = [] for character_bounding, character_text in zip(boundings_save, captcha_text): x, y, width, height = character_bounding margin = 2 # 提取单个字符的时候,在获取的轮廓拓宽margin个像素,因为findContours()的轮廓可能很紧凑 character_img = img_gray[y - margin:y + height + margin, x - margin:x + width + margin] if not os.path.exists(characters_save_path): # 如果要保存的路径不存在就创建该路径目录 os.makedirs(characters_save_path) character_path = os.path.join(characters_save_path, '{}_0.png'.format(character_text)) i = 0 while True: i += 1 if os.path.exists(character_path): # 该字符已经有样本,则在正确标签后面加_i, i标记重复次数 character_path = os.path.join( characters_save_path, '{}_{}.png'.format(character_text, i)) else: # 不存在重名路径,则跳出 break cv.imwrite(character_path, character_img) character_splited.append(character_img) print('Character detached from captcha, character has been saved at {}'. format(characters_save_path)) return character_splited