示例#1
0
def mark_results(img,
                 PS,
                 color_lines=np.array(
                     [np.array([0, 0, 255]),
                      np.array([0, 255, 0])]),
                 color_init=np.array([0, 255, 255]),
                 color_mid=np.array([255, 0, 255]),
                 color_end=np.array([255, 255, 0])):
    for p in range(PS.shape[0]):
        pxs, pys = mu.extract_coordinates(PS[p, :])
        for k in range(c.get_nb_landmarks()):
            px = int(pxs[k])
            py = int(pys[k])
            if (k == c.get_nb_landmarks() - 1):
                px_succ = int(pxs[0])
                py_succ = int(pys[0])
            else:
                px_succ = int(pxs[(k + 1)])
                py_succ = int(pys[(k + 1)])
            cv2.line(img, (px, py), (px_succ, py_succ), color_lines[p])

    for p in range(PS.shape[0]):
        pxs, pys = mu.extract_coordinates(PS[p, :])
        for k in range(c.get_nb_landmarks()):
            px = int(pxs[k])
            py = int(pys[k])
            if (k == 0):
                img[py, px] = color_init
            elif (k == c.get_nb_landmarks() - 1):
                img[py, px] = color_end
            else:
                img[py, px] = color_mid
    return img
def create_G(img, k, xs, ys, offsetX=0, offsetY=0):
    '''
    Sample along the profile normal and profile tangent k pixels either side for
    each of the given model points (xs[i], ys[i]) in the given image to create
    the matrix G, which contains for each landmark a normalized sample.
    @param img:          the image
    @param k:            the number of pixels to sample either side for each of the
                         given model points (xs[i], ys[i]) along the profile normal
    @param i:            the index of the model point
    @param xs:           x positions of the model points in the image
    @param ys:           y positions of the model points in the image
    @param offsetX:      the possible offset in x direction 
                         (used when working with cropped images and non-cropped xs & ys)
    @param offsetY:      the possible offset in y direction
                         (used when working with cropped images and non-cropped xs & ys)
    @return The matrix GN, which contains for each landmark a normalized sample 
            (sampled along the profile normal through the landmarks).
            The matrix GT, which contains for each landmark a normalized sample 
            (sampled along the profile tangent through the landmarks).
    '''
    GN = np.zeros((c.get_nb_landmarks(), 2 * k + 1))
    GT = np.zeros((c.get_nb_landmarks(), 2 * k + 1))
    for i in range(c.get_nb_landmarks()):
        x = xs[i] - offsetX
        y = ys[i] - offsetY
        tx, ty, nx, ny = create_ricos(img, i, xs, ys)
        GN[i, :] = normalize_Gi(create_Gi(img, k, x, y, nx, ny))
        GT[i, :] = normalize_Gi(create_Gi(img, k, x, y, tx, ty))
    return GN, GT
