def create_profile(): lm = Landmarks('Data/Landmarks/original/landmarks1-1.txt') img = rg.load() img = rg.enhance(img[0]) grad_img = rg.togradient_sobel(img) profile = Profile(img, grad_img, lm, 30, 40) Plotter.plot_profile(grad_img, profile)
def build_grey_level_model(): lms = landmarks.load(2) images = rg.load() images = [rg.enhance(img) for img in images] gimages = [rg.togradient_sobel(img) for img in images] glm = GreyLevelModel() glm.build(images, gimages, lms, 10, 20) Plotter.plot_grey_level_model(glm, gimages)
def auto_init(): imgs = rg.load() for radiograph in range(0, 14): img = imgs[radiograph] X = [] for tooth in range(1, 9): model = IncisorModel.load(tooth) X.append(ai.init(model, img)) Plotter.plot_landmarks_on_image(X, img, show=False, save=True, title='Autoinit/%02d' % (radiograph,))
def build_database(path): """Interactively select ROIs on the dental radiographs for creating the appearance model used for the automatic initialization. Args: path (str): The location of the dental radiographs. """ images = rg.load(path+"/", indices=range(1, 31)) create_database(images)
def train_and_save(): # parameters k = 10 imgs = rg.load() for tooth in range(1, 9): lms = landmarks.load_mirrored(tooth) model = IncisorModel(tooth) model.train(lms, imgs, k) model.save()
def fit(radiograph_index, incisor_ind, fit_mode, k, m, out): """Find the region of an incisor, using the given parameters. Args: radiograph_index (int): The index of the dental radiograph to fit on. incisor_ind (int): The index of the incisor to fit. fit mode (AUTO|MANUAL): Wheter to ask for a manual initial fit, or try to find one automatically. k (int): Number of pixels either side of point to represent in grey model. m (int): Number of sample points either side of current point for search. out (str): The location to store the result. """ # leave-one-out train_indices = range(0, 14) train_indices.remove(radiograph_index-1) lms = landmarks.load_mirrored(incisor_ind) test_lm = lms[radiograph_index-1] train_lms = [lms[index] for index in train_indices] imgs = rg.load() test_img = imgs[radiograph_index-1] train_imgs = [imgs[index] for index in train_indices] # train model = IncisorModel(incisor_ind) model.train(train_lms, train_imgs, k) # fit X = model.estimate_fit(test_img, fit_mode) X = model.fit(X, test_img, m) # evaluate ## show live Plotter.plot_landmarks_on_image([test_lm, X], test_img, wait=False) ## save image with tooth circled img = test_img.copy() colors = [(255, 0, 0), (0, 255, 0)] for ind, lms in enumerate([test_lm, X]): points = lms.as_matrix() for i in range(len(points) - 1): cv2.line(img, (int(points[i, 0]), int(points[i, 1])), (int(points[i + 1, 0]), int(points[i + 1, 1])), colors[ind]) cv2.imwrite('%s/%02d-%d.png' % (out, radiograph_index, incisor_ind,), img) ## save tooth region segmented height, width, _ = test_img.shape image2 = np.zeros((height, width), np.int8) mask = np.array([X.points], dtype=np.int32) cv2.fillPoly(image2, [mask], 255) maskimage2 = cv2.inRange(image2, 1, 255) segmented = cv2.bitwise_and(test_img, test_img, mask=maskimage2) cv2.imwrite('%s/%02d-%d-segmented.png' % (out, radiograph_index, incisor_ind,), segmented)
def auto_init(): imgs = rg.load() for radiograph in range(0, 14): img = imgs[radiograph] X = [] for tooth in range(1, 9): model = IncisorModel.load(tooth) X.append(ai.init(model, img)) Plotter.plot_landmarks_on_image(X, img, show=False, save=True, title='Autoinit/%02d' % (radiograph, ))
def preprocess(path): """Apply an adaptive median filter to the radiographs at the given path and stores the results in a separate ``filtered`` folder. Args: path (str): The location of the dental radiographs. """ images = rg.load(path+"/") for ind, img in enumerate(images): print "Preprocessing radiographs ["+str(ind+1)+"/14]" img = rg.adaptive_median(img, 3, 5) cv2.imwrite("%s/filtered/%02d.tif" % (path, ind+1,), img)
def auto_fit(): # parameters m = 15 imgs = rg.load() for radiograph in range(0, 14): img = imgs[radiograph] Xs = [] for tooth in range(1, 9): model = IncisorModel.load(tooth) X = model.estimate_fit(img, MODE_FIT_AUTO) X = model.fit(X, img, m) Xs.append(X) Plotter.plot_landmarks_on_image(Xs, img, show=False, save=True, title='Autofit/%02d' % (radiograph,))
def auto_fit(): # parameters m = 15 imgs = rg.load() for radiograph in range(0, 14): img = imgs[radiograph] Xs = [] for tooth in range(1, 9): model = IncisorModel.load(tooth) X = model.estimate_fit(img, MODE_FIT_AUTO) X = model.fit(X, img, m) Xs.append(X) Plotter.plot_landmarks_on_image(Xs, img, show=False, save=True, title='Autofit/%02d' % (radiograph, ))
def run_experiment(mode): """Test the fit quality for all training examples. Args: mode: MODE_FIT_AUTO or MODE_FIT_MANUAL """ imgs = rg.load() for radiograph in range(0, 14): Xs = [] for tooth in range(1, 9): X = test_fit(radiograph, tooth, mode) Xs.append(X) img = imgs[radiograph] Plotter.plot_landmarks_on_image(Xs, img, show=False, save=True, title='Results/%02d' % (radiograph + 1, ))
def init(model, img, show=False): """Find an initial estimate for the model in the given image. Args: model (Landmarks): The shape which should be fitted. img: The dental radiograph on which the shape should be fitted. Returns: Landmarks: An initial estimate for the position of the model in the given image. """ # Are we fitting a lower or an upper incisor? tooth = model.incisor_nr is_upper = tooth < 5 if is_upper: # UPPER: Avg. height: 314.714285714, Avg. width: 381.380952381 width = 380 height = 315 else: # LOWER: Avg. height: 259.518518519, Avg. width: 281.518518519 width = 280 height = 260 # Create the appearance model for the four upper/lower teeth radiographs = rg.load() data = load_database(radiographs, is_upper, width, height) [_, evecs, mean] = pca(data, 5) # Visualize the appearance model # cv2.imshow('img',np.hstack( (mean.reshape(height,width), # normalize(evecs[:,0].reshape(height,width)), # normalize(evecs[:,1].reshape(height,width)), # normalize(evecs[:,2].reshape(height,width))) # ).astype(np.uint8)) # cv2.waitKey(0) # Find the jaw split jaw_split = split_jaws(img) # Find the region of the radiograph that matches best with the appearance model img = rg.enhance(img) [(a, b), (c, d)], _ = find_bbox(mean, evecs, img, width, height, is_upper, jaw_split, show=show) # Assume all teeth have more or less the same width ind = tooth if tooth < 5 else tooth - 4 bbox = [(a +(ind-1)*(c-a)/4, b), (a +(ind)*(c-a)/4, d)] center = np.mean(bbox, axis=0) # Plot a bounding box around the estimated region of the requested tooth if show: Plotter.plot_autoinit(img, bbox, 0, jaw_split, wait=True) # Position the mean shape of the requested incisor inside the bbox template = model.asm.mean_shape.scale_to_bbox(bbox).translate(center) # The position of the lower incisors is further improved using the grey-level model if is_upper: X = template else: X = template # X = fit_template(template, model, img) # Show the final result if show: Plotter.plot_landmarks_on_image([X], img) # Return the estimated position of the shape's landmark points return X
def AM_filter(): img = rg.load()[0] filt_img = rg.adaptive_median(img, 3, 5) cv2.imwrite('Data/Radiographs/filtered/01.tif', filt_img)
def init(model, img, show=False): """Find an initial estimate for the model in the given image. Args: model (Landmarks): The shape which should be fitted. img: The dental radiograph on which the shape should be fitted. Returns: Landmarks: An initial estimate for the position of the model in the given image. """ # Are we fitting a lower or an upper incisor? tooth = model.incisor_nr is_upper = tooth < 5 if is_upper: # UPPER: Avg. height: 314.714285714, Avg. width: 381.380952381 width = 380 height = 315 else: # LOWER: Avg. height: 259.518518519, Avg. width: 281.518518519 width = 280 height = 260 # Create the appearance model for the four upper/lower teeth radiographs = rg.load() data = load_database(radiographs, is_upper, width, height) [_, evecs, mean] = pca(data, 5) # Visualize the appearance model # cv2.imshow('img',np.hstack( (mean.reshape(height,width), # normalize(evecs[:,0].reshape(height,width)), # normalize(evecs[:,1].reshape(height,width)), # normalize(evecs[:,2].reshape(height,width))) # ).astype(np.uint8)) # cv2.waitKey(0) # Find the jaw split jaw_split = split_jaws(img) # Find the region of the radiograph that matches best with the appearance model img = rg.enhance(img) [(a, b), (c, d)], _ = find_bbox(mean, evecs, img, width, height, is_upper, jaw_split, show=show) # Assume all teeth have more or less the same width ind = tooth if tooth < 5 else tooth - 4 bbox = [(a + (ind - 1) * (c - a) / 4, b), (a + (ind) * (c - a) / 4, d)] center = np.mean(bbox, axis=0) # Plot a bounding box around the estimated region of the requested tooth if show: Plotter.plot_autoinit(img, bbox, 0, jaw_split, wait=True) # Position the mean shape of the requested incisor inside the bbox template = model.asm.mean_shape.scale_to_bbox(bbox).translate(center) # The position of the lower incisors is further improved using the grey-level model if is_upper: X = template else: X = template # X = fit_template(template, model, img) # Show the final result if show: Plotter.plot_landmarks_on_image([X], img) # Return the estimated position of the shape's landmark points return X
center = np.mean(bbox, axis=0) # Plot a bounding box around the estimated region of the requested tooth if show: Plotter.plot_autoinit(img, bbox, 0, jaw_split, wait=True) # Position the mean shape of the requested incisor inside the bbox template = model.asm.mean_shape.scale_to_bbox(bbox).translate(center) # The position of the lower incisors is further improved using the grey-level model if is_upper: X = template else: X = template # X = fit_template(template, model, img) # Show the final result if show: Plotter.plot_landmarks_on_image([X], img) # Return the estimated position of the shape's landmark points return X if __name__ == '__main__': # create_database() from incisor_model import IncisorModel model = IncisorModel.load(5) img = rg.load()[7] init(model, img, show=False)
def preprocess(): img = rg.load()[0] img = rg.enhance(img) grad = rg.togradient_sobel(img) lms = landmarks.load_all_incisors_of_example(1) Plotter.plot_landmarks_on_image(lms, grad)
""" def gaussian_function(sigma, u): return 1 / (math.sqrt(2 * math.pi) * sigma) * math.e**-(u**2 / (2 * sigma**2)) if filter_length is None: #determine the length of the filter filter_length = math.ceil(sigma * 5) #make the length odd filter_length = 2 * (int(filter_length) / 2) + 1 #make sure sigma is a float sigma = float(sigma) #create the filter result = np.asarray([ gaussian_function(sigma, u) for u in range(-(filter_length / 2), filter_length / 2 + 1, 1) ]) result = result / result.sum() #return the filter return result if __name__ == '__main__': # test it on all radiographs imgs = rg.load() for i in range(0, 14): split_jaws(imgs[i], 50, True)
def test_fit(test_index, incisor_ind, fit_mode): """Test the fit quality of one incisor using leave-one-out analysis. Args: test_index (int): The index of the radiograph to fit on. [0-13] incisor_ind (int): The index of the incisor to fit. [1-8] fit_mode: MODE_FIT_AUTO or MODE_FIT_MANUAL Returns: Landmarks: The fitted model. """ # parameters k = 10 m = 15 # leave-one-out train_indices = range(0, 14) train_indices.remove(test_index) lms = landmarks.load_mirrored(incisor_ind) test_lm = lms[test_index] train_lms = [lms[index] for index in train_indices] imgs = rg.load() test_img = imgs[test_index] train_imgs = [imgs[index] for index in train_indices] # train model = IncisorModel(incisor_ind) model.train(train_lms, train_imgs, k) # test X = model.estimate_fit(test_img, fit_mode) X = model.fit(X, test_img, m) # evaluate Plotter.plot_landmarks_on_image([test_lm, X], test_img, wait=False) fit = fit_quality(test_lm, X) # save result ## landmark annotated img = test_img.copy() colors = [(255, 0, 0), (0, 255, 0)] for ind, lms in enumerate([test_lm, X]): points = lms.as_matrix() for i in range(len(points) - 1): cv2.line(img, (int(points[i, 0]), int(points[i, 1])), (int(points[i + 1, 0]), int(points[i + 1, 1])), colors[ind]) cv2.imwrite('Plot/Results/%02d-%d.png' % ( test_index + 1, incisor_ind, ), img) ## tooth region segmented height, width, _ = test_img.shape image2 = np.zeros((height, width), np.int8) mask = np.array([X.points], dtype=np.int32) cv2.fillPoly(image2, [mask], 255) maskimage2 = cv2.inRange(image2, 1, 255) out = cv2.bitwise_and(test_img, test_img, mask=maskimage2) cv2.imwrite( 'Plot/Results/Segmentations/%02d-%d.png' % ( test_index + 1, incisor_ind - 1, ), out) truth = cv2.imread( 'Data/Segmentations/%02d-%d.png' % ( test_index + 1, incisor_ind - 1, ), 0) (_, truth) = cv2.threshold(truth, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) fit = cv2.imread( 'Plot/Results/Segmentations/%02d-%d.png' % ( test_index + 1, incisor_ind - 1, ), 0) (_, fit) = cv2.threshold(fit, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) fit2 = fit_quality2(truth, fit) ## fit quality results = np.loadtxt('experiment_results.csv', delimiter=',') results[test_index, incisor_ind - 1] = fit2 np.savetxt('experiment_results.csv', results, fmt='%10.2f', delimiter=',') return X
# Plot a bounding box around the estimated region of the requested tooth if show: Plotter.plot_autoinit(img, bbox, 0, jaw_split, wait=True) # Position the mean shape of the requested incisor inside the bbox template = model.asm.mean_shape.scale_to_bbox(bbox).translate(center) # The position of the lower incisors is further improved using the grey-level model if is_upper: X = template else: X = template # X = fit_template(template, model, img) # Show the final result if show: Plotter.plot_landmarks_on_image([X], img) # Return the estimated position of the shape's landmark points return X if __name__ == '__main__': # create_database() from incisor_model import IncisorModel model = IncisorModel.load(5) img = rg.load()[7] init(model, img, show=False)
A 1-D numpy array of odd length, containing the symmetric, discrete approximation of a Gaussian with sigma Summation of the array-values must be equal to one. """ def gaussian_function(sigma, u): return 1/(math.sqrt(2*math.pi)*sigma)*math.e**-(u**2/(2*sigma**2)) if filter_length is None: #determine the length of the filter filter_length = math.ceil(sigma*5) #make the length odd filter_length = 2*(int(filter_length)/2) + 1 #make sure sigma is a float sigma = float(sigma) #create the filter result = np.asarray([gaussian_function(sigma, u) for u in range(-(filter_length/2), filter_length/2 + 1, 1)]) result = result / result.sum() #return the filter return result if __name__ == '__main__': # test it on all radiographs imgs = rg.load() for i in range(0, 14): split_jaws(imgs[i], 50, True)