Download segmentation/sam_guide.py from GoodBoy9/full: direct link, hf CLI and curl.
- Browser
- Download file 5.55 kB
-
https://huggingface.co/GoodBoy9/full/resolve/main/segmentation/sam_guide.py
- Command line
-
hf download hf://GoodBoy9/full/segmentation/sam_guide.py
-
curl -L -o sam_guide.py https://huggingface.co/GoodBoy9/full/resolve/main/segmentation/sam_guide.py
5.55 kB
| import cv2, os, json | |
| import numpy as np | |
| from math import atan2, cos, sin, sqrt, pi | |
| from sklearn.cluster import DBSCAN | |
| from sklearn.preprocessing import StandardScaler | |
| from sklearn.cluster import OPTICS, cluster_optics_dbscan | |
| from tqdm import tqdm | |
| from glob import glob | |
| def nms(boxes, thresh): | |
| if len(boxes) == 0: | |
| return [] | |
| pick = [] | |
| x1, y1, x2, y2 = boxes[:, 0], boxes[:, 1], boxes[:, 2], boxes[:, 3] | |
| area = (x2 - x1 + 1) * (y2 - y1 + 1) | |
| idxs = np.argsort(y2) | |
| while len(idxs) > 0: | |
| last = len(idxs) - 1 | |
| i = idxs[last] | |
| pick.append(i) | |
| xx1 = np.maximum(x1[i], x1[idxs[:last]]) | |
| yy1 = np.maximum(y1[i], y1[idxs[:last]]) | |
| xx2 = np.minimum(x2[i], x2[idxs[:last]]) | |
| yy2 = np.minimum(y2[i], y2[idxs[:last]]) | |
| w = np.maximum(0, xx2 - xx1 + 1) | |
| h = np.maximum(0, yy2 - yy1 + 1) | |
| overlap = (w * h) / area[idxs[:last]] | |
| idxs = np.delete(idxs, np.concatenate(([last], np.where(overlap > thresh)[0]))) | |
| return boxes[pick] | |
| def find_pts_on_line(og, slope, d): | |
| cx, cy = og | |
| x1 = float(cx - d / ((1 + slope**2)**0.5)) | |
| y1 = float(cy - slope * cx + x1 * slope) | |
| return (x1, y1) | |
| def cluster(img_path, im, save_dir): | |
| img = cv2.imread(img_path) | |
| imgray = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE) | |
| ret, binary_map = cv2.threshold(imgray, 127, 255, 0) | |
| nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats(binary_map, None, None, None, 8, cv2.CV_32S) | |
| areas = stats[1:, cv2.CC_STAT_AREA] | |
| result = np.zeros((labels.shape), np.uint8) | |
| for i in range(0, nlabels - 1): | |
| if areas[i] >= 250: | |
| result[labels == i + 1] = 255 | |
| re_copy = result.copy() | |
| edgeimg = cv2.Canny(result, 10, 150) | |
| size = np.size(result) | |
| skel = np.zeros(result.shape, np.uint8) | |
| element = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3)) | |
| while True: | |
| open_ = cv2.morphologyEx(result, cv2.MORPH_OPEN, element) | |
| temp = cv2.subtract(result, open_) | |
| eroded = cv2.erode(result, element) | |
| skel = cv2.bitwise_or(skel, temp) | |
| result = eroded.copy() | |
| if cv2.countNonZero(result) == 0: | |
| break | |
| nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats(skel, None, None, None, 8, cv2.CV_32S) | |
| areas = stats[1:, cv2.CC_STAT_AREA] | |
| skel = np.zeros((labels.shape), np.uint8) | |
| for i in range(0, nlabels - 1): | |
| if areas[i] >= 2: | |
| skel[labels == i + 1] = 255 | |
| # Lưu riêng cho mỗi ảnh | |
| base_name = os.path.splitext(im)[0] | |
| os.makedirs(save_dir, exist_ok=True) | |
| cv2.imwrite(os.path.join(save_dir, f"Skeleton_{base_name}.png"), skel) | |
| combined_img = cv2.addWeighted(skel, 1, edgeimg, 1, 0) | |
| cv2.imwrite(os.path.join(save_dir, f"SkeletonContour_{base_name}.png"), combined_img) | |
| filter_size = (10, 10) | |
| white_pixels = np.where(skel == 255) | |
| x_coords, y_coords = white_pixels[1], white_pixels[0] | |
| x1 = x_coords - filter_size[0] // 2 | |
| y1 = y_coords - filter_size[1] // 2 | |
| x2 = x_coords + filter_size[0] // 2 | |
| y2 = y_coords + filter_size[1] // 2 | |
| white_regions = np.column_stack((x1, y1, x2, y2)) | |
| white_regions = nms(white_regions, thresh=0.1) | |
| skeleton_image = cv2.cvtColor(skel.copy(), cv2.COLOR_GRAY2BGR) | |
| filtered_image = cv2.cvtColor(re_copy.copy(), cv2.COLOR_GRAY2BGR) | |
| center_points, directions = [], [] | |
| def get_direction2(bbox_pixels): | |
| nonzero_indices = np.column_stack(np.nonzero(bbox_pixels)) | |
| nonzero_indices = np.float32(nonzero_indices) | |
| if len(nonzero_indices) >= 2: | |
| mean, eigenvectors = cv2.PCACompute(nonzero_indices, mean=None) | |
| cntr = ((mean[0, 1]), (mean[0, 0])) | |
| return eigenvectors[0], cntr | |
| else: | |
| return (0, 0), (0, 0) | |
| for coor in white_regions: | |
| x1, y1, x2, y2 = coor | |
| bbox_pixels = skel[int(y1):int(y2), int(x1):int(x2)] | |
| direction, mean = get_direction2(bbox_pixels) | |
| directions.append(direction) | |
| center_points.append((mean[0] + x1, mean[1] + y1)) | |
| cv2.rectangle(skeleton_image, (int(x1), int(y1)), (int(x2), int(y2)), (255, 255, 255), 1) | |
| cv2.circle(skeleton_image, (int(mean[0] + x1), int(mean[1] + y1)), 1, (255, 0, 0), -1) | |
| cv2.imwrite(os.path.join(save_dir, f"Result_{base_name}.png"), skeleton_image) | |
| pts_group, bbox_group = [], [] | |
| for idx, pts in enumerate(center_points): | |
| if 640 > pts[0] > 0 and 480 > pts[1] > 0: | |
| pts_group.append([int(pts[0]), int(pts[1])]) | |
| x1, y1, x2, y2 = white_regions[idx] | |
| bbox_group.append([int(x1), int(y1), int(x2), int(y2)]) | |
| return pts_group, bbox_group | |
| mask_dir = "datasets/seg_train" | |
| save_json_dir = "datasets" | |
| save_img_dir = os.path.join(save_json_dir, "output") | |
| patterns = ['*.png', '*.jpg', '*.jpeg', '*.PNG', '*.JPG', '*.JPEG'] | |
| files = [] | |
| for p in patterns: | |
| files.extend(glob(os.path.join(mask_dir, p))) | |
| files = sorted(set(files)) | |
| print(f"Found {len(files)} files in {mask_dir}") | |
| file_dict = {} | |
| bbox_dict = {} | |
| for filepath in tqdm(files): | |
| filename = os.path.basename(filepath) | |
| pts, bbox = cluster(filepath, filename, save_img_dir) | |
| if len(pts) != 0: | |
| file_dict[filename] = pts | |
| bbox_dict[filename] = bbox | |
| with open(os.path.join(save_json_dir, 'train_seg_points.json'), 'w') as json_file: | |
| json.dump(file_dict, json_file) | |
| with open(os.path.join(save_json_dir, 'train_bbox_points.json'), 'w') as json_file: | |
| json.dump(bbox_dict, json_file) | |