示例#3
0
def create_landmarks_and_models_images(color_init=np.array([0,255,255]), color_mid=np.array([255,0,255]), color_end=np.array([255,255,0]), color_line=np.array([0,0,255]), color_model_line=np.array([255,0,0]), method=''):
    '''
    Stores all the preprocessed images corresponding to the given method with the landmarks
    of the training samples and models (transformed to the image coordinate system) marked.
    @param color_init:  the BGR color for the first landmark 
    @param color_mid:   the BGR color for all landmarks except the first and last landmark
    @param color_end:   the BGR color for the last landmark
    @param color_line:  the BGR color for the line between two consecutive landmarks of the training samples
    @param color_model_line:    the BGR color for the line between two consecutive landmarks of the models
    @param method:      the method used for preproccesing
    '''
    for i in c.get_trainingSamples_range():
        fname = c.get_fname_vis_pre(i, method)
        img = cv2.imread(fname)
        for j in range(c.get_nb_teeth()):
            xs, ys = mu.extract_coordinates(XS[j,(i-1),:])
            mxs, mys = mu.extract_coordinates(mu.full_align_with(MS[j], XS[j,(i-1),:]))
            
            for k in range(c.get_nb_landmarks()):
                x = int(xs[k] - offsetX)
                y = int(ys[k] - offsetY)
                mx = int(mxs[k] - offsetX)
                my = int(mys[k] - offsetY)
                if (k == c.get_nb_landmarks()-1):
                    x_succ = int(xs[0] - offsetX)
                    y_succ = int(ys[0] - offsetY)
                    mx_succ = int(mxs[0] - offsetX)
                    my_succ = int(mys[0] - offsetY)
                else:
                    x_succ = int(xs[(k+1)] - offsetX)
                    y_succ = int(ys[(k+1)] - offsetY)
                    mx_succ = int(mxs[(k+1)] - offsetX)
                    my_succ = int(mys[(k+1)] - offsetY)
                cv2.line(img, (x,y), (x_succ,y_succ), color_line)
                cv2.line(img, (mx,my), (mx_succ,my_succ), color_model_line)
          
            for k in range(c.get_nb_landmarks()):
                x = int(xs[k] - offsetX)
                y = int(ys[k] - offsetY)
                mx = int(mxs[k] - offsetX)
                my = int(mys[k] - offsetY)
                if (k == 0):
                    img[y,x] = color_init
                    img[my,mx] = color_init
                elif (k == c.get_nb_landmarks()-1):
                    img[y,x] = color_end
                    img[my,mx] = color_end
                else:
                    img[y,x] = color_mid
                    img[my,mx] = color_mid
                
            fname = c.get_fname_vis_ff_landmarks_and_models(i, method)
            cv2.imwrite(fname, img) 
示例#4
0
def create_profile_normals_images(k=5, color_init=np.array([0,255,255]), color_mid=np.array([255,0,255]), color_end=np.array([255,255,0]), color_line=np.array([255,0,0]), color_profile_point=np.array([0,255,0]), method=''):
    '''
    Stores all the preprocessed images corresponding to the given method with the landmarks
    of the models (transformed to the image coordinate system) and the points along the profile
    normals marked.
    @param k:                       the number of profile points along either side
                                    of the profile normal and profile tangent
    @param color_init:              the BGR color for the first landmark 
    @param color_mid:               the BGR color for all landmarks except the first and last landmark
    @param color_end:               the BGR color for the last landmark
    @param color_line:              the BGR color for the line between two consecutive landmarks
    @param color_profile_point:     the BGR color for the profile points
    @param method:                  the method used for preproccesing
    '''
    for i in c.get_trainingSamples_range():
        fname = c.get_fname_vis_pre(i, method)
        img = cv2.imread(fname)
        for j in range(c.get_nb_teeth()):
            xs, ys = mu.extract_coordinates(mu.full_align_with(MS[j], XS[j,(i-1),:]))
            
            for h in range(c.get_nb_landmarks()):
                x = int(xs[h] - offsetX)
                y = int(ys[h] - offsetY)
                if (h == c.get_nb_landmarks()-1):
                    x_succ = int(xs[0] - offsetX)
                    y_succ = int(ys[0] - offsetY)
                else:
                    x_succ = int(xs[(h+1)] - offsetX)
                    y_succ = int(ys[(h+1)] - offsetY)
                cv2.line(img, (x,y), (x_succ,y_succ), color_line)
          
            for h in range(c.get_nb_landmarks()):
                x = int(xs[h] - offsetX)
                y = int(ys[h] - offsetY)
                tx, ty, nx, ny = ff.create_ricos(img, h, xs, ys)
                for n in range(-k, k+1):
                    kx = round(x + n * nx)
                    ky = round(y + n * ny)
                    img[ky, kx] = color_profile_point
                for t in range(-k, k+1):
                    kx = round(x + t * tx)
                    ky = round(y + t * ty)
                    img[ky, kx] = color_profile_point
                
                if (h == 0):
                    img[y,x] = color_init
                elif (h == c.get_nb_landmarks()-1):
                    img[y,x] = color_end
                else:
                    img[y,x] = color_mid
                
            fname = c.get_fname_vis_ff_profile_normals(i, method)
            cv2.imwrite(fname, img) 
