From simon.rit at creatis.insa-lyon.fr Tue Jul 11 02:03:42 2017 From: simon.rit at creatis.insa-lyon.fr (Simon Rit) Date: Tue, 11 Jul 2017 08:03:42 +0200 Subject: [Rtk-users] Obtaining Cone Beam projections using sRTK In-Reply-To: References: Message-ID: Hi, Please use the mailing list. A 1 mm shift of an object at the isocenter should indeed translate in a 1.536 mm shift on the projection with the defined geometry. I don't see anything wrong in your code but you have only provided a part of it. Could you provide a full self-contained script? Simon On Mon, Jul 10, 2017 at 11:19 PM, Daniel Markel wrote: > Hi Simon, > > > Thank you for helping me earlier in getting SRTK up and > running. I've had some success running it to attain some projections using > a 3D volume but I have run into a problem and cannot find the solution > anywhere online. Perhaps you can help. > > > I'm getting projections using the following snippet of code > > > origin = [-200,-200,-180-(600-512)*0.39063] > > sid = 1000 # source to isocenter distance in mm > sdd = 1536 # source to detector distance in mm > > isox = 0 # X coordinate on the projection image of isocenter > isoy = -90 # Y coordinate on the projection image of isocenter > > angle = 180 > > Temp = srtk.GetArrayFromImage(Image) > > ? > Temp_vol = np.roll(Temp,int(shiftx2),2)#Shift in the LR axis > Temp_vol = np.roll(Temp_vol,int(shifty2),1)#Shift in the AP axis > Temp_vol = np.roll(Temp_vol,int(shiftz2),0)#Shift in the I/S axis > > ? > > ? > fwrd = srtk.JosephForwardProjectionImageFilter() > projInput = srtk.ConstantImageSource() > geometry = srtk.ThreeDCircularProjectionGeometry() > size = (425,425,1) > spacing = (1,1,1) > projInput.SetOrigin(origin) > projInput.SetSpacing(spacing) > projInput.SetSize(size) > projInput.SetConstant(int(1)) > pixelID = Image.GetPixelIDValue() > projInput.SetOutputPixelType(pixelID) > proj = projInput.Execute() > Image = srtk.GetImageFromArray(Temp_vol) > Image.SetOrigin(origin) > Image.SetSpacing(spacing2) > Image.SetDirection([1,0,0,0,0,1,0,1,0]) > geometry.AddProjection(sid,sdd,angle,isox,isoy) > fwrd.SetGeometry(geometry) > proj2 = fwrd.Execute(proj,Image) > > ? > > projim = srtk.GetArrayFromImage(proj2[:,:,0]) > > > What I wanted to do was shift an object in the 3D volume 'temp' by a known > amount recreate the image object using the shifted volume and then create a > kV projection through the shifted volume. I'm doing this to test the > ability of detecting shifts in the volume using the kV projected images. > The problem is that I was calculating the anticipated shifts using a cone > beam geometry where the shift in the 3D volume is magnified by an amount > related to the distance of the detector from the source and the position of > the 3D object in relation to the source. For the geometry I have above it's > 1000 mm to the center of my 3D object and 1536 mm from the source to the > detector so the factor of magnification of any shift in my 3D object should > be 1.536 on my projection but when I look at my results the magnification > is always 1 as if I'm not using a cone beam geometry at all but simply > attaining a projection straight on using parallel x-rays. Am I missing > something in my code to get a cone geometry? > > > Any insight would be greatly appreciated. > > > -Daniel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From simon.rit at creatis.insa-lyon.fr Wed Jul 12 05:08:22 2017 From: simon.rit at creatis.insa-lyon.fr (Simon Rit) Date: Wed, 12 Jul 2017 11:08:22 +0200 Subject: [Rtk-users] Obtaining Cone Beam projections using sRTK In-Reply-To: References: Message-ID: Hi, Again, I insist, use the mailing list. Can you make it a self contained code? You can replace your image with a simulated Shepp Logan phantom using DrawSheppLoganFilter. And please make it more minimal (just one shift). Thanks, Simon On Tue, Jul 11, 2017 at 3:55 PM, Daniel Markel wrote: > Hi Simon here is the full script, minus some sub-functions. I apologize > for the mess in advance. > > -Dan > > def main(): > folderpath = 'D:\test_object' > reader = srtk.ImageSeriesReader() #initialize the reader > onlyfile = srtk.ImageSeriesReader_GetGDCMSeriesFileNames(folderpath) > Image = srtk.Image() #initialize the image object type > reader.SetFileNames(onlyfile) #input the file names to be read in the > series > Image = reader.Execute() #import the dicom slices into a 3D volume > > Image = Image+2000 > Image.SetDirection([1,0,0,0,0,1,0,1,0]) > > > > > > size2 = Image.GetSize() > spacing2 = [1,1,1] > numberOfProjections = 31 > Disp = np.zeros((numberOfProjections-1,2,20))#recorded residual > geometric error > Normccs = np.zeros((numberOfProjections-1,20))#recorded metric values > post-registration > shiftsx = np.zeros((numberOfProjections-1,20))#recorded image > corrections > shiftsy = np.zeros((numberOfProjections-1,20)) > Inplaneshiftsx = np.zeros((numberOfProjections-1,20)) #recorded > perturbations to be corrected as projected into the plane of the kV panel > for x and y > Inplaneshiftsy = np.zeros((numberOfProjections-1,20)) > shiftsx2 = np.zeros((numberOfProjections-1,20)) > shiftsy2 = np.zeros((numberOfProjections-1,20)) > shiftsz2 = np.zeros((numberOfProjections-1,20)) > #Acc = np.zeros(numberOfProjections-1) > cast = srtk.CastImageFilter() > cast.SetOutputPixelType(7) > Image2 = cast.Execute(Image) > firstAngle = 0 > angularArc = 360 > > sid = 10000 # source to isocenter distance in mm > sdd = 15360 # source to detector distance in mm > > isox = 0 # X coordinate on the projection image of isocenter > isoy = -90 # Y coordinate on the projection image of isocenter\ > > for k in range(0,1): > Image = Image2 > geometry = srtk.ThreeDCircularProjectionGeometry() > angle = 180+k*18 > geometry.AddProjection(sid,sdd,angle,isox,isoy) > > projInput = srtk.ConstantImageSource() > > > > size = (425,425,1) > spacing = (1,1,1) > projInput.SetOrigin(origin) > projInput.SetSpacing(spacing) > projInput.SetSize(size) > projInput.SetConstant(int(1)) > pixelID = Image.GetPixelIDValue() > projInput.SetOutputPixelType(pixelID) > proj = projInput.Execute() > iters2 = numberOfProjections - 1 > > > > > > shifty2 = np.zeros(iters2+1) > #shiftx2 = np.zeros(iters2+1) > shiftz2 = np.zeros(iters2+1) > > shiftx2[1:] = np.linspace(1,30,30)-15 > > > Temp = srtk.GetArrayFromImage(Image) > Image_shifted_array = np.zeros((size[0],size[1],iters2+1)) > > for i in range(0,iters2): > > Temp_vol = np.roll(Temp,int(shiftx2[i]),2)#Shift in the LR > axis > Temp_vol = np.roll(Temp_vol,int(shifty2[i]),1)#Shift in the > AP axis > Temp_vol = np.roll(Temp_vol,int(shiftz2[i]),0)#Shift in the > I/S axis > shiftsx2[i,k] = shiftx2[i] > shiftsy2[i,k] = shifty2[i] > shiftsz2[i,k] = shiftz2[i] > Inplaneshiftsy[i,k] = shiftz2[i]*1.25 > Inplaneshiftsx[i,k] = ((shiftx2[i]*0.39063)*np.cos( > angle*np.pi/180)+(shifty2[i]*0.39063)*np.sin(angle*np.pi/180)) > fwrd = srtk.JosephForwardProjectionImageFilter() > projInput = srtk.ConstantImageSource() > geometry = srtk.ThreeDCircularProjectionGeometry() > > > size = (425,425,1) > spacing = (1,1,1) > projInput.SetOrigin(origin) > projInput.SetSpacing(spacing) > projInput.SetSize(size) > projInput.SetConstant(int(1)) > pixelID = Image.GetPixelIDValue() > projInput.SetOutputPixelType(pixelID) > proj = projInput.Execute() > Image = srtk.GetImageFromArray(Temp_vol) > Image.SetOrigin(origin) > Image.SetSpacing(spacing2) > Image.SetDirection([1,0,0,0,0,1,0,1,0]) > #geometry.AddProjection() > geometry.AddProjection(sid,sdd,angle,isox,isoy) > fwrd.SetGeometry(geometry) > proj2 = fwrd.Execute(proj,Image) > Image_shifted_array[:,:,i] = srtk.GetArrayFromImage(proj2[: > ,:,0]) > > Image_unshifted = Image_shifted_array[:,:,0] > > for i in range(0,iters2-1): > > Image_shifted = np.squeeze(Image_shifted_array[:,:,i]) > > plt.imshow(Image_shifted_array[:,:,i], cmap = cm.Greys_r) > plt.show() > plt.imshow(Image_unshifted, cmap = cm.Greys_r) > plt.show() > > iters = 150 > step_size = 30 > randy = np.round((np.random.rand(iters)-0.5)*step_size) > randx = np.round((np.random.rand(iters)-0.5)*step_size) > > normcc_last = NCC(Image_unshifted[40:(425- > 40),40:(425-40)],Image_shifted[40:(425-40),40:(425-40)]) > > shiftx = 0 > shifty = 0 > time_start = time.clock() > for shift in range(iters): > Image_temp = np.roll(Image_shifted,int( > shiftx+randx[shift]),1) > Image_temp = np.roll(Image_temp,int(shifty+ > randy[shift]),0) > > normcc_new = NCC(Image_unshifted[40:(425- > 40),40:(425-40)],Image_temp[40:(425-40),40:(425-40)]) > > if normcc_new>normcc_last: > shiftx = shiftx+randx[shift] > shifty = shifty+randy[shift] > normcc_last = normcc_new > if normcc_new == 0.5: > > break > > Disp[i,0,k] = np.sqrt((Inplaneshiftsx[i,k]*(1536/1000))**2+( > Inplaneshiftsy[i,k]*(1536/1000))**2) > Disp[i,1,k] = np.sqrt((shiftx*1.66 - > (Inplaneshiftsx[i,k]*(1536/1000)))**2+(shifty*1.66 - > (Inplaneshiftsy[i,k]*(1536/1000)))**2) > Normccs[i,k] = normcc_last > shiftsx[i,k] = shiftx > shiftsy[i,k] = shifty > > ind = np.argsort(Disp,axis = 0) > Disp2 = Disp > Normccs2 = Normccs > Inplaneshiftsx_new = Inplaneshiftsx > Inplaneshiftsy_new = Inplaneshiftsy > shiftsx_new = shiftsx > shiftsy_new = shiftsy > shiftsx2_new = shiftsx2 > shiftsy2_new = shiftsy2 > shiftsz2_new = shiftsz2 > for p in range(0,20): > Disp2[:,0,p] = Disp[ind[:,0,p],0,p] > Disp2[:,1,p] = Disp[ind[:,0,p],1,p] > Normccs2[:,p] = Normccs2[ind[:,0,p],p] > Inplaneshiftsy_new[:,p] = Inplaneshiftsy[ind[:,0,p],p] > Inplaneshiftsx_new[:,p] = Inplaneshiftsx[ind[:,0,p],p] > shiftsy_new[:,p] = shiftsy[ind[:,0,p],p] > shiftsx_new[:,p] = shiftsx[ind[:,0,p],p] > shiftsy2_new[:,p] = shiftsy2[ind[:,0,p],p] > shiftsx2_new[:,p] = shiftsx2[ind[:,0,p],p] > shiftsz2_new[:,p] = shiftsz2[ind[:,0,p],p] > with open('D:\\NCC_result_centered_HD_systematic2.csv','w', newline = > '') as csvfile: > spamwriter = csv.writer(csvfile, delimiter=' ', quotechar='|', > quoting=csv.QUOTE_MINIMAL) > sz = np.shape(Disp2) > for t in range(0,sz[2]): > for l in range(0,sz[0]): > line = '' > t0 = str(180+t*18) > t1 = ' ' > t2 = str(Disp2[l,0,t]) > t3 = str(Disp2[l,1,t]) > t4 = str(Inplaneshiftsx_new[l,t]) > t5 = str(Inplaneshiftsy_new[l,t]) > t6 = str(shiftsx2_new[l,t]) > t7 = str(shiftsy2_new[l,t]) > t8 = str(shiftsz2_new[l,t]) > t9 = str(shiftsx_new[l,t]) > t10 = str(shiftsy_new[l,t]) > t11 = 'angle:' > t12 = str(Normccs2[l,t]) > > > line = t11+t0+t1+t2+t1+t3+t1+t4+t1+ > t5+t1+t6+t1+t7+t1+t8+t1+t9+t1+t10+t1+t12 > > > > spamwriter.writerow(line) > > > main() > > On Tue, Jul 11, 2017 at 2:03 AM, Simon Rit > wrote: > >> Hi, >> Please use the mailing list. >> A 1 mm shift of an object at the isocenter should indeed translate in a >> 1.536 mm shift on the projection with the defined geometry. I don't see >> anything wrong in your code but you have only provided a part of it. Could >> you provide a full self-contained script? >> Simon >> >> On Mon, Jul 10, 2017 at 11:19 PM, Daniel Markel >> wrote: >> >>> Hi Simon, >>> >>> >>> Thank you for helping me earlier in getting SRTK up and >>> running. I've had some success running it to attain some projections using >>> a 3D volume but I have run into a problem and cannot find the solution >>> anywhere online. Perhaps you can help. >>> >>> >>> I'm getting projections using the following snippet of code >>> >>> >>> origin = [-200,-200,-180-(600-512)*0.39063] >>> >>> sid = 1000 # source to isocenter distance in mm >>> sdd = 1536 # source to detector distance in mm >>> >>> isox = 0 # X coordinate on the projection image of isocenter >>> isoy = -90 # Y coordinate on the projection image of isocenter >>> >>> angle = 180 >>> >>> Temp = srtk.GetArrayFromImage(Image) >>> >>> ? >>> Temp_vol = np.roll(Temp,int(shiftx2),2)#Shift in the LR axis >>> Temp_vol = np.roll(Temp_vol,int(shifty2),1)#Shift in the AP axis >>> Temp_vol = np.roll(Temp_vol,int(shiftz2),0)#Shift in the I/S axis >>> >>> ? >>> >>> ? >>> fwrd = srtk.JosephForwardProjectionImageFilter() >>> projInput = srtk.ConstantImageSource() >>> geometry = srtk.ThreeDCircularProjectionGeometry() >>> size = (425,425,1) >>> spacing = (1,1,1) >>> projInput.SetOrigin(origin) >>> projInput.SetSpacing(spacing) >>> projInput.SetSize(size) >>> projInput.SetConstant(int(1)) >>> pixelID = Image.GetPixelIDValue() >>> projInput.SetOutputPixelType(pixelID) >>> proj = projInput.Execute() >>> Image = srtk.GetImageFromArray(Temp_vol) >>> Image.SetOrigin(origin) >>> Image.SetSpacing(spacing2) >>> Image.SetDirection([1,0,0,0,0,1,0,1,0]) >>> geometry.AddProjection(sid,sdd,angle,isox,isoy) >>> fwrd.SetGeometry(geometry) >>> proj2 = fwrd.Execute(proj,Image) >>> >>> ? >>> >>> projim = srtk.GetArrayFromImage(proj2[:,:,0]) >>> >>> >>> What I wanted to do was shift an object in the 3D volume 'temp' by a >>> known amount recreate the image object using the shifted volume and then >>> create a kV projection through the shifted volume. I'm doing this to test >>> the ability of detecting shifts in the volume using the kV projected >>> images. The problem is that I was calculating the anticipated shifts using >>> a cone beam geometry where the shift in the 3D volume is magnified by an >>> amount related to the distance of the detector from the source and the >>> position of the 3D object in relation to the source. For the geometry I >>> have above it's 1000 mm to the center of my 3D object and 1536 mm from the >>> source to the detector so the factor of magnification of any shift in my 3D >>> object should be 1.536 on my projection but when I look at my results the >>> magnification is always 1 as if I'm not using a cone beam geometry at all >>> but simply attaining a projection straight on using parallel x-rays. Am I >>> missing something in my code to get a cone geometry? >>> >>> >>> Any insight would be greatly appreciated. >>> >>> >>> -Daniel >>> >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From shahedif96 at yahoo.com Sun Jul 16 05:11:11 2017 From: shahedif96 at yahoo.com (fateme shahedi) Date: Sun, 16 Jul 2017 09:11:11 +0000 (UTC) Subject: [Rtk-users] MV-CBCT References: <135003197.1171368.1500196271587.ref@mail.yahoo.com> Message-ID: <135003197.1171368.1500196271587@mail.yahoo.com> Dear RTK users and developersI am new to RTK. I have some trouble getting a proper reconstruction. I want to use EPID mounted on Elekta linear accelerator to get MV-CBCT images. I have 120 projection images (in his format) scanned over (0-357) degree of the phantom. The phantom is containing 5 rods of different materials (titanium, aluminum, acrylic, air and polyethylene). The measurement geometry is as bellow;- detector size= 1024*1024 pixels- size of each pixel=0.4mm-size of each pixel at the isocenter=0.25mm-source-to-detector distance=157cm-source-to-isocenter distance=100cmI used the rtkfdk as bellow;[sn at localhost workspace]$ rtkelektasynergygeometry --image_db MyIMAGE1.DBF --frame_db MyFRAME1.DBF --dicom_uid 1 -oelektaGeometry[sn at localhost workspace]$ rtkfdk --lowmem --geometry elektaGeometry --path img_1/ --regexp '.*.his' --output slice50.0.mha --verbose --spacing 0.25,0.25,0.25 --dimension 1024,1,1024 --origin -127.875,50,-127.875.I display .mha images with VV?, it just show the central rod (air) and doesn't show?the others??( although?the projections are??megavoltage,?I get result from some other?open-source software for CBCT). I attached the geometry file (frame and image.DBF)? with the mail. I?need your help to?know what went wrong. I really appreciate any help you can provide. best regards.fateme. -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: MyFRAME1.rar Type: application/octet-stream Size: 761 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: MyIMAGE1.rar Type: application/octet-stream Size: 865 bytes Desc: not available URL: From lotte.schyns at maastro.nl Tue Jul 18 05:17:41 2017 From: lotte.schyns at maastro.nl (Lotte Schyns) Date: Tue, 18 Jul 2017 09:17:41 +0000 Subject: [Rtk-users] SIRT Reconstruction In-Reply-To: <61aad553-6a95-e00d-ae80-669a513b7d74@maastro.nl> References: <61aad553-6a95-e00d-ae80-669a513b7d74@maastro.nl> Message-ID: <9c29efa3-35a4-b20e-f91c-4c85470ba670@maastro.nl> Hello, We are having problems with the SIRT reconstructions. They seem very strange and blurry. However, other reconstructions (SART, FDK, iterativeFDK) look perfect. I uploaded an example of a SART and a SIRT reconstruction (same parameters) to https://www.dropbox.com/sh/7a4bkyjg43zjmy7/AAAp4tJrk9HedMEEuIKsGYDSa?dl=0. I also uploaded a minimalistic version of the code that I used (the paths in CMakeLists.txt probably need to be adapted to your system). You can alternate between SART and SIRT by changing line 143. The raw data is also available on dropbox. I didn't use rtkXRadRawToAttenuationImageFilter, because our projections are already corrected for the dark field and flood field, so (signal-dark)/(flood-dark). I just take the natural logarithm and multiply by -1. Do you know what could be the problem with the SIRT reconstructions? Are we using wrong parameters? Thanks for your time. Lotte From cyril.mory at creatis.insa-lyon.fr Tue Jul 18 05:31:10 2017 From: cyril.mory at creatis.insa-lyon.fr (Cyril Mory) Date: Tue, 18 Jul 2017 11:31:10 +0200 Subject: [Rtk-users] SIRT Reconstruction In-Reply-To: <9c29efa3-35a4-b20e-f91c-4c85470ba670@maastro.nl> References: <61aad553-6a95-e00d-ae80-669a513b7d74@maastro.nl> <9c29efa3-35a4-b20e-f91c-4c85470ba670@maastro.nl> Message-ID: <52c5db23-4496-14da-3b71-dd6f1b7d8148@creatis.insa-lyon.fr> Hi Lotte, I had a very quick look at what you are doing. It looks fine to me, you just need to perform way more iterations in the SIRT case. 100 would be a good start. SIRT is more stable than SART when there are inconsistencies in the projection data, but converges slowly. An alternative to SIRT, which minimizes the same cost function with a faster algorithm, is the conjugate gradient algorithm. You should obtain nice results with something like 30-40 iterations (look for rtk::ConjugateGradientConeBeamReconstructionFilter if you want to give it a try). Best regards, Cyril On 18/07/2017 11:17, Lotte Schyns wrote: > Hello, > > We are having problems with the SIRT reconstructions. They seem very > strange and blurry. However, other reconstructions (SART, FDK, > iterativeFDK) look perfect. I uploaded an example of a SART and a SIRT > reconstruction (same parameters) to > https://www.dropbox.com/sh/7a4bkyjg43zjmy7/AAAp4tJrk9HedMEEuIKsGYDSa?dl=0. > I also uploaded a minimalistic version of the code that I used (the > paths in CMakeLists.txt probably need to be adapted to your system). You > can alternate between SART and SIRT by changing line 143. The raw data > is also available on dropbox. I didn't use > rtkXRadRawToAttenuationImageFilter, because our projections are already > corrected for the dark field and flood field, so > (signal-dark)/(flood-dark). I just take the natural logarithm and > multiply by -1. Do you know what could be the problem with the SIRT > reconstructions? Are we using wrong parameters? Thanks for your time. > > Lotte > _______________________________________________ > Rtk-users mailing list > Rtk-users at public.kitware.com > http://public.kitware.com/mailman/listinfo/rtk-users From lotte.schyns at maastro.nl Tue Jul 18 08:02:53 2017 From: lotte.schyns at maastro.nl (Lotte Schyns) Date: Tue, 18 Jul 2017 12:02:53 +0000 Subject: [Rtk-users] SIRT Reconstruction In-Reply-To: <52c5db23-4496-14da-3b71-dd6f1b7d8148@creatis.insa-lyon.fr> References: <61aad553-6a95-e00d-ae80-669a513b7d74@maastro.nl> <9c29efa3-35a4-b20e-f91c-4c85470ba670@maastro.nl> <52c5db23-4496-14da-3b71-dd6f1b7d8148@creatis.insa-lyon.fr> Message-ID: Thanks! I will try both the SIRT with 100 iterations and the conjugate gradient method. What exactly are the weights (input 2) and input support mask in rtkConjugateGradientConeBeamReconstructionFilter? On 18-07-17 11:31, Cyril Mory wrote: > Hi Lotte, > > I had a very quick look at what you are doing. It looks fine to me, > you just need to perform way more iterations in the SIRT case. 100 > would be a good start. SIRT is more stable than SART when there are > inconsistencies in the projection data, but converges slowly. > > An alternative to SIRT, which minimizes the same cost function with a > faster algorithm, is the conjugate gradient algorithm. You should > obtain nice results with something like 30-40 iterations (look for > rtk::ConjugateGradientConeBeamReconstructionFilter if you want to give > it a try). > > Best regards, > Cyril > > > On 18/07/2017 11:17, Lotte Schyns wrote: >> Hello, >> >> We are having problems with the SIRT reconstructions. They seem very >> strange and blurry. However, other reconstructions (SART, FDK, >> iterativeFDK) look perfect. I uploaded an example of a SART and a SIRT >> reconstruction (same parameters) to >> https://www.dropbox.com/sh/7a4bkyjg43zjmy7/AAAp4tJrk9HedMEEuIKsGYDSa?dl=0. >> >> I also uploaded a minimalistic version of the code that I used (the >> paths in CMakeLists.txt probably need to be adapted to your system). You >> can alternate between SART and SIRT by changing line 143. The raw data >> is also available on dropbox. I didn't use >> rtkXRadRawToAttenuationImageFilter, because our projections are already >> corrected for the dark field and flood field, so >> (signal-dark)/(flood-dark). I just take the natural logarithm and >> multiply by -1. Do you know what could be the problem with the SIRT >> reconstructions? Are we using wrong parameters? Thanks for your time. >> >> Lotte >> _______________________________________________ >> Rtk-users mailing list >> Rtk-users at public.kitware.com >> http://public.kitware.com/mailman/listinfo/rtk-users > From cyril.mory at creatis.insa-lyon.fr Tue Jul 18 08:28:04 2017 From: cyril.mory at creatis.insa-lyon.fr (Cyril Mory) Date: Tue, 18 Jul 2017 14:28:04 +0200 Subject: [Rtk-users] SIRT Reconstruction In-Reply-To: References: <61aad553-6a95-e00d-ae80-669a513b7d74@maastro.nl> <9c29efa3-35a4-b20e-f91c-4c85470ba670@maastro.nl> <52c5db23-4496-14da-3b71-dd6f1b7d8148@creatis.insa-lyon.fr> Message-ID: <9632ef3c-38fd-636f-c690-a008c7ed69e3@creatis.insa-lyon.fr> The weights are a way to adapt the cost function if you know that some pixels of your projection data are more reliable than others (you then give them a larger weight than the others). This is called Weighted Least Squares (WLS), you can easily find a lot of theory on it. IYou should only do this if you have a reliable way to estimate the variance of the noise on your projection data, and use the inverse variances as weights. There is one weight per pixel, so the weights image should be exactly the same size as the full projection dataset. Note that this input is mandatory for the rtk::ConjugateGradientConeBeamReconstructionFilter, so if you do not want to use it, you still have to generate an image full of ones and pass it as the weights. Clearly that behavior is not optimal, but that is the way it works at the moment. The support mask enforces a support constraint. It should be a binary volume (ones in the ROI you are interested in reconstructing, zeros outside). If it is provided, over the course of the iterations, the iterates are multiplied by the mask, leaving the voxels inside the ROI unchanged, and setting the ones outside the ROI to zero. Mathematically, it is a special case of preconditioner (a diagonal, binary preconditioner). Not passing a mask yields the same result (but faster) as passing a mask full of ones. Hope this helps, Cyril PS: If at some point you decide to use the "Weights" input of the conjugate gradient filter, in order to perform WLS reconstructions, do write another email on this list: I have a lot of advice to share on this topic. On 18/07/2017 14:02, Lotte Schyns wrote: > Thanks! I will try both the SIRT with 100 iterations and the conjugate > gradient method. What exactly are the weights (input 2) and input > support mask in rtkConjugateGradientConeBeamReconstructionFilter? > > On 18-07-17 11:31, Cyril Mory wrote: >> Hi Lotte, >> >> I had a very quick look at what you are doing. It looks fine to me, >> you just need to perform way more iterations in the SIRT case. 100 >> would be a good start. SIRT is more stable than SART when there are >> inconsistencies in the projection data, but converges slowly. >> >> An alternative to SIRT, which minimizes the same cost function with a >> faster algorithm, is the conjugate gradient algorithm. You should >> obtain nice results with something like 30-40 iterations (look for >> rtk::ConjugateGradientConeBeamReconstructionFilter if you want to give >> it a try). >> >> Best regards, >> Cyril >> >> >> On 18/07/2017 11:17, Lotte Schyns wrote: >>> Hello, >>> >>> We are having problems with the SIRT reconstructions. They seem very >>> strange and blurry. However, other reconstructions (SART, FDK, >>> iterativeFDK) look perfect. I uploaded an example of a SART and a SIRT >>> reconstruction (same parameters) to >>> https://www.dropbox.com/sh/7a4bkyjg43zjmy7/AAAp4tJrk9HedMEEuIKsGYDSa?dl=0. >>> >>> I also uploaded a minimalistic version of the code that I used (the >>> paths in CMakeLists.txt probably need to be adapted to your system). You >>> can alternate between SART and SIRT by changing line 143. The raw data >>> is also available on dropbox. I didn't use >>> rtkXRadRawToAttenuationImageFilter, because our projections are already >>> corrected for the dark field and flood field, so >>> (signal-dark)/(flood-dark). I just take the natural logarithm and >>> multiply by -1. Do you know what could be the problem with the SIRT >>> reconstructions? Are we using wrong parameters? Thanks for your time. >>> >>> Lotte >>> _______________________________________________ >>> Rtk-users mailing list >>> Rtk-users at public.kitware.com >>> http://public.kitware.com/mailman/listinfo/rtk-users > _______________________________________________ > Rtk-users mailing list > Rtk-users at public.kitware.com > http://public.kitware.com/mailman/listinfo/rtk-users From simon.rit at creatis.insa-lyon.fr Wed Jul 19 16:15:28 2017 From: simon.rit at creatis.insa-lyon.fr (Simon Rit) Date: Wed, 19 Jul 2017 22:15:28 +0200 Subject: [Rtk-users] MV-CBCT In-Reply-To: <135003197.1171368.1500196271587@mail.yahoo.com> References: <135003197.1171368.1500196271587.ref@mail.yahoo.com> <135003197.1171368.1500196271587@mail.yahoo.com> Message-ID: Dear Faterme, I don't know anyone who has done that before. I did not even know that the same database format was used for MV images. Looking at the file you've sent, the MyFRAME1.DBF has only zeros in the U_CENTRE and V_CENTRE columns which suggests that the system is not calibrated. This is consistent with the problem you describe, which indicates a geometry problem. Good luck, Simon On Sun, Jul 16, 2017 at 11:11 AM, fateme shahedi via Rtk-users < rtk-users at public.kitware.com> wrote: > Dear RTK users and developers > I am new to RTK. I have some trouble getting a proper reconstruction. I > want to use EPID mounted on Elekta linear accelerator to get MV-CBCT > images. I have 120 projection images (in his format) scanned over (0-357) > degree of the phantom. The phantom is containing 5 rods of different > materials (titanium, aluminum, acrylic, air and polyethylene). The > measurement geometry is as bellow; > - detector size= 1024*1024 pixels > - size of each pixel=0.4mm > -size of each pixel at the isocenter=0.25mm > -source-to-detector distance=157cm > -source-to-isocenter distance=100cm > I used the rtkfdk as bellow; > [sn at localhost workspace]$ rtkelektasynergygeometry --image_db > MyIMAGE1.DBF --frame_db MyFRAME1.DBF --dicom_uid 1 -o > elektaGeometry > [sn at localhost workspace]$ rtkfdk --lowmem --geometry elektaGeometry > --path img_1/ --regexp '.*.his' --output slice50.0.mha --verbose > --spacing 0.25,0.25,0.25 --dimension 1024,1,1024 --origin > -127.875,50,-127.875. > I display .mha images with VV , it just show the central rod (air) and > doesn't show the others ( although the projections are megavoltage, I get > result from some other open-source software for CBCT). I attached the > geometry file (frame and image.DBF) with the mail. I need your help > to know what went wrong. > I really appreciate any help you can provide. > > best regards. > fateme. > > _______________________________________________ > Rtk-users mailing list > Rtk-users at public.kitware.com > http://public.kitware.com/mailman/listinfo/rtk-users > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From lotte.schyns at maastro.nl Mon Jul 24 06:21:36 2017 From: lotte.schyns at maastro.nl (Lotte Schyns) Date: Mon, 24 Jul 2017 10:21:36 +0000 Subject: [Rtk-users] SIRT Reconstruction In-Reply-To: <9632ef3c-38fd-636f-c690-a008c7ed69e3@creatis.insa-lyon.fr> References: <61aad553-6a95-e00d-ae80-669a513b7d74@maastro.nl> <9c29efa3-35a4-b20e-f91c-4c85470ba670@maastro.nl> <52c5db23-4496-14da-3b71-dd6f1b7d8148@creatis.insa-lyon.fr> <9632ef3c-38fd-636f-c690-a008c7ed69e3@creatis.insa-lyon.fr> Message-ID: <763665cf-80d7-261a-32b2-4fa4700d4e4d@maastro.nl> Hi Cyril. I performed a SIRT reconstruction with 100 iterations as you suggested. After a whopping 80 hours of calculation time on 64 cores, the result was a bit disappointing (in the dropbox: https://www.dropbox.com/sh/7a4bkyjg43zjmy7/AAAp4tJrk9HedMEEuIKsGYDSa?dl=0). If anything, it looks worse than 3 iterations. Do you think we need even more iterations? Another question, you said the conjugate gradient method minimizes the same cost function as the SIRT method, but in the doxygen documentation I find that the conjugate gradient is similar to SART (not SIRT). Could you elaborate a bit on this please? Thanks again! On 18-07-17 14:28, Cyril Mory wrote: > The weights are a way to adapt the cost function if you know that some > pixels of your projection data are more reliable than others (you then > give them a larger weight than the others). This is called Weighted > Least Squares (WLS), you can easily find a lot of theory on it. IYou > should only do this if you have a reliable way to estimate the > variance of the noise on your projection data, and use the inverse > variances as weights. There is one weight per pixel, so the weights > image should be exactly the same size as the full projection dataset. > Note that this input is mandatory for the > rtk::ConjugateGradientConeBeamReconstructionFilter, so if you do not > want to use it, you still have to generate an image full of ones and > pass it as the weights. Clearly that behavior is not optimal, but that > is the way it works at the moment. > > The support mask enforces a support constraint. It should be a binary > volume (ones in the ROI you are interested in reconstructing, zeros > outside). If it is provided, over the course of the iterations, the > iterates are multiplied by the mask, leaving the voxels inside the ROI > unchanged, and setting the ones outside the ROI to zero. > Mathematically, it is a special case of preconditioner (a diagonal, > binary preconditioner). Not passing a mask yields the same result (but > faster) as passing a mask full of ones. > > Hope this helps, > Cyril > > PS: If at some point you decide to use the "Weights" input of the > conjugate gradient filter, in order to perform WLS reconstructions, do > write another email on this list: I have a lot of advice to share on > this topic. > > On 18/07/2017 14:02, Lotte Schyns wrote: >> Thanks! I will try both the SIRT with 100 iterations and the conjugate >> gradient method. What exactly are the weights (input 2) and input >> support mask in rtkConjugateGradientConeBeamReconstructionFilter? >> >> On 18-07-17 11:31, Cyril Mory wrote: >>> Hi Lotte, >>> >>> I had a very quick look at what you are doing. It looks fine to me, >>> you just need to perform way more iterations in the SIRT case. 100 >>> would be a good start. SIRT is more stable than SART when there are >>> inconsistencies in the projection data, but converges slowly. >>> >>> An alternative to SIRT, which minimizes the same cost function with a >>> faster algorithm, is the conjugate gradient algorithm. You should >>> obtain nice results with something like 30-40 iterations (look for >>> rtk::ConjugateGradientConeBeamReconstructionFilter if you want to give >>> it a try). >>> >>> Best regards, >>> Cyril >>> >>> >>> On 18/07/2017 11:17, Lotte Schyns wrote: >>>> Hello, >>>> >>>> We are having problems with the SIRT reconstructions. They seem very >>>> strange and blurry. However, other reconstructions (SART, FDK, >>>> iterativeFDK) look perfect. I uploaded an example of a SART and a SIRT >>>> reconstruction (same parameters) to >>>> https://www.dropbox.com/sh/7a4bkyjg43zjmy7/AAAp4tJrk9HedMEEuIKsGYDSa?dl=0. >>>> >>>> >>>> I also uploaded a minimalistic version of the code that I used (the >>>> paths in CMakeLists.txt probably need to be adapted to your >>>> system). You >>>> can alternate between SART and SIRT by changing line 143. The raw data >>>> is also available on dropbox. I didn't use >>>> rtkXRadRawToAttenuationImageFilter, because our projections are >>>> already >>>> corrected for the dark field and flood field, so >>>> (signal-dark)/(flood-dark). I just take the natural logarithm and >>>> multiply by -1. Do you know what could be the problem with the SIRT >>>> reconstructions? Are we using wrong parameters? Thanks for your time. >>>> >>>> Lotte >>>> _______________________________________________ >>>> Rtk-users mailing list >>>> Rtk-users at public.kitware.com >>>> http://public.kitware.com/mailman/listinfo/rtk-users >> _______________________________________________ >> Rtk-users mailing list >> Rtk-users at public.kitware.com >> http://public.kitware.com/mailman/listinfo/rtk-users > From cyril.mory at creatis.insa-lyon.fr Thu Jul 27 02:24:22 2017 From: cyril.mory at creatis.insa-lyon.fr (Cyril Mory) Date: Thu, 27 Jul 2017 08:24:22 +0200 Subject: [Rtk-users] SIRT Reconstruction In-Reply-To: <763665cf-80d7-261a-32b2-4fa4700d4e4d@maastro.nl> Message-ID: <5a6fb32b-07f4-4c46-93af-87287ce17b5e@email.android.com> An HTML attachment was scrubbed... URL: From hougeamm at 126.com Sun Jul 30 08:49:59 2017 From: hougeamm at 126.com (=?GBK?B?uu645w==?=) Date: Sun, 30 Jul 2017 20:49:59 +0800 (CST) Subject: [Rtk-users] About the FirstReconstruction Message-ID: <790efcc2.24fa.15d938bd09d.Coremail.hougeamm@126.com> Hello Everyone, How can I solve the error "Linking CXX executable FirstReconstruction CMakeFiles/FirstReconstruction.dir/FirstReconstruction.cxx.o: In function `rtk::FDKWeightProjectionFilter, itk::Image >::BeforeThreadedGenerateData()': FirstReconstruction.cxx:(.text._ZN3rtk25FDKWeightProjectionFilterIN3itk5ImageIfLj3EEES3_E26BeforeThreadedGenerateDataEv[rtk::FDKWeightProjectionFilter, itk::Image >::BeforeThreadedGenerateData()]+0x49): undefined reference to `rtk::ThreeDCircularProjectionGeometry::GetAngularGaps()' "? Thank you very much! -------------- next part -------------- An HTML attachment was scrubbed... URL: From hougeamm at 126.com Sun Jul 30 09:34:21 2017 From: hougeamm at 126.com (=?GBK?B?uu645w==?=) Date: Sun, 30 Jul 2017 21:34:21 +0800 (CST) Subject: [Rtk-users] About the FirstReconstruction 1 Message-ID: <4ef92ea1.271e.15d93b46e74.Coremail.hougeamm@126.com> This problem can be solved by modify the ITK and RTK version in the cmake. I set them as follows: ITK: /usr/local/lib/cmake/ITK-4.10 RTK: /usr/local/lib/cmake/RTK-1.1 The compile and link can work properly. -------------- next part -------------- An HTML attachment was scrubbed... URL: From hougeamm at 126.com Sun Jul 30 09:51:37 2017 From: hougeamm at 126.com (=?GBK?B?uu645w==?=) Date: Sun, 30 Jul 2017 21:51:37 +0800 (CST) Subject: [Rtk-users] About the FirstReconstruction Message-ID: <1b2552dd.2811.15d93c43b48.Coremail.hougeamm@126.com> Hello Everyone, The error : CMakeFiles/FirstReconstruction.dir/FirstReconstruction.cxx.o: In function `rtk::FDKWeightProjectionFilter, itk::Image >::BeforeThreadedGenerateData()': FirstReconstruction.cxx:(.text._ZN3rtk25FDKWeightProjectionFilterIN3itk5ImageIfLj3EEES3_E26BeforeThreadedGenerateDataEv[rtk::FDKWeightProjectionFilter, itk::Image >::BeforeThreadedGenerateData()]+0x49): undefined reference to `rtk::ThreeDCircularProjectionGeometry::GetAngularGaps()' "? can be solved as following: In the cmake interface modify the version of ITK and RTK In my experiment I set ITK as : /usr/local/lib/cmake/ITK-4.7 RTK as: /usr/local/lib/cmake/RTK-1.1 Then configure and make. All done. And the FirstReconstruction ran normally and we can get the result output.mha Thank you very much! Houge -------------- next part -------------- An HTML attachment was scrubbed... URL: