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)
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]