示例#5
0
def classify_positives(method=''):
    XS = l.create_full_XS()
    
    for s in c.get_trainingSamples_range():
        trainingSamples = c.get_trainingSamples_range()
        trainingSamples.remove(s)
        try:
            info_name_upper = c.get_dir_prefix() + 'data/Visualizations/Classified Samples/info' + method + str(s) + '-u' + '.txt' 
            info_name_lower = c.get_dir_prefix() + 'data/Visualizations/Classified Samples/info' + method + str(s) + '-l' + '.txt' 

            info_file_upper = open(info_name_upper, "w")
            info_file_lower = open(info_name_lower, "w")
            
            for i in trainingSamples:
                
                s = ''    
                if (i < 10):
                    s = '0'
                img_name = s + str(i) + '.png'
                
                min_y = min_x = float("inf")
                max_y = max_x = 0

                for j in range(0, c.get_nb_teeth()/2):
                    x_coords, y_coords = mu.extract_coordinates(XS[j, i-1, :])
                    for k in range(c.get_nb_landmarks()):
                        if x_coords[k] < min_x: min_x = x_coords[k]
                        if x_coords[k] > max_x: max_x = x_coords[k]
                        if y_coords[k] < min_y: min_y = y_coords[k]
                        if y_coords[k] > max_y: max_y = y_coords[k]
                
                line = 'rawdata/' + method + img_name + ' 1 ' + str(int(min_x - fu.offsetX)) + ' ' + str(int(min_y - fu.offsetY)) + ' ' + str(int(max_x - min_x)) + ' ' + str(int(max_y - min_y)) + '\n' 
                info_file_upper.write(line)
                
                min_y = min_x = float("inf")
                max_y = max_x = 0
                
                for j in range(c.get_nb_teeth()/2, c.get_nb_teeth()):
                    x_coords, y_coords = mu.extract_coordinates(XS[j, i-1, :])
                    for k in range(c.get_nb_landmarks()):
                        if x_coords[k] < min_x: min_x = x_coords[k]
                        if x_coords[k] > max_x: max_x = x_coords[k]
                        if y_coords[k] < min_y: min_y = y_coords[k]
                        if y_coords[k] > max_y: max_y = y_coords[k] 
                
                line = 'rawdata/' + method + img_name + ' 1 ' + str(int(min_x - fu.offsetX)) + ' ' + str(int(min_y - fu.offsetY)) + ' ' + str(int(max_x - min_x)) + ' ' + str(int(max_y - min_y)) + '\n' 
                info_file_lower.write(line) 

        finally:
            info_file_upper.close()
            info_file_lower.close()
示例#6
0
def draw_landmark(event, x, y, flags, param):
    if (event == cv2.EVENT_LBUTTONDOWN and count < c.get_nb_landmarks()):
        global img, count, landmarks
        landmarks[(2 * count)] = float(x)
        landmarks[(2 * count + 1)] = float(y)
        if count > 0:
            xp = int(landmarks[(2 * count - 2)])
            yp = int(landmarks[(2 * count - 1)])
            cv2.line(img, (xp, yp), (x, y), (0, 0, 255))
        cv2.circle(img, (x, y), 2, (0, 0, 255), -1)
        count += 1
        if count == c.get_nb_landmarks():
            xp = int(landmarks[0])
            yp = int(landmarks[1])
            cv2.line(img, (x, y), (xp, yp), (0, 0, 255))
