123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- /*
- %% Author: Rodrigo de Barros Vimieiro
- % Date: March, 2019
- % rodrigo.vimieiro@gmail.com
- % =========================================================================
- %{
- % -------------------------------------------------------------------------
- % projectionDDb_mex_CUDA(data3d,param)
- % -------------------------------------------------------------------------
- % DESCRIPTION:
- % This function calculates the volume projection based on the
- % Branchless Distance-Driven principle.
- % The geometry is for DBT with half cone-beam. All parameters are set
- % in "ParameterSettings" code.
- %
- % INPUT:
- %
- % - data3d = 3D volume for projection
- % - param = Parameter of all geometry
- % - nProj = projection number to be projected
- %
- % OUTPUT:
- %
- % - proj = projections for each angle.
- %
- % Reference:
- % - Branchless Distance Driven Projection and Backprojection,
- % Samit Basu and Bruno De Man (2006)
- % - GPU Acceleration of Branchless Distance Driven Projection and
- % Backprojection, Liu et al (2016)
- % - GPU-Based Branchless Distance-Driven Projection and Backprojection,
- % Liu et al (2017)
- % - A GPU Implementation of Distance-Driven Computed Tomography,
- % Ryan D. Wagner (2017)
- % ---------------------------------------------------------------------
- % Copyright (C) <2019> <Rodrigo de Barros Vimieiro>
- %
- % This program is free software: you can redistribute it and/or modify
- % it under the terms of the GNU General Public License as published by
- % the Free Software Foundation, either version 3 of the License, or
- % (at your option) any later version.
- %
- % This program is distributed in the hope that it will be useful,
- % but WITHOUT ANY WARRANTY; without even the implied warranty of
- % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- % GNU General Public License for more details.
- %
- % You should have received a copy of the GNU General Public License
- % along with this program. If not, see <http://www.gnu.org/licenses/>.
- %}
- % =========================================================================
- %% 3-D Projection Branchless Distance Driven Code
- */
- #include "projectionDDb_mex_cuda.h"
- /****************************************************************************
- * function: mexFunction() - Matlab interface function. *
- * INPUTS: *
- * nlhs - Number of expected output mxArrays, specified as an integer. *
- * plhs[] - Array of pointers to the expected mxArray output arguments. *
- * nrhs - Number of input mxArrays, specified as an integer. *
- * prhs[] - Array of pointers to the mxArray input arguments. *
- ****************************************************************************/
- void mexFunction(int nlhs, mxArray *plhs[],
- int nrhs, const mxArray *prhs[]) {
- /* Check for proper number of arguments */
- if (nrhs != 3) {
- mexErrMsgIdAndTxt("MATLAB:mexcpp:nargin",
- "projection_mex requires three input arguments.");
- }
- if (nlhs != 1) {
- mexErrMsgIdAndTxt("MATLAB:mexcpp:nargout",
- "projection_mex requires one output argument.");
- }
- /* Check if the input is of proper type */
- if (!mxIsDouble(prhs[0])) {
- mexErrMsgIdAndTxt("MATLAB:mexcpp:typeargin",
- "First argument has to be double.");
- }
- if (!mxIsStruct(prhs[1])) {
- mexErrMsgIdAndTxt("MATLAB:mexcpp:typeargin",
- "Second argument has to be a struct.");
- }
- if (!mxIsDouble(prhs[2])) {
- mexErrMsgIdAndTxt("MATLAB:mexcpp:typeargin",
- "Third argument has to be double.");
- }
- double* const pVolume = (double*)(mxGetPr(prhs[0]));
- double* const pTubeAngleD = mxGetPr(mxGetField(prhs[1], 0, "tubeDeg"));
- double* const pDetAngleD = mxGetPr(mxGetField(prhs[1], 0, "detectorDeg"));
-
- const int unsigned nProj = (const int)mxGetScalar(mxGetField(prhs[1], 0, "nProj"));
- const int unsigned nPixX = (const int)mxGetScalar(mxGetField(prhs[1], 0, "nx"));
- const int unsigned nPixY = (const int)mxGetScalar(mxGetField(prhs[1], 0, "ny"));
- const int unsigned nSlices = (const int)mxGetScalar(mxGetField(prhs[1], 0, "nz"));
- const int unsigned nDetX = (const int)mxGetScalar(mxGetField(prhs[1], 0, "nu"));
- const int unsigned nDetY = (const int)mxGetScalar(mxGetField(prhs[1], 0, "nv"));
- const double dx = (const double)mxGetScalar(mxGetField(prhs[1], 0, "dx"));
- const double dy = (const double)mxGetScalar(mxGetField(prhs[1], 0, "dy"));
- const double dz = (const double)mxGetScalar(mxGetField(prhs[1], 0, "dz"));
- const double du = (const double)mxGetScalar(mxGetField(prhs[1], 0, "du"));
- const double dv = (const double)mxGetScalar(mxGetField(prhs[1], 0, "dv"));
- const double DSD = (const double)mxGetScalar(mxGetField(prhs[1], 0, "DSD"));
- const double DDR = (const double)mxGetScalar(mxGetField(prhs[1], 0, "DDR"));
- const double DAG = (const double)mxGetScalar(mxGetField(prhs[1], 0, "DAG"));
- const double idXProj = (const double)mxGetScalar(prhs[2]);
- mwSize NRow = mxGetM(prhs[0]);
- mwSize NCol = mxGetN(prhs[0]);
- mwSize NElemVol = mxGetNumberOfElements(prhs[0]);
- /* Check if the input is in proper size */
- if (NRow != nPixY) {
- mexErrMsgIdAndTxt("MATLAB:mexcpp:typeargin",
- "First argument needs to have the same number of rows as in the configuration file.");
- }
- if (NCol/nSlices != nPixX) {
- mexErrMsgIdAndTxt("MATLAB:mexcpp:typeargin",
- "First argument needs to have the same number of columns as in the configuration file.");
- }
- if (idXProj >= nProj ){
- mexErrMsgIdAndTxt("MATLAB:mexcpp:typeargin",
- "Third argument needs to be less than the proj number (0->nproj-1)");
- }
- // Cast double vectors to single
- double* const pTubeAngle = (double*)mxMalloc(nProj * sizeof(double));
- double* const pDetAngle = (double*)mxMalloc(nProj * sizeof(double));
- for (unsigned int n = 0; n < nProj; n++) {
- pTubeAngle[n] = (double)pTubeAngleD[n];
- pDetAngle[n] = (double)pDetAngleD[n];
- }
- //mexPrintf("Nx:%d Ny:%d Nz:%d \nNu:%d Nv:%d \nDx:%.2f Dy:%.2f Dz:%.2f \nDu:%.2f Dv:%.2f \nDSD:%.2f DDR:%.2f \n", nPixX, nPixY, nSlices, nDetX, nDetY, dx, dy, dz, du, dv, DSD, DDR);
- // Output memory allocation
- mwSize dims[3] = { nDetY,nDetX,nProj };
- plhs[0] = mxCreateNumericArray(3, dims, mxDOUBLE_CLASS, mxREAL);
- double* const pProj = (double*)mxGetData(plhs[0]);
- projectionDDb(pProj, pVolume, pTubeAngle, pDetAngle, idXProj, nProj, nPixX, nPixY, nSlices, nDetX, nDetY, dx, dy, dz, du, dv, DSD, DDR, DAG);
- mxFree(pTubeAngle);
- mxFree(pDetAngle);
- return;
- }
|