def detect_markers(img, area_thresh=100): """ This is the main function for detecting markers in an image. Input: img: a color or grayscale image that may or may not contain a marker. Output: a list of found markers. If no markers are found, then it is an empty list. """ #cv2.namedWindow('watcher', cv2.WINDOW_NORMAL) if len(img.shape) > 2: img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) gray = img.copy() width, height = img.shape img = cv2.Canny(img, 100, 255) #M = np.ones((2, 2), np.uint8) #img = cv2.dilate(img, M, iterations=1) contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2:] # We only keep the long enough contours min_contour_length = width * height / area_thresh markers_list = [] for contour in contours: rect = cv2.minAreaRect(contour) if rect[1][0] * rect[1][1] <= min_contour_length: continue box = cv2.boxPoints(rect) box = np.int0(box) warped_gray = four_point_transform(gray, box) umbral = 120 _, warped_bin = cv2.threshold(warped_gray, umbral, 255, cv2.THRESH_BINARY) marker = cv2.resize(warped_bin, (7, 7), interpolation=cv2.INTER_LINEAR) #cv2.imshow('watcher', marker) #cv2.waitKey(0) marker[marker < 255] = 0 marker[marker == 255] = 1 try: marker = validate_and_turn(marker) hamming_code = extract_hamming_code(marker) marker_id = int(decode(hamming_code), 2) markers_list.append(HammingMarker(id=marker_id, contours=box)) except ValueError: continue return markers_list
def detect_markers_integrated(img, contours, area_thresh=100): """ This is the main function for detecting markers in an image. Input: img: a color or grayscale image that may or may not contain a marker. Output: a list of found markers. If no markers are found, then it is an empty list. """ if len(img.shape) > 2: gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) else: gray = img.copy() width, height = gray.shape # We only keep the long enough contours min_contour_length = width * height / area_thresh markers_list = [] new_contours = [] for contour in contours: rect = cv2.minAreaRect(contour) if rect[1][0] * rect[1][1] <= min_contour_length: new_contours.append(contour) continue box = cv2.boxPoints(rect) box = np.int0(box) if np.min(box) < 0 or np.max(box[:, 0]) > gray.shape[1] or np.max( box[:, 1]) > gray.shape[0]: new_contours.append(contour) continue warped_gray = four_point_transform(gray, box) umbral = 110 _, warped_bin = cv2.threshold(warped_gray, umbral, 255, cv2.THRESH_BINARY) marker = cv2.resize(warped_bin, (7, 7), interpolation=cv2.INTER_LINEAR) marker[marker < 255] = 0 marker[marker == 255] = 1 try: marker = validate_and_turn(marker) hamming_code = extract_hamming_code(marker) marker_id = int(decode(hamming_code), 2) markers_list.append(HammingMarker(id=marker_id, contours=box)) except ValueError: new_contours.append(contour) continue return [markers_list, new_contours]
def detect_markers(img): width, height, _ = img.shape gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) edges = cv2.Canny(gray, 10, 100) contours, hierarchy = cv2.findContours(edges.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)[-2:] # We only keep the long enough contours min_contour_length = min(width, height) / 50 contours = [ contour for contour in contours if len(contour) > min_contour_length ] warped_size = 49 canonical_marker_coords = array( ((0, 0), (warped_size - 1, 0), (warped_size - 1, warped_size - 1), (0, warped_size - 1)), dtype='float32') markers_list = [] for contour in contours: approx_curve = cv2.approxPolyDP(contour, len(contour) * 0.01, True) if not (len(approx_curve) == 4 and cv2.isContourConvex(approx_curve)): continue sorted_curve = array(cv2.convexHull(approx_curve, clockwise=False), dtype='float32') persp_transf = cv2.getPerspectiveTransform(sorted_curve, canonical_marker_coords) warped_img = cv2.warpPerspective(img, persp_transf, (warped_size, warped_size)) warped_gray = cv2.cvtColor(warped_img, cv2.COLOR_BGR2GRAY) _, warped_bin = cv2.threshold(warped_gray, 127, 255, cv2.THRESH_BINARY) marker = warped_bin.reshape([ MARKER_SIZE, warped_size // MARKER_SIZE, MARKER_SIZE, warped_size // MARKER_SIZE ]) marker = marker.mean(axis=3).mean(axis=1) marker[marker < 127] = 0 marker[marker >= 127] = 1 try: marker = validate_and_turn(marker) hamming_code = extract_hamming_code(marker) marker_id = int(decode(hamming_code), 2) markers_list.append( HammingMarker(id=marker_id, contours=approx_curve)) except ValueError: continue return markers_list
def detect_markers(img): """ This is the main function for detecting markers in an image. Input: img: a color or grayscale image that may or may not contain a marker. Output: a list of found markers. If no markers are found, then it is an empty list. """ if len(img.shape) > 2: width, height, _ = img.shape gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) else: width, height = img.shape gray = img edges = cv2.Canny(gray, 10, 100) contours, hierarchy = cv2.findContours(edges.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)[-2:] # We only keep the long enough contours min_contour_length = min(width, height) / 50 contours = [ contour for contour in contours if len(contour) > min_contour_length ] warped_size = 49 canonical_marker_coords = array( ((0, 0), (warped_size - 1, 0), (warped_size - 1, warped_size - 1), (0, warped_size - 1)), dtype='float32') markers_list = [] for contour in contours: approx_curve = cv2.approxPolyDP(contour, len(contour) * 0.01, True) if not (len(approx_curve) == 4 and cv2.isContourConvex(approx_curve)): continue sorted_curve = array(cv2.convexHull(approx_curve, clockwise=False), dtype='float32') persp_transf = cv2.getPerspectiveTransform(sorted_curve, canonical_marker_coords) warped_img = cv2.warpPerspective(img, persp_transf, (warped_size, warped_size)) # do i really need to convert twice? if len(warped_img.shape) > 2: warped_gray = cv2.cvtColor(warped_img, cv2.COLOR_BGR2GRAY) else: warped_gray = warped_img _, warped_bin = cv2.threshold(warped_gray, 127, 255, cv2.THRESH_BINARY) marker = warped_bin.reshape([ MARKER_SIZE, warped_size // MARKER_SIZE, MARKER_SIZE, warped_size // MARKER_SIZE ]) marker = marker.mean(axis=3).mean(axis=1) marker[marker < 127] = 0 marker[marker >= 127] = 1 global marker_id try: marker = validate_and_turn(marker) hamming_code = extract_hamming_code(marker) marker_id = int(decode(hamming_code), 2) markers_list.append( HammingMarker(id=marker_id, contours=approx_curve)) except ValueError: continue return markers_list