def create_fitting_functions(GNS, GTS):
    '''
    Creates the fitting function for each tooth, for each landmark.
    @param GNS:              the matrix GNS which contains for each tooth, for each of the given training samples,
                             for each landmark, a normalized sample (along the profile normal through that landmark)
    @param GTS:              the matrix GTS which contains for each tooth, for each of the given training samples,
                             for each landmark, a normalized sample (along the profile tangent through that landmark)
    @return The fitting functions for each tooth, for each landmark.
    '''
    fns = [[
        get_fitting_function(tooth, landmark, GNS)
        for landmark in range(c.get_nb_landmarks())
    ] for tooth in range(c.get_nb_teeth())]
    fts = [[
        get_fitting_function(tooth, landmark, GTS)
        for landmark in range(c.get_nb_landmarks())
    ] for tooth in range(c.get_nb_teeth())]
    return fns, fts
def create_fitting_functions_for_multiple_levels(L_GNS, L_GTS):
    '''
    Creates the fitting function for each level, for each tooth, for each landmark.
    @param L_GNS:            the matrix L_GNS which contains for each level, for each tooth, for each of the given training samples,
                             for each landmark, a normalized sample (along the profile normal through that landmark)
    @param L_GTS:            the matrix L_GTS which contains for each level, for each tooth, for each of the given training samples,
                             for each landmark, a normalized sample (along the profile tangent through that landmark)
    @return The fitting functions for each level, for each tooth, for each landmark.
    '''
    l_fns = [[[
        get_fitting_function(tooth, landmark, L_GNS[level, :])
        for landmark in range(c.get_nb_landmarks())
    ] for tooth in range(c.get_nb_teeth())] for level in range(L_GNS.shape[0])]
    l_fts = [[[
        get_fitting_function(tooth, landmark, L_GTS[level, :])
        for landmark in range(c.get_nb_landmarks())
    ] for tooth in range(c.get_nb_teeth())] for level in range(L_GTS.shape[0])]
    return l_fns, l_fts
def create_partial_GS(trainingSamples,
                      XS,
                      MS,
                      level=0,
                      offsetX=0,
                      offsetY=0,
                      k=5,
                      method=''):
    '''
    Creates the matrix GNS which contains for each tooth, for each of the given training samples,
    for each landmark, a normalized sample (along the profile normal through the landmarks).
    Creates the matrix GTS which contains for each tooth, for each of the given training samples,
    for each landmark, a normalized sample (along the profile tangent through the landmarks).
    @param trainingSamples: the number of the training samples (not the test training samples!)
    @param XS:              contains for each tooth, for each training sample, all landmarks (in the image coordinate frame)
    @param MS:              contains for each tooth, the tooth model (in the model coordinate frame)
    @param level:           the current level
    @param offsetX:         the possible offset in x direction (used when working with cropped images and non-cropped landmarks)
    @param offsetY:         the possible offset in y direction (used when working with cropped images and non-cropped landmarks)
    @param k:               the number of pixels to sample either side for each of the model points along the profile normal
    @param method:          the method used for preprocessing
    @return The matrix GNS which contains for each tooth, for each of the given training samples,
            for each landmark, a normalized sample (along the profile normal through that landmark).
            The matrix GTS which contains for each tooth, for each of the given training samples,
            for each landmark, a normalized sample (along the profile tangent through that landmark).
    '''
    GNS = np.zeros((c.get_nb_teeth(), len(trainingSamples),
                    c.get_nb_landmarks(), 2 * k + 1))
    GTS = np.zeros((c.get_nb_teeth(), len(trainingSamples),
                    c.get_nb_landmarks(), 2 * k + 1))
    for j in range(c.get_nb_teeth()):
        index = 0
        for i in trainingSamples:
            # model of tooth j from model coordinate frame to image coordinate frame
            xs, ys = mu.extract_coordinates(
                mu.full_align_with(MS[j], XS[j, index, :]))
            fname = c.get_fname_vis_pre(i, method)
            img = cv2.imread(fname)
            pyramid = gip.get_gaussian_pyramid_at(img, level)
            GN, GT = create_G(pyramid, k, xs, ys, offsetX, offsetY)
            GNS[j, index, :] = GN
            GTS[j, index, :] = GT
            index += 1
    return GNS, GTS
