#include <projector.h>
Inheritance diagram for EMAN::PawelProjector:
Public Member Functions | |
EMData * | project3d (EMData *image) const |
Project an 3D image into a 2D image. | |
EMData * | backproject3d (EMData *image) const |
Back-project a 2D image into a 3D image. | |
string | get_name () const |
Get the projector's name. | |
string | get_desc () const |
TypeDict | get_param_types () const |
Get processor parameter information in a dictionary. | |
Static Public Member Functions | |
Projector * | NEW () |
Static Public Attributes | |
const string | NAME = "pawel" |
Private Member Functions | |
void | prepcubes (int nx, int ny, int nz, int ri, Vec3i origin, int &nn, IPCube *ipcube=NULL) const |
Definition at line 248 of file projector.h.
|
Back-project a 2D image into a 3D image.
Implements EMAN::Projector. Definition at line 1967 of file projector.cpp. References anglelist, EMAN::Transform::at(), EMDeleteArray(), EMAN::PawelProjector::IPCube::end, EMAN::EMData::get_data(), EMAN::Util::get_min(), EMAN::Transform::get_rotation(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::Dict::has_key(), images, EMAN::PawelProjector::IPCube::loc, LOGERR, nn(), NullPointerException, nx, ny, phi, prepcubes(), EMAN::EMData::set_size(), EMAN::Dict::size(), EMAN::PawelProjector::IPCube::start, theta, EMAN::EMData::to_zero(), EMAN::EMData::update(), EMAN::Vec3f, and EMAN::Vec3i. 01968 { 01969 01970 float *images; 01971 01972 if (!imagestack) { 01973 return 0; 01974 } 01975 int ri; 01976 int nx = imagestack->get_xsize(); 01977 int ny = imagestack->get_ysize(); 01978 // int nslices = imagestack->get_zsize(); 01979 int dim = Util::get_min(nx,ny); 01980 images = imagestack->get_data(); 01981 01982 Vec3i origin(0,0,0); 01983 // If a sensible origin isn't passed in, choose the middle of 01984 // the cube. 01985 if (params.has_key("origin_x")) {origin[0] = params["origin_x"];} 01986 else {origin[0] = nx/2;} 01987 if (params.has_key("origin_y")) {origin[1] = params["origin_y"];} 01988 else {origin[1] = ny/2;} 01989 if (params.has_key("origin_z")) {origin[1] = params["origin_z"];} 01990 else {origin[2] = dim/2;} 01991 01992 if (params.has_key("radius")) {ri = params["radius"];} 01993 else {ri = dim/2 - 1;} 01994 01995 // Determine the number of rows (x-lines) within the radius 01996 int nn = -1; 01997 prepcubes(nx, ny, dim, ri, origin, nn); 01998 // nn is now the number of rows-1 within the radius 01999 // so we can create and fill the ipcubes 02000 IPCube* ipcube = new IPCube[nn+1]; 02001 prepcubes(nx, ny, dim, ri, origin, nn, ipcube); 02002 02003 int nangles = 0; 02004 vector<float> anglelist; 02005 // Do we have a list of angles? 02006 if (params.has_key("anglelist")) { 02007 anglelist = params["anglelist"]; 02008 nangles = anglelist.size() / 3; 02009 } else { 02010 Transform* t3d = params["transform"]; 02011 if ( t3d == NULL ) throw NullPointerException("The transform3d object (required for projection), was not specified"); 02012 // This part was modified by David Woolford - 02013 // Before this the code worked only for SPIDER and EMAN angles, 02014 // but the framework of the Transform3D allows for a generic implementation 02015 // as specified here. 02016 Dict p = t3d->get_rotation("spider"); 02017 if(t3d) {delete t3d; t3d=0;} 02018 02019 string angletype = "SPIDER"; 02020 float phi = p["phi"]; 02021 float theta = p["theta"]; 02022 float psi = p["psi"]; 02023 anglelist.push_back(phi); 02024 anglelist.push_back(theta); 02025 anglelist.push_back(psi); 02026 nangles = 1; 02027 } 02028 02029 // End David Woolford modifications 02030 02031 // initialize return object 02032 EMData* ret = new EMData(); 02033 ret->set_size(nx, ny, dim); 02034 ret->to_zero(); 02035 02036 // loop over sets of angles 02037 for (int ia = 0; ia < nangles; ia++) { 02038 int indx = 3*ia; 02039 Dict d("type","spider","phi",anglelist[indx],"theta",anglelist[indx+1],"psi",anglelist[indx+2]); 02040 Transform rotation(d); 02041 float dm1 = rotation.at(0,0); 02042 float dm4 = rotation.at(1,0); 02043 02044 if (2*(ri+1)+1 > dim) { 02045 // Must check x and y boundaries 02046 LOGERR("backproject3d, pawel, 2*(ri+1)+1 > dim\n"); 02047 return 0; 02048 } else { 02049 // No need to check x and y boundaries 02050 for (int i = 0 ; i <= nn; i++) { 02051 int iox = (int)ipcube[i].loc[0]+origin[0]; 02052 int ioy = (int)ipcube[i].loc[1]+origin[1]; 02053 int ioz = (int)ipcube[i].loc[2]+origin[2]; 02054 02055 Vec3f vb = rotation*ipcube[i].loc + origin; 02056 for (int j = ipcube[i].start; j <= ipcube[i].end; j++) { 02057 float xbb = (j-ipcube[i].start)*dm1 + vb[0]; 02058 int iqx = (int)floor(xbb); 02059 02060 float ybb = (j-ipcube[i].start)*dm4 + vb[1]; 02061 int iqy = (int)floor(ybb); 02062 02063 float dipx = xbb - iqx; 02064 float dipy = ybb - iqy; 02065 02066 (*ret)(iox,ioy,ioz) += images(iqx,iqy,ia) 02067 + dipy*(images(iqx,iqy+1,ia)-images(iqx,iqy,ia)) 02068 + dipx*(images(iqx+1,iqy,ia)-images(iqx,iqy,ia) 02069 + dipy*(images(iqx+1,iqy+1,ia)-images(iqx+1,iqy,ia) 02070 - images(iqx,iqy+1,ia)+images(iqx,iqy,ia))); 02071 iox++; 02072 } // end for j 02073 } // end for i 02074 } // end if 02075 } // end for ia 02076 02077 ret->update(); 02078 EMDeleteArray(ipcube); 02079 return ret; 02080 }
|
|
Implements EMAN::Projector. Definition at line 259 of file projector.h. 00260 { 00261 return "Pawel Penczek's optimized real-space projection generation. Minor interpolation artifacts."; 00262 }
|
|
Get the projector's name. Each projector is indentified by unique name.
Implements EMAN::Projector. Definition at line 254 of file projector.h. 00255 {
00256 return NAME;
00257 }
|
|
Get processor parameter information in a dictionary. Each parameter has one record in the dictionary. Each record contains its name, data-type, and description.
Reimplemented from EMAN::Projector. Definition at line 269 of file projector.h. References EMAN::TypeDict::put(). 00270 { 00271 TypeDict d; 00272 d.put("transform", EMObject::TRANSFORM); 00273 d.put("origin_x", EMObject::INT); 00274 d.put("origin_y", EMObject::INT); 00275 d.put("origin_z", EMObject::INT); 00276 d.put("radius", EMObject::INT); 00277 d.put("anglelist", EMObject::FLOATARRAY); 00278 d.put("angletype", EMObject::STRING); 00279 d.put("theta", EMObject::FLOAT); 00280 d.put("psi", EMObject::FLOAT); 00281 return d; 00282 }
|
|
Definition at line 264 of file projector.h. 00265 { 00266 return new PawelProjector(); 00267 }
|
|
Definition at line 533 of file projector.cpp. References EMAN::PawelProjector::IPCube::end, EMAN::PawelProjector::IPCube::loc, nn(), EMAN::PawelProjector::IPCube::start, t, and EMAN::Vec3i. Referenced by backproject3d(), and project3d(). 00534 { 00535 const float r = float(ri*ri); 00536 const int ldpx = origin[0]; 00537 const int ldpy = origin[1]; 00538 const int ldpz = origin[2]; 00539 float t; 00540 nn = -1; 00541 for (int i1 = 0; i1 < nz; i1++) { 00542 t = float(i1 - ldpz); 00543 const float xx = t*t; 00544 for (int i2 = 0; i2 < ny; i2++) { 00545 t = float(i2 - ldpy); 00546 const float yy = t*t + xx; 00547 bool first = true; 00548 for (int i3 = 0; i3 < nz; i3++) { 00549 t = float(i3 - ldpx); 00550 const float rc = t*t + yy; 00551 if (first) { 00552 // first pixel on this line 00553 if (rc > r) continue; 00554 first = false; 00555 nn++; 00556 if (ipcube != NULL) { 00557 ipcube[nn].start = i3; 00558 ipcube[nn].end = i3; 00559 ipcube[nn].loc[0] = i3 - ldpx; 00560 ipcube[nn].loc[1] = i2 - ldpy; 00561 ipcube[nn].loc[2] = i1 - ldpz; 00562 } 00563 } else { 00564 // second or later pixel on this line 00565 if (ipcube != NULL) { 00566 if (rc <= r) ipcube[nn].end = i3; 00567 } 00568 } 00569 } 00570 } 00571 } 00572 }
|
|
Project an 3D image into a 2D image.
Implements EMAN::Projector. Definition at line 725 of file projector.cpp. References EMDeleteArray(), EMAN::PawelProjector::IPCube::end, EMAN::Transform::get_matrix3_row(), EMAN::Util::get_min(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), EMAN::Dict::has_key(), EMAN::PawelProjector::IPCube::loc, LOGERR, nn(), NullPointerException, nx, ny, prepcubes(), EMAN::EMData::set_size(), EMAN::PawelProjector::IPCube::start, EMAN::EMData::to_zero(), EMAN::EMData::update(), EMAN::Vec3f, and EMAN::Vec3i. 00726 { 00727 if (!image) { 00728 return 0; 00729 } 00730 int ri; 00731 int nx = image->get_xsize(); 00732 int ny = image->get_ysize(); 00733 int nz = image->get_zsize(); 00734 int dim = Util::get_min(nx,ny,nz); 00735 if (nz == 1) { 00736 LOGERR("The PawelProjector needs a volume!"); 00737 return 0; 00738 } 00739 Vec3i origin(0,0,0); 00740 // If a sensible origin isn't passed in, choose the middle of 00741 // the cube. 00742 if (params.has_key("origin_x")) {origin[0] = params["origin_x"];} 00743 else {origin[0] = nx/2;} 00744 if (params.has_key("origin_y")) {origin[1] = params["origin_y"];} 00745 else {origin[1] = ny/2;} 00746 if (params.has_key("origin_z")) {origin[2] = params["origin_z"];} 00747 else {origin[2] = nz/2;} 00748 00749 if (params.has_key("radius")) {ri = params["radius"];} 00750 else {ri = dim/2 - 1;} 00751 00752 // Determine the number of rows (x-lines) within the radius 00753 int nn = -1; 00754 prepcubes(nx, ny, nz, ri, origin, nn); 00755 // nn is now the number of rows-1 within the radius 00756 // so we can create and fill the ipcubes 00757 IPCube* ipcube = new IPCube[nn+1]; 00758 prepcubes(nx, ny, nz, ri, origin, nn, ipcube); 00759 00760 Transform* rotation = params["transform"]; 00761 int nangles = 0; 00762 vector<float> anglelist; 00763 // Do we have a list of angles? 00764 /* 00765 if (params.has_key("anglelist")) { 00766 anglelist = params["anglelist"]; 00767 nangles = anglelist.size() / 3; 00768 } else {*/ 00769 00770 if ( rotation == NULL ) throw NullPointerException("The transform3d object (required for projection), was not specified"); 00771 /* 00772 Dict p = t3d->get_rotation("spider"); 00773 00774 string angletype = "SPIDER"; 00775 float phi = p["phi"]; 00776 float theta = p["theta"]; 00777 float psi = p["psi"]; 00778 anglelist.push_back(phi); 00779 anglelist.push_back(theta); 00780 anglelist.push_back(psi); 00781 */ 00782 nangles = 1; 00783 //} 00784 00785 // initialize return object 00786 EMData* ret = new EMData(); 00787 ret->set_size(nx, ny, nangles); 00788 ret->to_zero(); 00789 00790 // loop over sets of angles 00791 for (int ia = 0; ia < nangles; ia++) { 00792 //int indx = 3*ia; 00793 //Dict d("type","spider","phi",anglelist[indx],"theta",anglelist[indx+1],"psi",anglelist[indx+2]); 00794 //Transform rotation(d); 00795 if (2*(ri+1)+1 > dim) { 00796 // Must check x and y boundaries 00797 for (int i = 0 ; i <= nn; i++) { 00798 int k = ipcube[i].loc[1] + origin[1]; 00799 Vec3f vb = ipcube[i].loc*(*rotation) + origin; 00800 for (int j = ipcube[i].start; j <= ipcube[i].end; j++) { 00801 // check for pixels out-of-bounds 00802 int iox = int(vb[0]); 00803 if ((iox >= 0) && (iox < nx-1)) { 00804 int ioy = int(vb[1]); 00805 if ((ioy >= 0) && (ioy < ny-1)) { 00806 int ioz = int(vb[2]); 00807 if ((ioz >= 0) && (ioz < nz-1)) { 00808 // real work for pixels in bounds 00809 float dx = vb[0] - iox; 00810 float dy = vb[1] - ioy; 00811 float dz = vb[2] - ioz; 00812 float a1 = (*image)(iox,ioy,ioz); 00813 float a2 = (*image)(iox+1,ioy,ioz) - a1; 00814 float a3 = (*image)(iox,ioy+1,ioz) - a1; 00815 float a4 = (*image)(iox,ioy,ioz+1) - a1; 00816 float a5 = -a2 -(*image)(iox,ioy+1,ioz) 00817 + (*image)(iox+1,ioy+1,ioz); 00818 float a61 = -(*image)(iox,ioy,ioz+1) 00819 + (*image)(iox+1,ioy,ioz+1); 00820 float a6 = -a2 + a61; 00821 float a7 = -a3 - (*image)(iox,ioy,ioz+1) 00822 + (*image)(iox,ioy+1,ioz+1); 00823 float a8 = -a5 - a61 - (*image)(iox,ioy+1,ioz+1) 00824 + (*image)(iox+1,ioy+1,ioz+1); 00825 (*ret)(j,k,ia) += a1 + dz*(a4 + a6*dx 00826 + (a7 + a8*dx)*dy) 00827 + a3*dy + dx*(a2 + a5*dy); 00828 } 00829 } 00830 } 00831 vb += rotation->get_matrix3_row(0); 00832 } 00833 } 00834 00835 } else { 00836 // No need to check x and y boundaries 00837 for (int i = 0 ; i <= nn; i++) { 00838 int k = ipcube[i].loc[1] + origin[1]; 00839 Vec3f vb = ipcube[i].loc*(*rotation) + origin; 00840 for (int j = ipcube[i].start; j <= ipcube[i].end; j++) { 00841 int iox = int(vb[0]); 00842 int ioy = int(vb[1]); 00843 int ioz = int(vb[2]); 00844 float dx = vb[0] - iox; 00845 float dy = vb[1] - ioy; 00846 float dz = vb[2] - ioz; 00847 float a1 = (*image)(iox,ioy,ioz); 00848 float a2 = (*image)(iox+1,ioy,ioz) - a1; 00849 float a3 = (*image)(iox,ioy+1,ioz) - a1; 00850 float a4 = (*image)(iox,ioy,ioz+1) - a1; 00851 float a5 = -a2 -(*image)(iox,ioy+1,ioz) 00852 + (*image)(iox+1,ioy+1,ioz); 00853 float a61 = -(*image)(iox,ioy,ioz+1) 00854 + (*image)(iox+1,ioy,ioz+1); 00855 float a6 = -a2 + a61; 00856 float a7 = -a3 - (*image)(iox,ioy,ioz+1) 00857 + (*image)(iox,ioy+1,ioz+1); 00858 float a8 = -a5 - a61 - (*image)(iox,ioy+1,ioz+1) 00859 + (*image)(iox+1,ioy+1,ioz+1); 00860 (*ret)(j,k,ia) += a1 + dz*(a4 + a6*dx 00861 + (a7 + a8*dx)*dy) 00862 + a3*dy + dx*(a2 + a5*dy); 00863 vb += rotation->get_matrix3_row(0); 00864 } 00865 } 00866 } 00867 } 00868 ret->update(); 00869 EMDeleteArray(ipcube); 00870 if(rotation) {delete rotation; rotation=0;} 00871 return ret; 00872 }
|
|
Definition at line 51 of file projector.cpp. |