예제 #1
0
def appearance(mean,points,training):
    
    xmean = mean[:len(mean)/2]
    ymean = mean[len(mean)/2:]
    minxmean = np.min(xmean)
    minymean = np.min(ymean)
    
    refshape = zip(xmean,ymean)
    refshape = [((p[0]-minxmean),(p[1]-minymean)) for p in refshape]
    model_matrix = []
    appshapes = np.zeros(shape=(len(training),2))
    
    # get vector for each image
    for i in range(len(training)):
        
        # take gradient + clean
        gradimg = rg.togradient(training[i])
        
        # get model from cleaned image
        appearance = appvec(refshape,points[i],gradimg)
        model_matrix.append(appearance)
        appshapes[i] = appearance.shape

    #calculate mean appearance shape
    meanshape0 = int(np.mean([s[0] for s in appshapes]))
    meanshape1 = int(np.mean([s[1] for s in appshapes]))
    model = np.uint8(np.zeros(shape=(len(training),meanshape0*meanshape1)))
    
    #resize model matrix according to mean shape and flatten into vector
    for i in range(len(training)):
        model[i] = cv2.resize(model_matrix[i],(meanshape1,meanshape0)).flatten()

    # mean of image model vectors and mean of shape = total model
    return np.uint8(np.mean(model,axis=0)),(meanshape0, meanshape1)
예제 #2
0
def autoinit(mean, marks, trainimgs, testimg, k, m, gmod):
   
    imgw, imgh = testimg.shape[1],testimg.shape[0]
    
    # get appearance model
    a_mean,mean_shape = appearance(mean,marks,trainimgs)
    
    
    # get TL model (mean and standard dev) for top-left corners of landmarks
    TL, TLmin, TLmax = TLmodel(marks,trainimgs, imgw, imgh)
    
    # get radiograph as gradient image (also equalizes for better edges)
    gradimg = rg.togradient(testimg)

    #
    xmean, ymean = mean[:len(mean)/2], mean[len(mean)/2:]
    min_x,min_y = np.min(xmean),np.min(ymean)
    initshape = zip([(x-min_x)*imgw for x in xmean],[(y-min_y)*imgh for y in ymean])
    
    min_x,min_y = np.min(mean[:len(mean)/2]),np.min(mean[len(mean)/2:])
    pts = zip(mean[:len(mean)/2],mean[len(mean)/2:])
    pts = [((point[0]-min_x),(point[1]-min_y)) for point in pts]
    initshape = [(int(y[0]*imgw),int(y[1]*imgh)) for y in pts]
    
    # set of angles and scales to nudge new shapes in
    angles = np.array(range(-8,9,1))/2.0
    scales = range(8,-1,-1)  
    
    
    # to start, use template equal to bounding box around mean shape of appearance model
    template = a_mean.reshape((mean_shape[0],mean_shape[1]))
    temph, tempw = template.shape
    
    chosenangle = 0
    chosenscalex = 0
    chosenscaley = 0
    chosenlocation = (0,0)
    
    dmin = np.inf
    
    # scale shape over select amount of scaling factors- x axis
    for sx in [0.05*s+0.1 for s in scales]:
        xtempl = cv2.resize(template,(int(tempw*sx),temph))
        
        # scale shape over select amount of scaling factors - y axis
        for sy in [0.05*s+0.1 for s in scales]:
                X,Y,dTL = gettemplateparam(xtempl,sy, TLmin, TLmax, TL, gradimg)
                
                # rotate shape over select amount of rotations, find best fit
                for a in angles:
                    angle = a*0.1
                    # get a new shape by 'nudging' the current shape 
                    # = scale, rotate, translate
                    nudgedshape = nudgeshape(sx,sy,angle,X,Y,initshape,1.0,1.0)
                    points = np.array(zip(*nudgedshape)).flatten().tolist()
                    d = 0
                    
                    if not(np.max(points[:len(points)/2])+k > imgw-1 or np.max(points[len(points)/2:])+k > imgh-1):
                        for l in range(len(nudgedshape)):
                            
                            # get model, gradients, normal and profile for point l
                            profile, n = prfl.get(nudgedshape,l)
                            cov,mean = gmod[l]
                            # Get mahalanobis distance from profile[0]'s greylvl model to provided greymodel (co,mean)
                            d = d + prfl.greylvldistancemetric(profile[0], mean, cov, k ,n,testimg)
                        
                        # calculate full metric
                        d = d/len(nudgedshape)
                        dtot = d+0.01*np.linalg.norm(dTL)
                        
                        # update 
                        if dtot < dmin:
                            dmin = dtot
                            chosenlocation = X,Y
                            chosenscalex = sx
                            chosenscaley = sy
                            chosenangle = angle


    print "Estimate found:"
    print "Location = ("+ ",".join([str(c).split(".")[0] for c in chosenlocation]) + ")"
    print "Angle = " + str(chosenangle)
    print "Scale X = " + str(chosenscalex)
    print "Scale Y = " + str(chosenscaley)

    # nudge initial shape by chosen angle, scale and position
    result = nudgeshape(chosenscalex,chosenscaley,chosenangle,chosenlocation[0],chosenlocation[1],initshape,(1.0/float(imgw)),(1.0/float(imgh)))

    return [el for point in zip(*result) for el in point]