def create_partial_GS_for_multiple_levels(trainingSamples,
                                          XS,
                                          MS,
                                          nb_levels=1,
                                          offsetX=0,
                                          offsetY=0,
                                          k=5,
                                          method=''):
    '''
    Creates the matrix L_GNS which contains for each level, for each tooth, for each of the given training samples,
    for each landmark, a normalized sample (along the profile normal through the landmarks).
    Creates the matrix L_GTS which contains for each tooth, for each of the given training samples,
    for each landmark, a normalized sample (along the profile tangent through the landmarks).
    @param trainingSamples: the number of the training samples (not the test training samples!)
    @param XS:              contains for each tooth, for each training sample, all landmarks (in the image coordinate frame)
    @param MS:              contains for each tooth, the tooth model (in the model coordinate frame)
    @param nb_levels:           the number of levels
    @param offsetX:         the possible offset in x direction (used when working with cropped images and non-cropped landmarks)
    @param offsetY:         the possible offset in y direction (used when working with cropped images and non-cropped landmarks)
    @param k:               the number of pixels to sample either side for each of the model points along the profile normal
    @param method:          the method used for preprocessing
    @return The matrix L_GNS which contains for each level, for each tooth, for each of the given training samples,
            for each landmark, a normalized sample (along the profile normal through that landmark).
            The matrix L_GTS which contains for each level, for each tooth, for each of the given training samples,
            for each landmark, a normalized sample (along the profile tangent through that landmark).
    '''
    L_GNS = np.zeros((nb_levels, c.get_nb_teeth(), len(trainingSamples),
                      c.get_nb_landmarks(), 2 * k + 1))
    L_GTS = np.zeros((nb_levels, c.get_nb_teeth(), len(trainingSamples),
                      c.get_nb_landmarks(), 2 * k + 1))
    for i in range(nb_levels):
        GNS, GTS = create_partial_GS(trainingSamples,
                                     np.around(np.divide(XS, 2**i)),
                                     MS,
                                     i,
                                     offsetX=round(float(offsetX) / 2**i),
                                     offsetY=round(float(offsetY) / 2**i),
                                     k=k,
                                     method=method)
        L_GNS[i, :] = GNS
        L_GTS[i, :] = GTS
    return L_GNS, L_GTS
示例#11
0
def create_negatives(method=''):
    XS = l.create_full_XS()
    
    for i in c.get_trainingSamples_range():
        fname = c.get_fname_vis_pre(i, method)
        img = cv2.imread(fname)
        
        s = ''    
        if (i < 10): s = '0'
        
        min_y = min_x = float("inf")
        max_y = max_x = 0
    
        for j in range(0, c.get_nb_teeth()/2):
            x_coords, y_coords = mu.extract_coordinates(XS[j, i-1, :])
            for k in range(c.get_nb_landmarks()):
                if x_coords[k] < min_x: min_x = x_coords[k]
                if x_coords[k] > max_x: max_x = x_coords[k]
                if y_coords[k] < min_y: min_y = y_coords[k]
                if y_coords[k] > max_y: max_y = y_coords[k]
        
        fname = c.get_dir_prefix() + 'data/Visualizations/Classified Samples/' + method + str(s) + str(i) + '-l' + '.png'    
        cv2.imwrite(fname, img[max_y-fu.offsetY+1:,:])
        
        min_y = min_x = float("inf")
        max_y = max_x = 0
        
        for j in range(c.get_nb_teeth()/2, c.get_nb_teeth()):
            x_coords, y_coords = mu.extract_coordinates(XS[j, i-1, :])
            for k in range(c.get_nb_landmarks()):
                if x_coords[k] < min_x: min_x = x_coords[k]
                if x_coords[k] > max_x: max_x = x_coords[k]
                if y_coords[k] < min_y: min_y = y_coords[k]
                if y_coords[k] > max_y: max_y = y_coords[k] 
        
        fname = c.get_dir_prefix() + 'data/Visualizations/Classified Samples/' + method + str(s) + str(i) + '-u' + '.png'    
        cv2.imwrite(fname, img[:min_y-fu.offsetY,:])
