void GVFplugin::domenu(const QString &menu_name, V3DPluginCallback2 &callback, QWidget *parent) { if (menu_name == tr("Gradient vector flow based Segmentation")) { // the GVF function wants a pointer to a Vol3DSimple, which I haven't seen before. // this code below generates it (take from plugin_FL_cellseg) // check what's up with the current window: is there a valid image pointer? v3dhandle curwin = callback.currentImageWindow(); if (!curwin) { v3d_msg("Please open an image."); return; } Image4DSimple* subject = callback.getImage(curwin); QString m_InputFileName = callback.getImageName(curwin); if (!subject) { QMessageBox::information(0, "", QObject::tr("No image is open.")); return; } if (subject->getDatatype()!=V3D_UINT8) { QMessageBox::information(0, "", QObject::tr("This demo program only supports 8-bit data. Your current image data type is not supported.")); return; } V3DLONG sz0 = subject->getXDim(); V3DLONG sz1 = subject->getYDim(); V3DLONG sz2 = subject->getZDim(); V3DLONG sz3 = subject->getCDim(); Image4DProxy<Image4DSimple> pSub(subject); V3DLONG channelsz = sz0*sz1*sz2; float *pLabel = 0; unsigned char *pData = 0; gvfsegPara segpara; // set these fields one at a time: segpara.diffusionIteration= 5; segpara.fusionThreshold = 10; segpara.minRegion = 10; segpara.sigma = 3; // doesn't seem to be used in the actual function? //input parameters bool ok1; int c=1; if (sz3>1) //only need to ask if more than one channel { c = QInputDialog::getInteger(parent, "Channel", "Choose channel for segmentation:", 1, 1, sz3, 1, &ok1); c = c-1; //channels are indexed to 0 in Image4DSimple->getRawDataAtChannel if (!ok1) return; } // read in parameters segpara.diffusionIteration = QInputDialog::getInteger(parent, "Diffusion Iterations", "Choose Number of Diffusion Iterations:", 5, 1, 10, 1, &ok1); if (!ok1) return; segpara.fusionThreshold = QInputDialog::getInteger(parent, "Fusion Threshold", "Choose Fusion Threshold :", 2, 1, 10, 1, &ok1); if (!ok1) return; segpara.minRegion= QInputDialog::getInteger(parent, "Minimum Region", "Choose Minimum Region Size (voxels):", 10, 1, 1000, 1, &ok1); if (!ok1) return; // allocate memory for the images Vol3DSimple <unsigned char> * tmp_inimg = 0; Vol3DSimple <USHORTINT16> * tmp_outimg = 0; try { tmp_inimg = new Vol3DSimple <unsigned char> (sz0, sz1, sz2); tmp_outimg = new Vol3DSimple <USHORTINT16> (sz0, sz1, sz2); } catch (...) { v3d_msg("Unable to allocate memory for processing."); if (tmp_inimg) {delete tmp_inimg; tmp_inimg=0;} if (tmp_outimg) {delete tmp_outimg; tmp_outimg=0;} return; } //copy image data into our new memory memcpy((void *)tmp_inimg->getData1dHandle(), (void *)subject->getRawDataAtChannel(c), sz0*sz1*sz2); //now do computation //bool b_res = gvfCellSeg(img3d, outimg3d, segpara); bool b_res = gvfCellSeg(tmp_inimg, tmp_outimg, segpara); // clear out temporary space if (tmp_inimg) {delete tmp_inimg; tmp_inimg=0;} if (!b_res) { v3d_msg("image segmentation using gvfCellSeg() failed \n"); } else { // now display the results // parameters for the new image data V3DLONG new_sz0 = tmp_outimg->sz0(); V3DLONG new_sz1 = tmp_outimg->sz1(); V3DLONG new_sz2 = tmp_outimg->sz2(); V3DLONG new_sz3 = 1; V3DLONG tunits = new_sz0*new_sz1*new_sz2*new_sz3; // USHORTINT16 * outvol1d = new USHORTINT16 [tunits]; // USHORTINT16 * tmpImg_d1d = (USHORTINT16 *)(tmp_outimg->getData1dHandle()); memcpy((void *)outvol1d, (void *)tmp_outimg->getData1dHandle(), tunits*sizeof(USHORTINT16)); if (tmp_outimg) {delete tmp_outimg; tmp_outimg=0;} //free the space immediately for better use of memory Image4DSimple p4DImage; p4DImage.setData((unsigned char*)outvol1d, sz0, sz1, sz2, 1, V3D_UINT16); v3dhandle newwin = callback.newImageWindow(); callback.setImage(newwin, &p4DImage); callback.setImageName(newwin, QString("Segmented Image")); callback.updateImageWindow(newwin); } return; } else { v3d_msg(tr("A plugin for cell segmentation using Gradient Vector Flow. " "Developed based on the source code developed by Tianming Liu, Fuhui Long, and Hanchuan Peng (2010-2014)")); } }
//void startVesselTracing ( V3DPluginCallback2 &v3d, QWidget *parent ) void startVesselTracing(V3DPluginCallback2 &v3d,int xflag,int yflag,int zflag,int xbegin, int xend,int xdis,int ybegin,int yend,int ydis,int zbegin,int zend,int zdis,QString swcfile,int slipsize,int pruning_flag,int c) { v3dhandle curwin = v3d.currentImageWindow(); if (!curwin) { v3d_msg("You don't have any image open in the main window."); return; } //ensure the 3d viewer window is open; if not, then open it // v3d.open3DWindow(curwin); // get land mark list LandmarkList seedList = v3d.getLandmark(curwin); Image4DSimple* oldimg = v3d.getImage(curwin); unsigned char* data1d = oldimg->getRawDataAtChannel(c-1); ImagePixelType pixeltype = oldimg->getDatatype(); V3DLONG pagesz = oldimg->getTotalUnitNumberPerChannel(); unsigned char *output_image=0; switch (pixeltype) { case V3D_UINT8: try {output_image = new unsigned char [pagesz];} catch(...) {v3d_msg("cannot allocate memory for output_image."); return;} for(V3DLONG i = 0; i<pagesz; i++) output_image[i] = data1d[i]; break; default: v3d_msg("Invalid data type. Do nothing."); return; } V3DLONG in_sz[4]; in_sz[0] = oldimg->getXDim(); in_sz[1] = oldimg->getYDim(); in_sz[2] = oldimg->getZDim();in_sz[3] = 1; // simple_saveimage_wrapper(v3d, "temp.v3draw", (unsigned char *)output_image, in_sz, pixeltype); MOSTImage img; // set data img.setData( (unsigned char*)output_image, oldimg->getXDim(),oldimg->getYDim(),oldimg->getZDim(),oldimg->getCDim(),oldimg->getDatatype()); if ( seedList.isEmpty() ) { QTime qtime_seed; qtime_seed.start(); //img.auto_detect_seedz(seedList,img.getZDim()/2); if(xflag) { for(int i =xbegin;i<=xend;i+=xdis) img.auto_detect_seedx(seedList,i,InitThreshold,seed_size_all); // img.auto_detect_seedx(seedList,xend); } if(yflag) { for(int i =ybegin;i<=yend;i+=ydis) img.auto_detect_seedy(seedList,i,InitThreshold,seed_size_all); // img.auto_detect_seedy(seedList,yend); } if(zflag) { for(int i =zbegin;i<=zend;i+=zdis) img.auto_detect_seedz(seedList,i,InitThreshold,seed_size_all); //img.auto_detect_seedz(seedList,zend); } qDebug(" cost time seed = %g sec", qtime_seed.elapsed()*0.001); } // clear visited, only excute once static long init_flag = 0; /* if ( init_flag <= 0 ) { visited.fill( false, oldimg->getTotalUnitNumber()); init_flag ++; }*/ for(init_flag = 0;init_flag<oldimg->getTotalUnitNumber();init_flag++) { visited.push_back(false); } // converte the formate NeuronTree vt; QTime qtime; qtime.start(); vt = img.trace_seed_list(seedList, visited,InitThreshold,res_x_all,res_y_all,res_z_all,swcfile,slipsize,pruning_flag); qDebug(" cost time totol= %g sec", qtime.elapsed()*0.001); v3d_msg(QString("Now you can drag and drop the generated swc fle [%1] into Vaa3D.").arg(swcfile),1); // NeuronTree vt_old = v3d.getSWC(curwin); // visualization // v3d.setLandmark(curwin, seedList); // v3d.setSWC(curwin,vt); // v3d.pushObjectIn3DWindow(curwin); // v3d.updateImageWindow(curwin); //img.~MOSTImage(); }
void bwlabelimg(V3DPluginCallback2 &callback, QWidget *parent, int method_code) { v3dhandle curwin = callback.currentImageWindow(); if (!curwin) { v3d_msg("You don't have any image open in the main window."); return; } if (method_code!=3 && method_code!=2) { v3d_msg("Invalid BWLabel method code. You should never see this message. Report this bug to the developer"); return; } LabelImgObjectParaDialog dialog(callback, parent); if (!dialog.image) return; if (dialog.exec()!=QDialog::Accepted) return; V3DLONG ch = dialog.ch; V3DLONG th_idx = dialog.th_idx; double tt = dialog.thresh; V3DLONG volsz_thres = (dialog.b_filtersmallobjs) ? dialog.volsz : 0; //the threshold to filter out small objects int start_t = clock(); // record time Image4DSimple* subject = callback.getImage(curwin); QString m_InputFileName = callback.getImageName(curwin); if (!subject) { QMessageBox::information(0, title, QObject::tr("No image is open.")); return; } if (subject->getDatatype()!=V3D_UINT8) { QMessageBox::information(0, title, QObject::tr("This demo program only supports 8-bit data. Your current image data type is not supported.")); return; } if (th_idx==0 || th_idx==1) { double mm, vv; mean_and_std(subject->getRawDataAtChannel(ch), subject->getTotalUnitNumberPerChannel(), mm, vv); tt = (th_idx == 0) ? mm : mm+vv; v3d_msg(QString("in fast image object labeling: ch=%1 mean=%2 std=%2").arg(ch).arg(mm).arg(vv), 0); } Image4DProxy<Image4DSimple> pSub(subject); V3DLONG sz0 = subject->getXDim(); V3DLONG sz1 = subject->getYDim(); V3DLONG sz2 = subject->getZDim(); V3DLONG sz3 = subject->getCDim(); //---------------------------------------------------------------------------------------------------------------------------------- V3DLONG channelsz = sz0*sz1*sz2; unsigned short int *pLabel = 0; unsigned char *pData = 0; try { pLabel = new unsigned short int [channelsz]; pData = new unsigned char [channelsz]; } catch (...) { v3d_msg("Fail to allocate memory in Fast Object Labeling Plugin."); if (pLabel) {delete []pLabel; pLabel=0;} if (pData) {delete []pData; pData=0;} return; } unsigned char * pSubtmp = pSub.begin(); for(V3DLONG i = 0; i < channelsz; i++) { pData[i] = (pSubtmp[i]<=tt) ? 0 : 1; } // dist transform V3DLONG sz_data[4]; sz_data[0]=sz0; sz_data[1]=sz1; sz_data[2]=sz2; sz_data[3]=1; V3DLONG nobjs=0; if (method_code==3) { V3DLONG nh_code=26; //6,18,or 26 nobjs = findConnectedComponent(pData, sz_data, 3, nh_code, pLabel); } else if (method_code==2) { V3DLONG nh_code=8; //4 or 8 nobjs = findConnectedComponent(pData, sz_data, 2, nh_code, pLabel); } else { v3d_msg("Invalid BWLabelN method code. You should never see this message. Report this bug to the developer"); return; } if (pData) {delete []pData; pData=0;} if (volsz_thres>0) //filter out small objects { try { float * hh = new float [nobjs]; float * mapval = new float [nobjs]; V3DLONG j; for (j=0;j<nobjs;j++) {hh[j]=0; mapval[j]=j;} //of course, 0 also map to 0! for (j=0;j<channelsz;j++) { //pLabel[j]--; //it seems Fuhui's data is 1-based, so subtract 1. Is this correct? hh[pLabel[j]]++; } V3DLONG k=0; for (j=1;j<nobjs;j++) //start from 1 as it is the background! { if (hh[j]<volsz_thres) { mapval[j]=0; //if less than a thres, then map to 0, which is background } else { printf("Obj [%ld] = [%ld]\n", V3DLONG(j), V3DLONG(hh[j])); k++; mapval[j] = k; //otherwise map to a continous label-value } } for (j=0;j<channelsz;j++) pLabel[j] = mapval[pLabel[j]]; if (hh) {delete []hh; hh=0;} if (mapval) {delete []mapval; mapval=0;} } catch (...) { v3d_msg("Unable to allocate memory to filter small objects. Thus skip it."); } } //---------------------------------------------------------------------------------------------------------------------------------- int end_t = clock(); printf("time eclapse %d s for labeling objects!\n", (end_t-start_t)/1000000); Image4DSimple p4DImage; p4DImage.setData((unsigned char*)pLabel, sz0, sz1, sz2, 1, V3D_UINT16); v3dhandle newwin = callback.newImageWindow(); callback.setImage(newwin, &p4DImage); callback.setImageName(newwin, QString("Object-Labeled Image")); callback.updateImageWindow(newwin); }
bool autotrace(const V3DPluginArgList & input, V3DPluginArgList & output,V3DPluginCallback2 &callback) { cout<<"Welcome to MOST tracing"<<endl; unsigned int c=1; int InitThreshold = 20; seed_size_all = 20; int slipsize=20; if (input.size()>=2) { vector<char*> paras = (*(vector<char*> *)(input.at(1).p)); cout<<paras.size()<<endl; if(paras.size() >= 1) c = atoi(paras.at(0)); if(paras.size() >= 2) InitThreshold = atoi(paras.at(1)); if(paras.size() >= 3) seed_size_all = atoi(paras.at(2)); if(paras.size() >= 4) slipsize = atoi(paras.at(3)); } char * inimg_file = ((vector<char*> *)(input.at(0).p))->at(0); cout<<"ch = "<<c<<endl; cout<<"threshold = "<<InitThreshold<<endl; cout<<"inimg_file = "<<inimg_file<<endl; cout<<"seedsize = "<<seed_size_all<<endl; cout<<"slipsize = "<<slipsize<<endl; Image4DSimple *subject = callback.loadImage(inimg_file); if(!subject || !subject->valid()) { v3d_msg("Fail to load the input image.",0); if (subject) {delete subject; subject=0;} return false; } if( c < 1 || c > subject->getCDim()) { v3d_msg("Invalid channel input.",0); if (subject) {delete subject; subject=0;} return false; } V3DLONG N = subject->getXDim(); V3DLONG M = subject->getYDim(); V3DLONG P = subject->getZDim(); V3DLONG pagesz = N*M*P; int datatype = subject->getDatatype(); unsigned char *data1d = subject->getRawDataAtChannel(c-1); unsigned char *output_image=0; switch (datatype) { case V3D_UINT8: try {output_image = new unsigned char [pagesz];} catch(...) {v3d_msg("cannot allocate memory for output_image.",0); return false;} for(V3DLONG i = 0; i<pagesz; i++) output_image[i] = data1d[i]; break; default: v3d_msg("Invalid data type. Do nothing.",0); return false; } MOSTImage img; img.setData( (unsigned char*)output_image, subject->getXDim(),subject->getYDim(),subject->getZDim(),subject->getCDim(),subject->getDatatype()); QString swcfile = QString(inimg_file) + "_MOST.swc"; LandmarkList seedList; QTime qtime_seed; qtime_seed.start(); if(1) { for(int i =1;i<=N;i+=20) img.auto_detect_seedx(seedList,i,InitThreshold,seed_size_all); } if(1) { for(int i =1;i<=M;i+=20) img.auto_detect_seedy(seedList,i,InitThreshold,seed_size_all); } if(1) { for(int i =1;i<=P;i+=20) img.auto_detect_seedz(seedList,i,InitThreshold,seed_size_all); } qDebug(" cost time seed = %g sec", qtime_seed.elapsed()*0.001); static long init_flag = 0; for(init_flag = 0;init_flag<subject->getTotalUnitNumberPerChannel();init_flag++) { visited.push_back(false); } // converte the formate NeuronTree vt; QTime qtime; qtime.start(); vt = img.trace_seed_list(seedList, visited,InitThreshold,1.0,1.0,1.0,swcfile,slipsize,0); qDebug(" cost time totol= %g sec", qtime.elapsed()*0.001); v3d_msg(QString("\nNow you can drag and drop the generated swc fle [%1] into Vaa3D.").arg(swcfile),0); if (subject) {delete subject; subject=0;} return true; }
void FL_cellseg(V3DPluginCallback2 &callback, QWidget *parent) { v3dhandle curwin = callback.currentImageWindow(); if (!curwin) { v3d_msg("You don't have any image open in the main window."); return; } Image4DSimple* subject = callback.getImage(curwin); QString m_InputFileName = callback.getImageName(curwin); if (!subject) { QMessageBox::information(0, title, QObject::tr("No image is open.")); return; } if (subject->getDatatype()!=V3D_UINT8) { QMessageBox::information(0, title, QObject::tr("This demo program only supports 8-bit data. Your current image data type is not supported.")); return; } V3DLONG sz0 = subject->getXDim(); V3DLONG sz1 = subject->getYDim(); V3DLONG sz2 = subject->getZDim(); V3DLONG sz3 = subject->getCDim(); Image4DProxy<Image4DSimple> pSub(subject); //---------------------------------------------------------------------------------------------------------------------------------- V3DLONG channelsz = sz0*sz1*sz2; float *pLabel = 0; unsigned char *pData = 0; //get the segmentation parameters segParameter segpara; dialog_watershed_para *p_mydlg=0; if (!p_mydlg) p_mydlg = new dialog_watershed_para(&segpara, subject); int res = p_mydlg->exec(); if (res!=QDialog::Accepted) return; else p_mydlg->fetchData(&segpara); if (p_mydlg) {delete p_mydlg; p_mydlg=0;} // now allocate memory and do computation int start_t = clock(); Vol3DSimple <unsigned char> * tmp_inimg = 0; Vol3DSimple <USHORTINT16> * tmp_outimg = 0; try { tmp_inimg = new Vol3DSimple <unsigned char> (sz0, sz1, sz2); tmp_outimg = new Vol3DSimple <USHORTINT16> (sz0, sz1, sz2); } catch (...) { v3d_msg("Unable to allocate memory for processing. Do nothing."); if (tmp_inimg) {delete tmp_inimg; tmp_inimg=0;} if (tmp_outimg) {delete tmp_outimg; tmp_outimg=0;} return; } //do computation memcpy((void *)tmp_inimg->getData1dHandle(), (void *)subject->getRawDataAtChannel(segpara.channelNo), sz0*sz1*sz2); bool b_res = FL_cellseg(tmp_inimg, tmp_outimg, segpara); if (tmp_inimg) {delete tmp_inimg; tmp_inimg=0;} //free the space immediately for better use of memory if (!b_res) { v3d_msg("Fail to do the cell segmentation using FL_cellseg().\n"); } else { V3DLONG new_sz0 = tmp_outimg->sz0(); V3DLONG new_sz1 = tmp_outimg->sz1(); V3DLONG new_sz2 = tmp_outimg->sz2(); V3DLONG new_sz3 = 1; V3DLONG tunits = new_sz0*new_sz1*new_sz2*new_sz3; USHORTINT16 * outvol1d = new USHORTINT16 [tunits]; USHORTINT16 * tmpImg_d1d = (USHORTINT16 *)(tmp_outimg->getData1dHandle()); memcpy((void *)outvol1d, (void *)tmp_outimg->getData1dHandle(), tunits*sizeof(USHORTINT16)); if (tmp_outimg) {delete tmp_outimg; tmp_outimg=0;} //free the space immediately for better use of memory Image4DSimple p4DImage; p4DImage.setData((unsigned char*)outvol1d, sz0, sz1, sz2, 1, V3D_UINT16); v3dhandle newwin = callback.newImageWindow(); callback.setImage(newwin, &p4DImage); callback.setImageName(newwin, QString("Segmented Image")); callback.updateImageWindow(newwin); } //---------------------------------------------------------------------------------------------------------------------------------- int end_t = clock(); printf("time eclapse %d s for labeling objects!\n", (end_t-start_t)/1000000); }