def calculateRA(T, sx, sy, points, P): """Calculate Reconstruction Accuracy, as indicated in [Ref2]_. It needs 1 single-point feature to be extracted for some US images of a calibration quality assessment acquisition. These points (each for different US images) are reconstructed in global reference frame. RA is the mean of the norm of the difference between these points and the gold-standard points ``P``. Parameters ---------- T : np.ndarray N x 4 x 4 array where ``T[i,:,:]`` represents the roto-translation matrix from US image reference frame to global reference frame, for time frame ``i``. sx, sy : float Number of mm for each pixel in US image, for horizontal and vertical axis (in *mm/pixel*). points : dict Dictionary where keys are frame numbers and values are lists of tuples, each one representing a point position in the corresponding US image. Only one tuple is needed. P : np.ndarray Gold-standard 3D positions (in *mm*) for reconstruction accuracy estimation. Returns ------- dist : np.ndarray Array containing distances, each on calculated by using a real 3D point and the reconstructed 3D point. DA : float Mean of ``dist`` ignoring nans. """ # Calculate points in the global reference frame pointsGl1 = np.zeros((3,len(points))) * np.nan pointsGl2 = np.zeros((3,len(points))) * np.nan frames = np.sort(points.keys()) for i in xrange(0, len(points)): if len(points[frames[i]]) <> 1: # pointsGl[:,i] = np.nan continue fr = frames[i] point = singlePointFeaturesTo3DPointsMatrix(points, sx, sy, idx=(fr,)).squeeze() pointsGl1[:,i] = np.dot(T[fr,:,:],point)[0:3] if fr < P.shape[0]: pointsGl2[:,i] = P[fr,:] else: pointsGl2[:,i] = np.nan #pointsGl1 = pointsGl1[0:3,:] # Calculate RA dist = np.zeros((pointsGl1.shape[1],)) for i in xrange(0,pointsGl1.shape[1]): # np.linalg.norm has no 'axis' argument for NumPy 1.7.1 dist[i] = np.linalg.norm(pointsGl1[:,i]-pointsGl2[:,i]) RA = stats.nanmean(dist) return dist, RA
def calculateRP(T, sx, sy, points): """Calculate point reconstruction reconstruction precision, as in [Ref1]_. It needs single-point feature to be extracted for some US images of a calibration quality assessment acquisition. The points are the reconstructed in 3D space, creating a cloud of points. RP is the mean of the distances between each 3D point and the 3D average point. Parameters ---------- T : np.ndarray N x 4 x 4 array where ``T[i,:,:]`` represents the roto-translation matrix from US image reference frame to global reference frame, for time frame ``i``. sx, sy : float Number of mm for each pixel in US image, for horizontal and vertical axis (in *mm/pixel*). points : dict dictionary where keys are frame numbers and values are lists of tuples, each one representing a point position in the corresponding US image. Returns ------- float Reconstruction precision value """ # Calculate points in the global reference frame pointsGl = np.zeros((4,len(points))) frames = np.sort(points.keys()) for i in xrange(0, len(points)): if len(points[frames[i]]) <> 1: pointsGl[:,i] = np.nan continue fr = frames[i] # point = np.zeros((4,)) # point[0] = points[frames[i]][0][0] * sx # point[1] = points[frames[i]][0][1] * sy # point[2:4] = (0, 1) point = singlePointFeaturesTo3DPointsMatrix(points, sx, sy, idx=(fr,)).squeeze() pointsGl[:,i] = np.dot(T[fr,:,:],point) pointsGl = pointsGl[0:3,:] # Calculate RP meanPoint = stats.nanmean(pointsGl, axis=1) pointsNorm = np.zeros((pointsGl.shape[1],)) for i in xrange(0,len(pointsNorm)): # np.linalg.norm has no 'axis' argument for NumPy 1.7.1 pointsNorm[i] = np.linalg.norm(pointsGl[:,i]-meanPoint) RP = np.mean(pointsNorm) return RP
def calculateDA(T, sx, sy, points, L): """Calculate Distance Accuracy, as indicated in [Ref2]_. It needs 2 single-point features to be extracted for some US images of a calibration quality assessment acquisition. These 2 points (each for different US images) are reconstructed in and the distance is calculated. This process can be repeated for other couples of US images. For instance, if one point is indicated for frames 1, 4, 10, 15, 25, 40, then 3 distances are calculated (1-4, 10-15, 25-40). DA is the mean of the difference between these distances and the gold-standard measured real distance ``L``. Parameters ---------- T : np.ndarray N x 4 x 4 array where ``T[i,:,:]`` represents the roto-translation matrix from US image reference frame to global reference frame, for time frame ``i``. sx, sy : float Number of mm for each pixel in US image, for horizontal and vertical axis (in *mm/pixel*). points : dict Dictionary where keys are frame numbers and values are lists of tuples, each one representing a point position in the corresponding US image. Only one tuple is needed. L : float Gold-standard distance (in *mm*) for distance accuracy estimation. Returns ------- listDA : np.ndarray Array containing distances, each on calculated by using points from 2 consecutive frame numbers from ``points``. DA : float Mean of ``listDA`` ignoring nans. """ # Calculate points in the global reference frame Nc = np.floor(len(points) / 2.) pointsGl1 = np.zeros((4,Nc)) * np.nan pointsGl2 = np.zeros((4,Nc)) * np.nan frames = np.sort(points.keys()) c = 0 for i in xrange(0, len(points)-1, 2): if len(points[frames[i]]) <> 1 or len(points[frames[i+1]]) <> 1: continue fr1 = frames[i] fr2 = frames[i+1] # point1 = np.zeros((4,)) # point1[0] = points[frames[i]][0][0] * sx # point1[1] = points[frames[i]][0][1] * sy # point1[2:4] = (0, 1) # pointsGl1[:,c] = np.dot(T[fr1,:,:],point1) # point2 = np.zeros((4,)) # point2[0] = points[frames[i+1]][0][0] * sx # point2[1] = points[frames[i+1]][0][1] * sy # point2[2:4] = (0, 1) # pointsGl2[:,c] = np.dot(T[fr2,:,:],point2) pointsGl = singlePointFeaturesTo3DPointsMatrix(points, sx, sy, idx=(fr1,fr2,)) pointsGl1[:,c] = np.dot(T[fr1,:,:],pointsGl[0,:]) pointsGl2[:,c] = np.dot(T[fr2,:,:],pointsGl[1,:]) c += 1 pointsGl1 = pointsGl1[0:3,:] pointsGl2 = pointsGl2[0:3,:] # Calculate DA dist = np.zeros((pointsGl1.shape[1],)) for i in xrange(0,len(dist)): dist[i] = np.linalg.norm(pointsGl1[:,i]-pointsGl2[:,i]) listDA = np.abs(dist - L) DA = stats.nanmean(listDA) return listDA, DA