def display_landmarks(X, nr_trainingSample=1, color=np.array([0, 0, 255])):
    '''
    Displays the landmarks corresponding to the given training sample
    on the corresponding radiograph in the image coordinate frame.
    @param X:                   the training samples
    @param nr_trainingSample:   the training sample to select
    @param color:               the color used for displaying
    '''
    img = cv2.imread(c.get_fname_radiograph(nr_trainingSample))

    xCoords, yCoords = mu.extract_coordinates(X[(nr_trainingSample - 1), :])
    for i in range(c.get_nb_landmarks()):
        #y coordinate , x coordinate
        img[yCoords[i], xCoords[i], :] = color
    #cv2.imshow("test", img)
    # writing instead of showing, because the displayed image is too large
    cv2.imwrite("test.tif", img)
示例#13
0
def multi_resolution_search(img,
                            P,
                            tooth_index,
                            fitting_function=1,
                            show=False):
    '''
    Fits the tooth corresponding to the given tooth index in the given image.
    @param img:                 the image  
    @param P:                   the start points for the target tooth
    @param tooth_index:         the index of the the target tooth (used in MS, EWS, fs)
    @param fitting_function:    the fitting function used
                                * 0: fitting function along profile normal through landmark +
                                     fitting function along profile gradient through landmark
                                * 1: fitting function along profile normal through landmark
                                * 2: fitting function along profile gradient through landmark
    @param show:                must the intermediate results (after each iteration) be displayed
    @return The fitted points for the tooth corresponding to the given tooth index
            and the number of iterations used.
    '''
    nb_it = 0
    level = max_level
    pyramids = gip.get_gaussian_pyramids(img, level)

    # Compute model point positions in image at coarsest level
    P = np.around(np.divide(P, 2**level))

    while (level >= 0):
        nb_it += 1
        pxs, pys = mu.extract_coordinates(P)
        for i in range(c.get_nb_landmarks()):
            tx, ty, nx, ny = ff.create_ricos(pyramids[level], i, pxs, pys)
            f_optimal = float("inf")

            if (fitting_function == 0):
                rn = rt = range(-(m - k), (m - k) + 1)
            elif (fitting_function == 1):
                rn = range(-(m - k), (m - k) + 1)
                rt = [0]
            else:
                rn = [0]
                rt = range(-(m - k), (m - k) + 1)

            for n in rn:
                for t in rt:
                    x = round(pxs[i] + n * nx + t * tx)
                    y = round(pys[i] + n * ny + t * ty)
                    try:
                        fn = fns[level][tooth_index][i](ff.normalize_Gi(
                            ff.create_Gi(pyramids[level], k, x, y, nx, ny)))
                        ft = fts[level][tooth_index][i](ff.normalize_Gi(
                            ff.create_Gi(pyramids[level], k, x, y, tx, ty)))
                    except (IndexError):
                        continue
                    f = fu.evaluate_fitting(fn=fn,
                                            ft=ft,
                                            fitting_function=fitting_function)
                    if f < f_optimal:
                        f_optimal = f
                        cx = x
                        cy = y
            pxs[i] = cx
            pys[i] = cy

        P_new = validate(pyramids[level], tooth_index,
                         mu.zip_coordinates(pxs, pys), nb_it, show)
        nb_close_points = nb_closest_points(P, P_new)
        P = P_new

        # Repeat unless more than pclose of the points are found close to the current position
        # or nmax iterations have been applied at this resolution
        print 'Level:' + str(level) + ', Iteration: ' + str(
            nb_it) + ', Ratio: ' + str(
                (2 * nb_close_points / float(P.shape[0])))

        converged = (2 * nb_close_points / float(P.shape[0]) >= pclose)
        if (converged or nb_it >= max_it):
            if (level > 0):
                level -= 1
                nb_it = 0
                P = P * 2
            else:
                break

    return P