def trainCompleteStatisticalModel(self, k_pixels, resolutionLevels, filter_settings, doLeaveOneOutTrainingSetTest=False, leaveOneOut=None): """ Performs leave-one-out validation of the training set, then trains a statistical model from the entire training set. """ if doLeaveOneOutTrainingSetTest: self.doLeaveOneOutTrainingSetValidation() if leaveOneOut is not None: self.completeDataHandler = DataHandler(leave_one_out=leaveOneOut) statisticalToothModels = self.trainModelFromCompleteTrainingSet() grayLevelMultiResModel = self.multiResTrainer.trainGrayLevelMultiResolutionModel( k_pixels, resolutionLevels, filter_settings) completeModel = CompleteStatisticalModel(statisticalToothModels, grayLevelMultiResModel) print("Statistical model trained!") return completeModel
def __init__(self): tk.Tk.__init__(self) self.title("CV Project") self.dataHandler = DataHandler(scale_radiographs_by=0.4) self.frameFactory = FrameFactory(self.dataHandler) self.statisticalModelTrainer = StatisticalModelTrainer() self.procrustes = Procrustes() self.radiographFrameContainer = RadiographFrameContainer( self, self.frameFactory) self.procrustesTeethSetImageContainer = None self.modelFittingContainer = None self.buttonContainer = ButtonContainer(self) self.buttonContainer.createImageNavigationButtons( self.radiographFrameContainer) self.buttonContainer.createFunctionButtons(self) self.manualModelPlacementContainer = None self.alignedTeeth = list() self.meanModels = list() self.k_pixels = [13, 7, 2, 2, 1] self.m_pixels = [25, 15, 4, 3, 2] self.resolutionLevels = 2 self.filter_settings = [(3, 3, 6), (3, 3, 6), (3, 3, 6), (1, 2, 6), (1, 2, 3)]
def performModelFitting(self): if self.manualModelPlacementContainer is not None: initialModelPositions = self.manualModelPlacementContainer.getChosenModelPositions( ) initialModelRotations = self.manualModelPlacementContainer.getChosenModelRotations( ) initialModelPositions *= 2.5 self.multiResActiveShapeModel = MultiResolutionActiveShapeModel( self.statisticalModel, resolutionLevels=self.resolutionLevels, m_pixels=self.m_pixels, k_pixels=self.k_pixels, filter_settings=self.filter_settings, initialPositions=initialModelPositions, initialRotations=initialModelRotations) radiograph = DataHandler().getRadiographs(deepCopy=True)[ self.manualModelPlacementContainer.getChosenRadiograph()] # Fit the first tooth to the radiograph fittedModels_Y = self.multiResActiveShapeModel.fitCompleteModel( radiograph) self.fittedModels = list() # allign fitted model to be drawn for model in fittedModels_Y: [X, Y] = model temp = self.procrustes.allignModelToData(Y, X)[1] self.fittedModels.append(temp) self.fittedModels = np.array(self.fittedModels) print("fittedModels" + str(np.array(self.fittedModels).shape)) radiograph.scaleImage(0.4) self.frameFactory.createFittingErrorPresentationImages( self.fittedModels, radiograph) self.modelFittingContainer = ModelFittingContainer( self, self.frameFactory, [self.fittedModels], radiograph) self.buttonContainer.createImageNavigationButtons( self.modelFittingContainer)
def doLeaveOneOutTrainingSetValidation(self): """ Performs a leave-one-out validation of the training set. If for any subset of the training set the error on the left out example is too big, the training set is considered insuficient. """ # Number of training examples n = len(self.completeDataHandler.getRadiographs(deepCopy=True)) for i in range(n): dataHandler = DataHandler(leave_one_out=i) statisticalModel = self.trainModel(dataHandler) print("Left out radiograph: " + str(i)) self.testTrainedModelOnLeftOutExample(dataHandler, statisticalModel)
def __init__(self): self.completeDataHandler = DataHandler() self.grayLevelToothModels = None
class MultiResolutionTrainer: def __init__(self): self.completeDataHandler = DataHandler() self.grayLevelToothModels = None def trainGrayLevelMultiResolutionModel(self, k_pixels, resolutionLevels, filter_settings): singleResolutionModels = list() for i in range(resolutionLevels): start_time = time.time() singleResModel = self.trainGrayLevelSingleResolutionModel(k_pixels[i], i, filter_settings[i]) singleResolutionModels.append(singleResModel) print("--- %s seconds ---" % (time.time() - start_time)) singleResolutionModels = np.array(singleResolutionModels) print(str(len(singleResolutionModels)) + " single resolution models created") return StatisticalGrayLevelMultiResModel(singleResolutionModels, resolutionLevels) def trainGrayLevelSingleResolutionModel(self, k_pixels, resolutionLevel, filter_settings): """ Learns the statistical gray-level models for all point on all teeth for a single resolution level """ g_all = self.trainGrayLevelModelForAllPointsAllExamples(k_pixels, resolutionLevel, filter_settings) print("g_all: " + str(g_all.shape)) grayLevelToothModels = self.trainGrayLevelToothModels(g_all, k_pixels, resolutionLevel) print(str(len(grayLevelToothModels)) + " Gray level tooth models created during training") return StatisticalGrayLevelSingleResModel(grayLevelToothModels, resolutionLevel) def trainGrayLevelToothModels(self, g_all, k_pixels, resolutionLevel): grayLevelToothModels = list() for i in range(8): grayLevelPointModels = list() for j in range(40): g_point = list() for k in range(14): g_point.append(g_all[k][i][j]) g_point = np.array(g_point) g_point_mean = np.mean(g_point, axis=0) g_point_cov = np.cov(g_point.T) grayLevelPointModels.append(StatisticalGrayLevelPointModel(g_point_mean, g_point_cov, k_pixels, i, j)) grayLevelPointModels = np.array(grayLevelPointModels) statisticalGrayLevelToothModel = StatisticalGrayLevelToothModel(grayLevelPointModels, i, resolutionLevel) grayLevelToothModels.append(statisticalGrayLevelToothModel) return np.array(grayLevelToothModels) def trainGrayLevelModelForAllPointsAllExamples(self, k, resolutionLevel, filter_settings): """ calcualtes the gray-level vectors for all point of all teeth in all provided examples. """ radiographs = self.completeDataHandler.getRadiographs(deepCopy=True) g_all = list() for radiograph in radiographs: # Scale image to current resolution level for i in range(resolutionLevel): radiograph.downScale() # Pre process image img = Filter.process_image(deepcopy(radiograph.getImage(deepCopy=True)), filter_settings[0], filter_settings[1], filter_settings[2]) derivate_img = Filter.laplacian(img) # derivate_img = Filter.histogramEql(Filter.process_image(deepcopy(img), filter_settings[0], filter_settings[1], filter_settings[2])) # derivate_img = Filter.process_image(deepcopy(derivate_img), median_kernel=3, bilateral_kernel=5) g_ex = self.trainGrayLevelModelForAllPointsOneExample(img, derivate_img, radiograph, k) g_all.append(g_ex) return np.array(g_all) def trainGrayLevelModelForAllPointsOneExample(self, img, derivate_img, radiograph, k): """ Calculate the grey-level vectors for all points of all teeth in one example. """ g_ex = list() teeth = radiograph.getTeeth() for tooth in teeth: points = tooth.getLandmarks() g_p = list() for i in range(len(points)): current_point = points[i] if i == 0: previous_point = points[len(points)-1] else: previous_point = points[i-1] if i == len(points)-1: next_point = points[0] else: next_point = points[i+1] g_p.append(self.trainGrayLevelModelForOnePointOneExample(img, derivate_img, current_point, previous_point, next_point, k)) g_ex.append(np.array(g_p)) return np.array(g_ex) def trainGrayLevelModelForOnePointOneExample(self, img, derivate_img, current_point, previous_point, next_point, k): """ calculates the grey-level vector of the pixels on the normal in the given point in the given example. """ sample,_,_ = Utils.getSampleFromImage(img, derivate_img, current_point, previous_point, next_point, k) return sample
class MainApp(tk.Tk): def __init__(self): tk.Tk.__init__(self) self.title("CV Project") self.dataHandler = DataHandler(scale_radiographs_by=0.4) self.frameFactory = FrameFactory(self.dataHandler) self.statisticalModelTrainer = StatisticalModelTrainer() self.procrustes = Procrustes() self.radiographFrameContainer = RadiographFrameContainer( self, self.frameFactory) self.procrustesTeethSetImageContainer = None self.modelFittingContainer = None self.buttonContainer = ButtonContainer(self) self.buttonContainer.createImageNavigationButtons( self.radiographFrameContainer) self.buttonContainer.createFunctionButtons(self) self.manualModelPlacementContainer = None self.alignedTeeth = list() self.meanModels = list() self.k_pixels = [13, 7, 2, 2, 1] self.m_pixels = [25, 15, 4, 3, 2] self.resolutionLevels = 2 self.filter_settings = [(3, 3, 6), (3, 3, 6), (3, 3, 6), (1, 2, 6), (1, 2, 3)] #self.filterTest() #self.createMeanModelImages = True def filterTest(self): radiograph = self.dataHandler.getRadiographs(deepCopy=True)[0] blurred_img = Filter.process_image(deepcopy(radiograph.getImage()), median_kernel=3, bilateral_kernel=10) cv2.imshow("BlurredImage", blurred_img) clahe = cv2.equalizeHist(blurred_img) cv2.imshow("Clahe", clahe) img_1 = Filter.laplacian(blurred_img) cv2.imshow("Img1", img_1) # radiograph.downScale() # blurred_img = Filter.process_image(deepcopy(radiograph.getImage()), median_kernel=3, bilateral_kernel=10) # img_2 = Filter.laplacian(deepcopy(blurred_img)) # height = img_1.shape[0] # width = img_1.shape[1] # img_2 = cv2.resize(img_1, (int(width*0.5), int(height*0.5))) # cv2.imshow("Img2", img_2) # radiograph.downScale() # blurred_img = Filter.process_image(deepcopy(radiograph.getImage()), median_kernel=3, bilateral_kernel=10) # img_3 = Filter.laplacian(deepcopy(blurred_img)) # height = img_2.shape[0] # width = img_2.shape[1] # img_3 = cv2.resize(img_2, (int(width*0.5), int(height*0.5))) # cv2.imshow("Img3", img_3) # radiograph.downScale() # blurred_img = Filter.process_image(deepcopy(radiograph.getImage()), median_kernel=3, bilateral_kernel=10) # img_4 = cv2.Canny(deepcopy(blurred_img), 15, 15) # cv2.imshow("Img4", img_4) # radiograph.downScale() # blurred_img = Filter.process_image(deepcopy(radiograph.getImage()), median_kernel=3, bilateral_kernel=10) # img_5 = cv2.Canny(deepcopy(blurred_img), 15, 15) # cv2.imshow("Img5", img_5) def trainCompleteStatisticalModel(self): self.statisticalModel = self.statisticalModelTrainer.trainCompleteStatisticalModel( self.k_pixels, self.resolutionLevels, self.filter_settings, leaveOneOut=0) # for i in range(8): # maxEig = self.statisticalModel.getToothModelByIndex(i).getEigenvalues()[0] # print("Tooth " + str(i) + " biggest eigenvalue: " + str(maxEig*10000)) # if(self.createMeanModelImages): # self.frameFactory.createMeanModelPresentationImages(self.statisticalModel) def performManualModelPositionInit(self): self.manualModelPlacementContainer = ManualModelPlacementContainer( self, self.frameFactory, self.statisticalModel.getAllToothModels(deepCopy=True)) self.buttonContainer.createImageNavigationButtons( self.manualModelPlacementContainer) def acceptModelPosition(self): self.manualModelPlacementContainer.nextMeanModel() def changeToothRotation(self, var): if self.manualModelPlacementContainer is not None: self.manualModelPlacementContainer.manualRotation(var) def performAutoModelPositionInit(self): return None def performModelFitting(self): if self.manualModelPlacementContainer is not None: initialModelPositions = self.manualModelPlacementContainer.getChosenModelPositions( ) initialModelRotations = self.manualModelPlacementContainer.getChosenModelRotations( ) initialModelPositions *= 2.5 self.multiResActiveShapeModel = MultiResolutionActiveShapeModel( self.statisticalModel, resolutionLevels=self.resolutionLevels, m_pixels=self.m_pixels, k_pixels=self.k_pixels, filter_settings=self.filter_settings, initialPositions=initialModelPositions, initialRotations=initialModelRotations) radiograph = DataHandler().getRadiographs(deepCopy=True)[ self.manualModelPlacementContainer.getChosenRadiograph()] # Fit the first tooth to the radiograph fittedModels_Y = self.multiResActiveShapeModel.fitCompleteModel( radiograph) self.fittedModels = list() # allign fitted model to be drawn for model in fittedModels_Y: [X, Y] = model temp = self.procrustes.allignModelToData(Y, X)[1] self.fittedModels.append(temp) self.fittedModels = np.array(self.fittedModels) print("fittedModels" + str(np.array(self.fittedModels).shape)) radiograph.scaleImage(0.4) self.frameFactory.createFittingErrorPresentationImages( self.fittedModels, radiograph) self.modelFittingContainer = ModelFittingContainer( self, self.frameFactory, [self.fittedModels], radiograph) self.buttonContainer.createImageNavigationButtons( self.modelFittingContainer)
def __init__(self): self.completeDataHandler = DataHandler() self.procrustes = Procrustes() self.pca = PCA() self.modelFitter = ModelFitter() self.multiResTrainer = MultiResolutionTrainer()
class StatisticalModelTrainer: def __init__(self): self.completeDataHandler = DataHandler() self.procrustes = Procrustes() self.pca = PCA() self.modelFitter = ModelFitter() self.multiResTrainer = MultiResolutionTrainer() def trainCompleteStatisticalModel(self, k_pixels, resolutionLevels, filter_settings, doLeaveOneOutTrainingSetTest=False, leaveOneOut=None): """ Performs leave-one-out validation of the training set, then trains a statistical model from the entire training set. """ if doLeaveOneOutTrainingSetTest: self.doLeaveOneOutTrainingSetValidation() if leaveOneOut is not None: self.completeDataHandler = DataHandler(leave_one_out=leaveOneOut) statisticalToothModels = self.trainModelFromCompleteTrainingSet() grayLevelMultiResModel = self.multiResTrainer.trainGrayLevelMultiResolutionModel( k_pixels, resolutionLevels, filter_settings) completeModel = CompleteStatisticalModel(statisticalToothModels, grayLevelMultiResModel) print("Statistical model trained!") return completeModel def trainModel(self, dataHandler): """ Trains a statistical model from the examples provided in the given dataHandler. """ alignedTrainingExamples = self.allignTrainingExamples(dataHandler) return self.perfromPCA(alignedTrainingExamples) def allignTrainingExamples(self, dataHandler): """ Alligns all training examples, grouped by the same tooth, using procrustes analysis. """ alignedTrainingExamples = list() for i in range(8): temp = dataHandler.getAllTeethAtIndex(i, deepCopy=True) alignedTrainingExamples.append( self.procrustes.performProcrustesAlignment(temp)) return alignedTrainingExamples def perfromPCA(self, alignedTrainingExamples): """ Performs PCA on the given training set, and returns the obtained statistical models. """ meanModels = list() for i in range(8): [mean, eigenvalues, eigenvectors ] = self.pca.do_pca_and_build_model(alignedTrainingExamples[i]) statisticalToothModel = StatisticalToothModel( mean, eigenvalues, eigenvectors) meanModels.append(statisticalToothModel) meanModels = np.array(meanModels) return meanModels def trainModelFromCompleteTrainingSet(self): """ Trains a statistical model from the complete training set. """ statisticalModel = self.trainModel(self.completeDataHandler) return statisticalModel def doLeaveOneOutTrainingSetValidation(self): """ Performs a leave-one-out validation of the training set. If for any subset of the training set the error on the left out example is too big, the training set is considered insuficient. """ # Number of training examples n = len(self.completeDataHandler.getRadiographs(deepCopy=True)) for i in range(n): dataHandler = DataHandler(leave_one_out=i) statisticalModel = self.trainModel(dataHandler) print("Left out radiograph: " + str(i)) self.testTrainedModelOnLeftOutExample(dataHandler, statisticalModel) def testTrainedModelOnLeftOutExample(self, dataHandler, statisticalModel): """ Test the learned model by fitting it to the train examples as well as to the left out exampele and compares the mean error on the training examples to the error on the left out example. """ training_radiographs = dataHandler.getRadiographs(deepCopy=True) leftOut_radiograph = dataHandler.getLeftOutRadiograph(deepCopy=True) total_error = 0 for radiograph in training_radiographs: error = self.fitModelToAnnotatedExampleAndMeasureError( radiograph, statisticalModel) total_error += error errorOnTrainingExamples = total_error / len(training_radiographs) errorOnLeftOutExample = self.fitModelToAnnotatedExampleAndMeasureError( leftOut_radiograph, statisticalModel) errorComparison = errorOnLeftOutExample / errorOnTrainingExamples if errorComparison > 3: print("Relative error on left out example = " + str(errorOnLeftOutExample)) print( "Error on test image is relativelly big (>3 times the mean error on the train images), " + "the training set might not be good enough") def fitModelToAnnotatedExampleAndMeasureError(self, radiograph, statisticalModel): """ Fits a model to an annotated example and measures the error. """ teeth = radiograph.getTeeth(deepCopy=True) total_error = 0 for i in range(8): tooth = deepcopy(teeth[i]) model = statisticalModel[i] # Fit the model to the radiograph fitted_model = self.modelFitter.fitModel(deepcopy(tooth), model) # align fitted model to examples alignedModel = self.procrustes.allignModelToData( deepcopy(tooth), fitted_model)[1] # Error is the measured as the norm of the difference of the two matrices error = (tooth.getLandmarks() - alignedModel.getLandmarks() ) / alignedModel.getLandmarks() error = np.linalg.norm(error) total_error += error return total_error