// Get the current V3D image window /* static */ ImageWindow ImageWindow::current() { V3DPluginCallback2* callback = v3d::get_plugin_callback(); if (! callback) throw std::runtime_error("No V3D callback handler"); return ImageWindow(callback->currentImageWindow()); }
void Invert(V3DPluginCallback2 &v3d, QWidget *parent) { v3dhandle oldwin = v3d.currentImageWindow(); Image4DSimple* image = v3d.getImage(oldwin); if (! image) { QMessageBox::information(0, title, QObject::tr("No image is open.")); return; } // if (image->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; // } Image4DProxy<Image4DSimple> p(image); // for (uint8* ip=p.begin(); ip<=p.end(); ip++) // { // *ip = 255 - *ip; // } Image4DProxy_foreach(p, x,y,z,c) { double f = 0; if (p.is_inner(x,y,z,c)) f = p.value_at(x,y,z,c); f = 255-f; p.put_at(x,y,z,c, (f)); }
void setSeeds(V3DPluginCallback2 &v3d, QWidget *parent ) { 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); }
void SynTwoImage(V3DPluginCallback2 &v3d, QWidget *parent) { v3dhandleList win_list = v3d.getImageWindowList(); if (win_list.size()<2) { v3d_msg("You need at least two opened images to synchronize their 3D views!"); return; } if (panel) { panel->show(); return; } else { panel = new lookPanel(v3d, parent); if (panel) { panel->show(); panel->raise(); panel->move(100,100); panel->activateWindow(); } } }
int compute(V3DPluginCallback2 &callback, QWidget *parent) { v3dhandle curwin; curwin=callback.currentImageWindow(); if(!curwin) { v3d_msg("No V3D window is available for returning data ... Do nothing.", 0); return -1; } Image4DSimple *p4DImage = callback.getImage(curwin); if (p4DImage->getDatatype()!=V3D_UINT8) { v3d_msg("Now we only support 8 bit image.\n"); return -1; } //TODO add datatype judgment double max_value = 256; V3DLONG histscale = 256; QVector<QVector<int> > hist_vec; QStringList labelsLT; int nChannel = p4DImage->getCDim(); V3DLONG sz[3]; sz[0] = p4DImage->getXDim(); sz[1] = p4DImage->getYDim(); sz[2] = p4DImage->getZDim(); for (int c=0;c<nChannel;c++) { unsigned char * inimg1d = p4DImage->getRawDataAtChannel(c); QVector<int> tmp; getHistogram(inimg1d, sz[0]*sz[1]*sz[2], max_value, histscale, tmp); hist_vec.append(tmp); labelsLT.append(QString("channel %1").arg(c+1)); } QString labelRB = QString("%1").arg(max_value); histogramDialog * dlg = new histogramDialog(hist_vec, labelsLT, labelRB, parent, QSize(500,150), QColor(50,50,50)); dlg->setWindowTitle(QObject::tr("Histogram")); dlg->show(); return 1; }
void border_tips::dosearch(V3DPluginCallback2 &callback, QWidget *parent) { //select the window to operate QList <V3dR_MainWindow *> allWindowList = callback.getListAll3DViewers(); QList <V3dR_MainWindow *> selectWindowList; V3dR_MainWindow * v3dwin; QList<NeuronTree> * ntTreeList; int winid; qDebug("search for 3D windows"); for (V3DLONG i=0;i<allWindowList.size();i++) { ntTreeList = callback.getHandleNeuronTrees_Any3DViewer(allWindowList[i]); if(ntTreeList->size()>0) selectWindowList.append(allWindowList[i]); } qDebug("match and select 3D windows"); if(selectWindowList.size()<1){ v3d_msg("Cannot find 3D view with SWC file. Please load the SWC file you want to identify border tips on."); return; }else if(selectWindowList.size()>1){ //pop up a window to select QStringList items; for(int i=0; i<selectWindowList.size(); i++){ items.append(callback.getImageName(selectWindowList[i])); } bool ok; QString selectitem = QInputDialog::getItem(parent, QString::fromUtf8("Neuron Stitcher"), QString::fromUtf8("Select A Window to Operate"), items, 0, false, &ok); if(!ok) return; for(int i=0; i<selectWindowList.size(); i++){ if(selectitem==callback.getImageName(selectWindowList[i])) { winid=i; break; } } }else{ winid=0; } v3dwin = selectWindowList[winid]; neuron_tipspicker_dialog * myDialog = NULL; myDialog = new neuron_tipspicker_dialog(&callback, v3dwin); myDialog->show(); }
void MovieFrom3Dviewer(V3DPluginCallback2 & v3d, QWidget * parent) { v3dhandle curwin = v3d.currentImageWindow(); if (!curwin) { v3d_msg("You don't have any image open in the main window."); return; } v3d.open3DWindow(curwin); if (controlPanel::m_pLookPanel) { controlPanel::m_pLookPanel->show(); return; } controlPanel* p = new controlPanel(v3d, parent); if (p) p->show(); }
void SnapShoot3Dviewer(V3DPluginCallback2 & v3d, QWidget * parent) { v3dhandle curwin = v3d.currentImageWindow(); if (!curwin) { v3d_msg("You don't have any image opened in the main window."); return; } v3d.open3DWindow(curwin); QFileDialog d(parent); d.setWindowTitle(QObject::tr("Choose output snapshot filename")); d.setAcceptMode(QFileDialog::AcceptSave); if (!d.exec()) return; QString BMPfilename = (d.selectedFiles())[0]; if (BMPfilename.endsWith(".BMP", Qt::CaseInsensitive)) BMPfilename.resize(BMPfilename.length()-4); //by PHC v3d.screenShot3DWindow(curwin, BMPfilename); QMessageBox::information(0, title, QString("Snapshot was saved to: %1.BMP\n").arg(BMPfilename)); }
void processImage(V3DPluginCallback2 &callback) { v3dhandle curwin = callback.currentImageWindow(); if (!curwin) { QMessageBox::information(0, "", "You don't have any image open in the main window."); return; } Image4DSimple* p4DImage = callback.getImage(curwin); if (!p4DImage) { QMessageBox::information(0, "", "The image pointer is invalid. Ensure your data is valid and try again!"); return; } unsigned char* data1d = p4DImage->getRawData(); V3DLONG N = p4DImage->getXDim(); V3DLONG M = p4DImage->getYDim(); V3DLONG P = p4DImage->getZDim(); ImagePixelType pixeltype = p4DImage->getDatatype(); // display new this was copied from plug_watershed and is substantially different // from ZZs local enhancement code. Image4DSimple new4DImage; new4DImage.setData((unsigned char *)data1d,N, M, P, 1, pixeltype); v3dhandle newwin = callback.newImageWindow(); callback.setImage(newwin, &new4DImage); callback.setImageName(newwin, QString("Local_adaptive_enhancement_result")); callback.updateImageWindow(newwin); }
void snapShots3Dviewer(V3DPluginCallback2 & v3d, QWidget * parent) { QFileDialog inANO_d(parent); inANO_d.setWindowTitle(QObject::tr("Choose input ano filename")); inANO_d.setAcceptMode(QFileDialog::AcceptOpen); if (!inANO_d.exec()) return; QString inANO_fn = (inANO_d.selectedFiles())[0]; P_ObjectFileType cc; if(! loadAnoFile(inANO_fn,cc)){ cout <<"Fail to load ano file" <<endl; return; } QString output_d=QFileDialog::getExistingDirectory(parent, QString(QObject::tr("Choose the output directory, where the snapshots would be saved."))); float x_rot = QInputDialog::getDouble(parent, "Roation about x axis", "Rotation about x :", 90, -180, 180); float y_rot = QInputDialog::getDouble(parent, "Roation about y axis", "Rotation about y :", 0, -180, 180); float z_rot = QInputDialog::getDouble(parent, "Roation about z axis", "Rotation about z :", 90, -180, 180); for(int i = 0; i <cc.swc_file_list.size(); i++) { QString swc_file = cc.swc_file_list[i]; v3d.open3DViewerForSingleSurfaceFile(swc_file); QList<V3dR_MainWindow * > list_3dviewer = v3d.getListAll3DViewers(); V3dR_MainWindow * surface_win = list_3dviewer[i]; if (!surface_win) { cout << "surface_win is empty"<<endl; } View3DControl *view = v3d.getView3DControl_Any3DViewer(surface_win); view->doAbsoluteRot(x_rot,y_rot,z_rot); swc_file = QFileInfo(swc_file).fileName(); QString BMPfilename = QDir(output_d).absolutePath()+ '/'+swc_file; // v3d_msg(BMPfilename); v3d.update_3DViewer(surface_win); v3d.screenShot_Any3DViewer(surface_win, BMPfilename); v3d.close3DWindow(surface_win); } }
void SetNeuronDisplayColor::do1clickcolor(V3DPluginCallback2 &callback, QWidget *parent) { //select the window to operate QList <V3dR_MainWindow *> allWindowList = callback.getListAll3DViewers(); QList <V3dR_MainWindow *> selectWindowList; V3dR_MainWindow * v3dwin; QList<NeuronTree> * ntTreeList; int winid; qDebug("search for 3D windows"); for (V3DLONG i=0;i<allWindowList.size();i++) { ntTreeList = callback.getHandleNeuronTrees_Any3DViewer(allWindowList[i]); if(ntTreeList->size()>0) selectWindowList.append(allWindowList[i]); } qDebug("match and select 3D windows"); if(selectWindowList.size()<1){ v3d_msg("Cannot find 3D view with SWC file. Please load the SWC files you want to color in the 3D view"); return; }else if(selectWindowList.size()>1){ //pop up a window to select QStringList items; for(int i=0; i<selectWindowList.size(); i++){ items.append(callback.getImageName(selectWindowList[i])); } bool ok; QString selectitem = QInputDialog::getItem(parent, QString::fromUtf8("1-click neuron color"), QString::fromUtf8("Select A Window to Operate"), items, 0, false, &ok); if(!ok) return; for(int i=0; i<selectWindowList.size(); i++){ if(selectitem==callback.getImageName(selectWindowList[i])) { winid=i; break; } } }else{ winid=0; } v3dwin = selectWindowList[winid]; //load neuron tree ntTreeList=callback.getHandleNeuronTrees_Any3DViewer(v3dwin); for(int i=0; i<ntTreeList->size(); i++){ NeuronTree* p = (NeuronTree*)&(ntTreeList->at(i)); int k=i%8; p->color.r=R_table[k]; p->color.g=G_table[k]; p->color.b=B_table[k]; p->color.a=255; } qDebug("Done Setting Color"); callback.update_3DViewer(v3dwin); }
int open_sec_editor(V3DPluginCallback2 &callback, QWidget *parent) { v3dhandleList win_list = callback.getImageWindowList(); if(win_list.size()<1) { QMessageBox::information(0, title, QObject::tr("No image is open.")); return -1; } SWCEditorWidget * w = new SWCEditorWidget(callback, parent); w->show(); //TestDialog dialog(callback, parent); //if (dialog.exec()!=QDialog::Accepted) return -1; //dialog.update(); //int i = dialog.i; //int c = dialog.channel; //Image4DSimple *p4DImage = callback.getImage(win_list[i]); //if(p4DImage->getCDim() <= c) {v3d_msg(QObject::tr("The channel isn't existed.")); return -1;} //V3DLONG sz[3]; //sz[0] = p4DImage->getXDim(); //sz[1] = p4DImage->getYDim(); //sz[2] = p4DImage->getZDim(); //unsigned char * inimg1d = p4DImage->getRawDataAtChannel(c); //v3dhandle newwin; //if(QMessageBox::Yes == QMessageBox::question(0, "", QString("Do you want to use the existing windows?"), QMessageBox::Yes, QMessageBox::No)) //newwin = callback.currentImageWindow(); //else //newwin = callback.newImageWindow(); //p4DImage->setData(inimg1d, sz[0], sz[1], sz[2], sz[3]); //callback.setImage(newwin, p4DImage); //callback.setImageName(newwin, QObject::tr("open_sec_editor")); //callback.updateImageWindow(newwin); return 1; }
void RivuletPlugin::domenu(const QString &menu_name, V3DPluginCallback2 &callback, QWidget *parent) { if (menu_name == tr("tracing")) { bool bmenu = true; input_PARA PARA; if(callback.getImageWindowList().empty()) { v3d_msg("Oops... No image opened in V3D..."); return; } PARA_RIVULET p; // fetch parameters from dialog if (!p.rivulet_dialog()) return; PARA.threshold = p.threshold; PARA.connectrate = p.connectrate; PARA.percentage = p.percentage; PARA.dumpbranch = p.dumpbranch; PARA.gap = p.gap; PARA.stepsize = p.stepsize; PARA.channel = p.channel; PARA.sigma = p.sigmavalue; PARA.alpha_one = p.alpha_one_value; PARA.alpha_two = p.alpha_two_value; reconstruction_func(callback,parent,PARA,bmenu); } else { v3d_msg(tr("Rivulet algorithm for 3D neuron tracing. . " "Developed by Siqi Liu, Donghao Zhang, 2015-8-25")); } }
void reconstruction_func(V3DPluginCallback2 &callback, QWidget *parent, input_PARA &PARA, bool bmenu) { unsigned char* data1d = 0; V3DLONG N,M,P,sc,c; V3DLONG in_sz[4]; int datatype = 0; if(bmenu) { v3dhandle curwin = callback.currentImageWindow(); if (!curwin) { QMessageBox::information(0, "", "You don't have any image open in the main window."); return; } Image4DSimple* p4DImage = callback.getImage(curwin); if (!p4DImage) { QMessageBox::information(0, "", "The image pointer is invalid. Ensure your data is valid and try again!"); return; } data1d = p4DImage->getRawData(); N = p4DImage->getXDim(); M = p4DImage->getYDim(); P = p4DImage->getZDim(); sc = p4DImage->getCDim(); datatype = (int) p4DImage->getDatatype(); bool ok1; if(sc==1) { c=1; ok1=true; } else { c = QInputDialog::getInteger(parent, "Channel", "Enter channel NO:", 1, 1, sc, 1, &ok1); } if(!ok1) return; in_sz[0] = N; in_sz[1] = M; in_sz[2] = P; in_sz[3] = sc; PARA.inimg_file = p4DImage->getFileName(); } else { if (!simple_loadimage_wrapper(callback,PARA.inimg_file.toStdString().c_str(), data1d, in_sz, datatype)) { fprintf (stderr, "Error happens in reading the subject file [%s]. Exit. \n",PARA.inimg_file.toStdString().c_str()); return; } if(PARA.channel < 1 || PARA.channel > in_sz[3]) { fprintf (stderr, "Invalid channel number. \n"); return; } N = in_sz[0]; M = in_sz[1]; P = in_sz[2]; sc = in_sz[3]; c = PARA.channel; } if(datatype!=1){ v3d_msg(QString("Now only support image type UINT8."),bmenu); return; } //main neuron reconstruction code QString swc_name=PARA.inimg_file+"_smartTracing"; nt_selfcorrect_func tracefunc; tracefunc.smart_tracing(PARA.inimg_file,swc_name,&callback,c-1); if(!bmenu) { if(data1d) {delete []data1d; data1d = 0;} } if(tracefunc.error_code==0) { v3d_msg(QString("Now you can drag and drop the generated swc fle [%1] into Vaa3D.").arg(swc_name.toStdString().c_str()),bmenu); }else{ QString error_msg; switch(tracefunc.error_code){ case 1: error_msg="Failed to call APP2 tracing function. Please check if plugin Vaa3D_Neuron2 is installed correctly."; break; case 2: error_msg="Failed to run SVM. Please check your configuration."; break; case 31: error_msg="Failed to read image file."; break; case 32: error_msg="Invalid image type. Please convert and save the image in type UINT8."; break; default: error_msg="Encounter unknown error. Please check the code or contact developer: Hanbo Chen"; break; } v3d_msg(error_msg,bmenu); } return; }
void IBioformatIOPlugin::domenu(const QString &menu_name, V3DPluginCallback2 &callback, QWidget *parent) { if (menu_name == tr("load an image using Bioformats Java library")) { // input QString m_FileName = QFileDialog::getOpenFileName(parent, QObject::tr("Open An Image"), QDir::currentPath(), QObject::tr("Image File (*.*)")); if(m_FileName.isEmpty()) { printf("\nError: Your image does not exist!\n"); return; } // temp QString baseName = QFileInfo(m_FileName).baseName(); QString tmpfile = QDir::tempPath().append("/").append(baseName).append(".tif"); // QFile tmpqfile(tmpfile); if (tmpqfile.exists()) system(qPrintable(QString("rm -f \"%1\"").arg(tmpfile))); //look for loci_tools.jar QString lociDir = ("loci_tools.jar"); if (!QFile(lociDir).exists()) { printf("loci_tools.jar is not in current directory, search v3d app path.\n"); lociDir = getAppPath().append("/loci_tools.jar"); printf(qPrintable(lociDir)); printf("\n"); if (!QFile(lociDir).exists()) { v3d_msg("Cannot find loci_tools.jar, please download it and make sure it is put under the Vaa3D executable folder, parallel to the Vaa3D executable and the plugins folder."); return; } } #if defined(Q_OS_WIN32) QSettings settings("HHMI", "Vaa3D"); QString fileOpenName = settings.value("JavaPath").toString(); if(fileOpenName.isEmpty()) { fileOpenName = QFileDialog::getOpenFileName(0, QObject::tr("Open Java Executable File"), "", QObject::tr("Supported file (*.exe)" )); if(fileOpenName.isEmpty()) return; settings.setValue("JavaPath", fileOpenName); } QString cmd_loci = QString("\"\"%1\" -cp \"%2\" loci.formats.tools.ImageConverter \"%3\" \"%4\"\"").arg(fileOpenName.toStdString().c_str()).arg(lociDir.toStdString().c_str()).arg(m_FileName.toStdString().c_str()).arg(tmpfile.toStdString().c_str()); #else QString cmd_loci = QString("java -cp \"%1\" loci.formats.tools.ImageConverter \"%2\" \"%3\"").arg(lociDir.toStdString().c_str()).arg(m_FileName.toStdString().c_str()).arg(tmpfile.toStdString().c_str()); #endif v3d_msg(cmd_loci, 0); system(qPrintable(cmd_loci)); if (!tmpqfile.exists()) { v3d_msg("The temprary file does not exist. The conversion of format using Bioformats has failed. Please sue another way to convert and load using Vaa3D.\n"); return; } // load V3DLONG sz_relative[4]; int datatype_relative = 0; unsigned char* relative1d = 0; if (simple_loadimage_wrapper(callback, const_cast<char *>(tmpfile.toStdString().c_str()), relative1d, sz_relative, datatype_relative)!=true) { fprintf (stderr, "Error happens in reading the subject file [%s]. Exit. \n",tmpfile.toStdString().c_str()); return; } // visualize Image4DSimple p4DImage; if(datatype_relative == V3D_UINT8) { p4DImage.setData((unsigned char*)relative1d, sz_relative[0], sz_relative[1], sz_relative[2], sz_relative[3], V3D_UINT8); } else if(datatype_relative == V3D_UINT16) { p4DImage.setData((unsigned char*)relative1d, sz_relative[0], sz_relative[1], sz_relative[2], sz_relative[3], V3D_UINT16); } else if(datatype_relative == V3D_FLOAT32) { p4DImage.setData((unsigned char*)relative1d, sz_relative[0], sz_relative[1], sz_relative[2], sz_relative[3], V3D_FLOAT32); } else { printf("\nError: The program only supports UINT8, UINT16, and FLOAT32 datatype.\n"); return; } v3dhandle newwin = callback.newImageWindow(); callback.setImage(newwin, &p4DImage); callback.setImageName(newwin, tmpfile.toStdString().c_str()); callback.updateImageWindow(newwin); } else if (menu_name == tr("click me if you are unhappy with the loading result...")) { v3d_msg("This program is designed to use a system call to invoke the LOCI Bioformats Image IO Java library loci_tools.jar" " to load an image. It first calls bioformats library to generate a temporary 3D TIF file on your harddrive" " and then uses Vaa3D to load that temporary file. Therefore, if you see some wrong loading result using this plugin, it is" " likely that you will get the same thing if you run the bioformats library directly. Of course, you may find a newer" " version of the loci_tools.jar at the LOCI website http://loci.wisc.edu/bio-formats/downloads; we encourage you" " to copy the latest version to the Vaa3D executable folder and try if it would fix your problem.", 1); return; } else if (menu_name == tr("About")) { QMessageBox::information(parent, "Version info", QString("Simple image reading using Bioformats library %1 (2011-2012) developed by Yang Yu, Yinan Wan, and Hanchuan Peng. (Janelia Research Farm Campus, HHMI)").arg(getPluginVersion()).append("\n")); return; } }
void processImage(V3DPluginCallback2 &callback, QWidget *parent, unsigned int rotateflag) { v3dhandle curwin = callback.currentImageWindow(); if (!curwin) { QMessageBox::information(0, "", "You don't have any image open in the main window."); return; } Image4DSimple* image = callback.getImage(curwin); if (!image) { QMessageBox::information(0, "", "The image pointer is invalid. Ensure your data is valid and try again!"); return; } unsigned char* data1d = image->getRawData(); V3DLONG szx = image->getXDim(), szy = image->getYDim(), szz = image->getZDim(), szc = image->getCDim(); // V3DLONG szchan = image->getTotalUnitNumberPerChannel(), szplane = image->getTotalUnitNumberPerPlane(); // V3DLONG N = image->getTotalBytes(); // V3DLONG i,j,k,c; if (!data1d || szx<=0 || szy<=0 || szz<=0 || szc<=0) { throw("Your data to the plugin is invalid. Check the program."); return; } ImagePixelType pixeltype = image->getDatatype(); V3DLONG in_sz[4]; in_sz[0]=szx; in_sz[1]=szy; in_sz[2]=szz; in_sz[3]=szc; unsigned char* outimg=0; rotateimage(data1d, in_sz, pixeltype, rotateflag, outimg); // image->setData(outimg, szy, szx, szz, szc, image->getDatatype()); // display Image4DSimple * new4DImage = new Image4DSimple(); switch(rotateflag) { case 1: new4DImage->setData((unsigned char*)outimg, szy, szx, szz, szc, image->getDatatype()); break; case 2: new4DImage->setData((unsigned char*)outimg, szy, szx, szz, szc, image->getDatatype()); break; case 3: new4DImage->setData((unsigned char*)outimg, szx, szy, szz, szc, image->getDatatype()); break; default: break; } v3dhandle newwin = callback.newImageWindow(); callback.setImage(newwin, new4DImage); callback.setImageName(newwin, title); callback.updateImageWindow(newwin); }
void neuron_render_ESWC_features::docolor(V3DPluginCallback2 &callback, QWidget *parent) { //select the window to operate QList <V3dR_MainWindow *> allWindowList = callback.getListAll3DViewers(); QList <V3dR_MainWindow *> selectWindowList; V3dR_MainWindow * v3dwin; QList<NeuronTree> * ntTreeList; int winid; qDebug("search for 3D windows"); for (V3DLONG i=0;i<allWindowList.size();i++) { ntTreeList = callback.getHandleNeuronTrees_Any3DViewer(allWindowList[i]); if(ntTreeList->size()>0){ qDebug()<<"cojoc:"; for(V3DLONG j=0; j<ntTreeList->size(); j++){ if(ntTreeList->at(j).listNeuron.at(0).fea_val.size()>0){ selectWindowList.append(allWindowList[i]); break; } } qDebug()<<"cojoc:"; qDebug()<<ntTreeList->at(0).listNeuron.at(0).fea_val.size(); } } qDebug("match and select 3D windows"); if(selectWindowList.size()<1){ v3d_msg("Cannot find 3D view with eligible ESWC file. Please load the ESWC files with features you want to display 3D view"); return; }else if(selectWindowList.size()>1){ //pop up a window to select QStringList items; for(int i=0; i<selectWindowList.size(); i++){ items.append(callback.getImageName(selectWindowList[i])); } bool ok; QString selectitem = QInputDialog::getItem(parent, QString::fromUtf8("Color Render ESWC"), QString::fromUtf8("Select A Window to Operate"), items, 0, false, &ok); if(!ok) return; for(int i=0; i<selectWindowList.size(); i++){ if(selectitem==callback.getImageName(selectWindowList[i])) { winid=i; break; } } }else{ winid=0; } v3dwin = selectWindowList[winid]; V3DLONG nid=0; ntTreeList = callback.getHandleNeuronTrees_Any3DViewer(v3dwin); QList<V3DLONG> selectNeuronList; for(V3DLONG j=0; j<ntTreeList->size(); j++){ if(ntTreeList->at(j).listNeuron.at(0).fea_val.size()>0){ selectNeuronList.append(j); } } if(selectNeuronList.size()>1){ //pop up a window to select QStringList items; for(int i=0; i<selectNeuronList.size(); i++){ items.append(QString::number(i+1)+": "+ntTreeList->at(selectNeuronList.at(i)).file); } bool ok; QString selectitem = QInputDialog::getItem(parent, QString::fromUtf8("Color Render ESWC"), QString::fromUtf8("Select A Neuron to Color"), items, 0, false, &ok); if(!ok) return; for(int i=0; i<selectNeuronList.size(); i++){ if(selectitem==items.at(i)) { nid==selectNeuronList.at(i); break; } } }else{ nid=selectNeuronList.at(0); } color_render_ESWC_dialog * myDialog = NULL; myDialog = new color_render_ESWC_dialog(&callback, v3dwin, nid); myDialog->show(); }
void brl00::domenu(const QString &menu_name, V3DPluginCallback2 &callback, QWidget *parent) { if (menu_name == tr("Select ROI")) { // check what's up with the current window v3dhandle curwin = callback.currentImageWindow(); if (!curwin) { QMessageBox::information(0, "", "You don't have an image open in the main window."); return; } Image4DSimple* p4DImage = callback.getImage(curwin); if (!p4DImage) { QMessageBox::information(0, "", "The image pointer is invalid."); return; } // first need to select an ROI... this should be an existing command with the callback as an argument // apparently there's a lot of overhead for this... // declearing stuff... V3DPluginArgItem arg; V3DPluginArgList input; V3DPluginArgList output; unsigned char * data1d_loaded = 0; // this is a pointer to the data loaded from a file int datatype; // these are defined by load_image_wrapper? V3DLONG * in_zz = 0; unsigned char* data1d_image = p4DImage->getRawData(); //this is for the data from the current window //and this thing that defines what channel we're looking at char c=1; arg.type = "random";std::vector<char*> args1; args1.push_back("/Users/brl/dump/ex_.v3draw"); arg.p = (void *) & args1; input<< arg; arg.type = "random";std::vector<char*> args; char channel = '0' + c; args.push_back("3");args.push_back("3");args.push_back("3");args.push_back(&channel); args.push_back("1.0"); arg.p = (void *) & args; input << arg; arg.type = "random";std::vector<char*> args2;args2.push_back("/Users/brl/dump/gfImage.v3draw"); arg.p = (void *) & args2; output<< arg; QString full_plugin_name = "gaussian"; QString func_name = "gf"; callback.callPluginFunc(full_plugin_name,func_name, input,output); char * outimg_file = ((vector<char*> *)(output.at(0).p))->at(0); v3d_msg(outimg_file); simple_loadimage_wrapper(callback, outimg_file, data1d_loaded, in_zz, datatype); // remove("temp.v3draw"); // remove("gfImage.v3draw"); } else if (menu_name == tr("Modify voxels")) { // this will be my processImage function which will be defined below processImage(callback); } else { v3d_msg(tr("BRL test plugin 00 " "Developed by BRL 2013.12.20")); } }
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 reconstruction_func(V3DPluginCallback2 &callback, QWidget *parent, input_PARA &PARA, bool bmenu) { unsigned char* data1d = 0; V3DLONG N,M,P,sc,c; V3DLONG in_sz[4]; if(bmenu) { v3dhandle curwin = callback.currentImageWindow(); if (!curwin) { QMessageBox::information(0, "", "You don't have any image open in the main window."); return; } Image4DSimple* p4DImage = callback.getImage(curwin); if (!p4DImage) { QMessageBox::information(0, "", "The image pointer is invalid. Ensure your data is valid and try again!"); return; } data1d = p4DImage->getRawData(); N = p4DImage->getXDim(); M = p4DImage->getYDim(); P = p4DImage->getZDim(); sc = p4DImage->getCDim(); bool ok1; if(sc==1) { c=1; ok1=true; } else { c = QInputDialog::getInteger(parent, "Channel", "Enter channel NO:", 1, 1, sc, 1, &ok1); } if(!ok1) return; in_sz[0] = N; in_sz[1] = M; in_sz[2] = P; in_sz[3] = sc; PARA.inimg_file = p4DImage->getFileName(); } else { int datatype = 0; if (!simple_loadimage_wrapper(callback,PARA.inimg_file.toStdString().c_str(), data1d, in_sz, datatype)) { fprintf (stderr, "Error happens in reading the subject file [%s]. Exit. \n",PARA.inimg_file.toStdString().c_str()); return; } if(PARA.channel < 1 || PARA.channel > in_sz[3]) { fprintf (stderr, "Invalid channel number. \n"); return; } N = in_sz[0]; M = in_sz[1]; P = in_sz[2]; sc = in_sz[3]; c = PARA.channel; } //main neuron reconstruction code //Stack *data1d_ch1 = C_Stack::make(GREY,(int)N,(int)M,(int)P); V3DLONG pagesz = N*M*P; V3DLONG offsetc = (c-1)*pagesz; size_t voxelNumber = ((size_t) N) * M * P; float *im3d = new float[voxelNumber]; size_t voxelOffset = 0; float maxI = -FLT_MAX; float minI = FLT_MAX; for(V3DLONG z = 0; z < P; z++) { V3DLONG offsetk = z*M*N; for(V3DLONG y = 0; y < M; y++) { V3DLONG offsetj = y*N; for(V3DLONG x = 0; x < N; x++) { voxelOffset = offsetk + offsetj + x; float dataval = data1d[offsetc + voxelOffset]; if (maxI < dataval) { maxI = dataval; } if (minI > dataval) { minI = dataval; } im3d[voxelOffset] = dataval; //double dataval = data1d[offsetc + offsetk + offsetj + x]; //Set_Stack_Pixel(data1d_ch1,x,y,z,0,dataval); } } } //invert to bright field for (size_t i = 0; i < voxelNumber; ++i) { im3d[i] = (maxI - im3d[i])/(maxI - minI + 1e-10); } QString swc_name = PARA.inimg_file + "_neutu_autotrace.swc"; #if defined(_MAC_APPLICATION_) std::string paramDir = QApplication::applicationDirPath().toStdString() + "/../../../../" + NEUTU_PARAM_DIR; #else std::string paramDir = QApplication::applicationDirPath().toStdString(); #endif std::string paramFile = paramDir + "/NeuTuAuto.Params.dat"; std::cout << paramFile << std::endl; NeuTuAutoTraceOneStack(im3d, M, N, P, paramFile.c_str(), swc_name.toStdString().c_str()); delete []im3d; /* JNeuronTracer tracer; ZStack stack; stack.load(data1d_ch1,true); Stack *stackData = stack.c_stack(); if (C_Stack::mode(stackData) > C_Stack::min(stackData)) { std::cout << "Bright field detected." << std::endl; Stack_Invert_Value(stackData); } else { std::cout << "Dark field detected." << std::endl; } //tracer.initTraceWorkspace(&stack); //tracer.initConnectionTestWorkspace(); ZSwcTree *tree = tracer.trace(stackData); tree->setType(2); QString swc_name = PARA.inimg_file + "_neutu_autotrace.swc"; tree->save(swc_name.toStdString().c_str()); delete tree; */ if(!bmenu) { if(data1d) {delete []data1d; data1d = 0;} } v3d_msg(QString("Now you can drag and drop the generated swc fle [%1] into Vaa3D.").arg(swc_name.toStdString().c_str()),bmenu); return; }
void autotrace(V3DPluginCallback2 &callback, QWidget *parent) { v3dhandle curwin = callback.currentImageWindow(); if (!curwin) { QMessageBox::information(0, "", "You don't have any image open in the main window."); return; } Image4DSimple* p4DImage = callback.getImage(curwin); if (!p4DImage) { QMessageBox::information(0, "", "The image pointer is invalid. Ensure your data is valid and try again!"); return; } //Mc_Stack *stack = NVInterface::makeStack(p4DImage); unsigned char* data1d = p4DImage->getRawData(); V3DLONG N = p4DImage->getXDim(); V3DLONG M = p4DImage->getYDim(); V3DLONG P = p4DImage->getZDim(); V3DLONG sc = p4DImage->getCDim(); int in_sz[3]; in_sz[0] = N; in_sz[1] = M; in_sz[2] = P; bool ok1; int c; if(sc==1) { c=1; ok1=true; } else { c = QInputDialog::getInteger(parent, "Channel", "Enter channel NO:", 1, 1, sc, 1, &ok1); } if(!ok1) return; IM = new ImageOperation; Tracer = new OpenSnakeTracer; // IM->ImRead(callback.getImageName(curwin).toStdString().c_str()); IM->Imcreate(data1d,in_sz); //preprocessing std::cout<<"Compute Gradient Vector Flow..."<<std::endl; IM->computeGVF(1000,5,0); std::cout<<"Compute Vesselness (CPU)..."<<std::endl; IM->ComputeGVFVesselness(); std::cout<<"Detect Seed Points..."<<std::endl; IM->SeedDetection(IM->v_threshold,0,0); std::cout<<"Adjust Seed Points..."<<std::endl; IM->SeedAdjustment(10); std::cout<<"Preprocessing Finished..."<<std::endl; IM->ImComputeInitBackgroundModel(IM->v_threshold); IM->ImComputeInitForegroundModel(); //tracing std::cout<<"--------------Tracing--------------"<<std::endl; IM->ImRefresh_LabelImage(); Tracer->SetImage(IM); Tracer->use_multi_threads = true; Tracer->Init(); Tracer->tracing_thread->stopped = false; float alpha = 0; int iter_num = 50; int ITER = 5; int pt_distance = 2; float beta = 0.05; float kappa = 1; float gamma = 1; float stretchingRatio = 3; int collision_dist = 1; int minimum_length = 5; bool automatic_merging = true; int max_angle = 99; bool freeze_body = true; int s_force = 1; int tracing_model = 0; int coding_method = 0; float sigma_ratio = 1; int border = 0; Tracer->setParas(pt_distance,gamma,stretchingRatio,minimum_length,collision_dist,5,5,automatic_merging,max_angle, freeze_body,s_force,tracing_model,false,coding_method,sigma_ratio,border); IM->SetCodingMethod(0); Tracer->Open_Curve_Snake_Tracing(); Tracer->RemoveSeeds(); //tracing finished while( IM->SeedPt.GetSize() != IM->visit_label.sum() ) { Tracer->Open_Curve_Snake_Tracing(); Tracer->RemoveSeeds(); } std::cout<<std::endl; std::cout<<"--------------Processing Finished--------------"<<std::endl; QString fileName = callback.getImageName(curwin) + "_snake.swc"; QFile swc_file(fileName); PointList3D wrote_pt, All_Pt; if (swc_file.open(QFile::WriteOnly | QFile::Truncate)) { QTextStream *out_txt; out_txt = new QTextStream(&swc_file); vnl_vector<int> *snake_visit_label; snake_visit_label = new vnl_vector<int>(Tracer->SnakeList.NSnakes); snake_visit_label->fill(0); int *point_id; point_id = new int[1]; point_id[0] = 1; All_Pt.RemoveAllPts(); std::vector<int> *branch_label; branch_label = new std::vector<int>[1]; for( int i = 0; i < Tracer->SnakeList.NSnakes; i++ ) { if( snake_visit_label[0](i) == 1 ) continue; if( Tracer->SnakeList.valid_list[i] == 0 ) continue; wrote_pt.RemoveAllPts(); int snake_id = i; findBranch_Raw( snake_id, -1, Tracer->SnakeList.Snakes[i].Cu.GetFirstPt(), snake_visit_label, point_id, out_txt, &wrote_pt, &All_Pt, branch_label ); } } v3d_msg(QString("Now you can drag and drop the generated swc fle [%1] into Vaa3D.").arg(fileName)); return; }
void reconstruction_func(V3DPluginCallback2 &callback, QWidget *parent, input_PARA &PARA, bool bmenu) { cout<<"Welcome to NeuroStalker!!"<<endl; unsigned char* data1d = 0; V3DLONG N,M,P,sc,c; V3DLONG in_sz[4]; Image4DSimple* p4DImage; if(bmenu) { v3dhandle curwin = callback.currentImageWindow(); if (!curwin) { QMessageBox::information(0, "", "You don't have any image open in the main window."); return; } p4DImage = callback.getImage(curwin); if (!p4DImage) { QMessageBox::information(0, "", "The image pointer is invalid. Ensure your data is valid and try again!"); return; } data1d = p4DImage->getRawData(); N = p4DImage->getXDim(); M = p4DImage->getYDim(); P = p4DImage->getZDim(); sc = p4DImage->getCDim(); bool ok1; if(sc==1) { c=1; ok1=true; } else { c = QInputDialog::getInteger(parent, "Channel", "Enter channel NO:", 1, 1, sc, 1, &ok1); } if(!ok1) return; in_sz[0] = N; in_sz[1] = M; in_sz[2] = P; in_sz[3] = sc; PARA.inimg_file = p4DImage->getFileName(); } else { int datatype = 0; if (!simple_loadimage_wrapper(callback,PARA.inimg_file.toStdString().c_str(), data1d, in_sz, datatype)) { fprintf (stderr, "Error happens in reading the subject file [%s]. Exit. \n",PARA.inimg_file.toStdString().c_str()); return; } if(PARA.channel < 1 || PARA.channel > in_sz[3]) { fprintf (stderr, "Invalid channel number. \n"); return; } N = in_sz[0]; M = in_sz[1]; P = in_sz[2]; sc = in_sz[3]; c = PARA.channel; } if (PARA.unittest & 2) { cout<<"+++++ Running Unit-Tests +++++"<<endl; //TestRadius(data1d, in_sz); } // ------- Main neuron reconstruction code // Crop The image vectype boxlowsize; if (PARA.preprocessing & 1) { cout<<"=============== Cropping the image ==============="<<endl; V3DLONG sz_img_crop[4]; unsigned char *p_img8u_crop = crop(in_sz, data1d, sz_img_crop, &boxlowsize, PARA.threshold); cout<<"boxlowsize: "<<boxlowsize[0]<<"boxlowsize: "<<boxlowsize[1]<<"boxlowsize: "<<boxlowsize[2]<<endl; //cout<<"Saving cropped image to downsample.v3draw"<<endl; //saveImage("test/cropoutside.v3draw", p_img8u_crop, sz_img_crop, V3D_UINT8); if(!bmenu) { if (data1d) delete [] data1d; } data1d = p_img8u_crop; for (int i=0; i<4; i++){ in_sz[i] = sz_img_crop[i]; } //cout<<"boxlowsize: "<<boxlowsize[0]<<"boxlowsize: "<<boxlowsize[1]<<"boxlowsize: "<<boxlowsize[2]<<endl; cout<<"=============== Image Cropped ==============="<<endl; } // Imcreate takes in_sz with int* // Downsample the image if (PARA.preprocessing & 2) { cout<<"=============== Downsampling the image..."<<endl; V3DLONG downsz[4]; cout<<"Data size before downsample: "<<in_sz[0]<<","<<in_sz[1]<<","<<in_sz[2]<<endl; unsigned char* downdata1d = downsample(in_sz, c, data1d, downsz); data1d = downdata1d; in_sz[0] = downsz[0]; in_sz[1] = downsz[1]; in_sz[2] = downsz[2]; in_sz[3] = downsz[3]; cout<<"Data size after downsample: "<<in_sz[0]<<","<<in_sz[1]<<","<<in_sz[2]<<endl; //cout<<"Saving downsampled image to test/downsample.v3draw"<<endl; //saveImage("test/downsample.v3draw", downdata1d, downsz, V3D_UINT8); cout<<"=============== Image Downsampled..."<<endl; } // Using the Image Operation found in vaa3d_tools/hackathon/zhi/snake_tracing/TracingCore/ in for some simple Image Processing IM = new ImageOperation; // Imcreate takes in_sz with int* int in_sz_int[4]; for(int i = 0; i < 4; i++) { in_sz_int[i] = (int)in_sz[i]; } // Preprocessing IM->Imcreate(data1d, in_sz_int); std::cout<<"=== Compute Gradient Vector Flow..."<<std::endl; IM->computeGVF(1000, 5, 1); std::cout<<"=== Compute Vesselness (CPU)..."<<std::endl; IM->ComputeGVFVesselness(); std::cout<<"=== Detect Seed Points..."<<std::endl; IM->SeedDetection(IM->v_threshold, 0, 0); std::cout<<"=== Adjust Seed Points..."<<std::endl; IM->SeedAdjustment(10); std::cout<<"=== Preprocessing Finished..."<<std::endl; //----------------------------vesselness begin /* V3DLONG l_npixels_vessel; l_npixels_vessel = in_sz_int[0] * in_sz_int[1] * in_sz_int[2]; cout<<"l_npixels_vessel"<<l_npixels_vessel<<endl; GradientImageType::IndexType index;*/ float vp; /* for (int i = 0; i < 10; ++i) { index[0] = 66 + i; index[1] = 208 + i; index[2] = 48 + i; vp = (float) (IM->IVessel)->GetPixel(index); cout<<"vp output: "<<vp<<endl; }*/ const int testthreshold = IM->v_threshold; cout<<"testthreshold: "<<testthreshold<<endl; /* unsigned char *p_vessel = new(std::nothrow) unsigned char[l_npixels_vessel](); unsigned char * vp_tmp = p_vessel; for(V3DLONG Z = 0;Z < in_sz[2]; Z++) for(V3DLONG Y = 0;Y < in_sz[1]; Y++) for(V3DLONG X = 0;X < in_sz[0]; X++) { //cout<<"continue"; index[0] = X; index[1] = Y; index[2] = Z; vp = (float) (IM->IVessel)->GetPixel(index); *vp_tmp = vp; vp_tmp++; } saveImage("test/Vesselness.v3draw", p_vessel, in_sz, V3D_UINT8);*/ //---------------------------vesselness end // Adaptive thresholding here, may replace with graph cut //IM->ImComputeInitBackgroundModel(IM->v_threshold); //IM->ImComputeInitForegroundModel(); // Get the Binary Image //replace simple threshold by adaptive thresholding //LabelImagePointer binaryimg = DeriveForegroundLabelImage(IM->I, ForegroundThreshold); LabelImagePointer binaryimg = DeriveForegroundLabelImage(IM->I, (int) PARA.threshold); // Save the binary img to visualise the segmentation unsigned short int * binaryimgbuffer = binaryimg->GetBufferPointer(); unsigned char * binaryimg2uchar = new unsigned char [in_sz[0]*in_sz[1]*in_sz[2]]; for (int i = 0; i < in_sz[0]*in_sz[1]*in_sz[2]; i++) { binaryimg2uchar[i] = (unsigned char) ((double)(binaryimgbuffer[i]) * 255.0); } //saveImage("test/binaryimage.v3draw", binaryimg2uchar, in_sz, V3D_UINT8); vectype xpfinal, ypfinal, zpfinal, rfinal, pn, sn; // ------- Run Unit-Tests if (PARA.unittest & 2){ cout<<"+++++ Running Unit-Tests +++++"<<endl; TestMatMath(); TestPressureSampler(IM->I, IM->IGVF, binaryimg, IM->SeedPt, &xpfinal, &ypfinal, &zpfinal, &pn, &rfinal, &sn); cout<<"All Tests Finished!!!!!!! G'Day!!"<<endl; } if (PARA.unittest & 1) { //PressureSampler p(100, 100, IM->I, IM->IGVF, 10); TraceReal(IM->I, IM->IGVF, binaryimg, IM->SeedPt, &xpfinal, &ypfinal, &zpfinal, &pn, &rfinal, &sn, PARA.step, PARA.stepsize); } cout<<"pn size: "<<pn.size()<<" xpoint size: "<<xpfinal.size()<<" ypoint size: " <<ypfinal.size()<<" zpoint size: "<<zpfinal.size()<<" rpoint size: "<<rfinal.size()<<endl; //Output NeuronTree nt; QList <NeuronSWC> listNeuron; QHash <int, int> hashNeuron; listNeuron.clear(); hashNeuron.clear(); NeuronSWC S; for (int i = 0; i < ypfinal.size(); i++) { S.n = sn[i]; S.type = 7; S.x = xpfinal[i] + boxlowsize[0]; S.y = ypfinal[i] + boxlowsize[1]; S.z = zpfinal[i] + boxlowsize[2]; S.r = rfinal[i]; S.pn = pn[i]; listNeuron.append(S); hashNeuron.insert(S.n, listNeuron.size() - 1); } nt.n = -1; nt.on = true; nt.listNeuron = listNeuron; nt.hashNeuron = hashNeuron; QString swc_name = PARA.inimg_file + "_NeuroStalker.swc"; nt.name = "NeuroStalker"; writeSWC_file(swc_name.toStdString().c_str(), nt); if(!bmenu) { if(data1d) {delete [] data1d; data1d = 0;} } v3d_msg(QString("Now you can drag and drop the generated swc fle [%1] into Vaa3D.").arg(swc_name.toStdString().c_str()),bmenu); return; }
void reconstruction_func(V3DPluginCallback2 &callback, QWidget *parent, input_PARA &PARA, bool bmenu) { // QMessageBox msgBox; // if (bmenu) // { // msgBox.setText("Rivulet Running..."); // msgBox.setIcon(QMessageBox::Information); // msgBox.setStandardButtons(QMessageBox::Ok); // // msgBox.setAutoClose(true); // // msgBox.setTimeout(3); //Closes after three seconds // msgBox.exec(); // } unsigned char* data1d = 0; V3DLONG N,M,P,sc,c; V3DLONG in_sz[4]; if(bmenu) { v3dhandle curwin = callback.currentImageWindow(); if (!curwin) { QMessageBox::information(0, "", "You don't have any image open in the main window."); return; } Image4DSimple* p4DImage = callback.getImage(curwin); if (!p4DImage) { QMessageBox::information(0, "", "The image pointer is invalid. Ensure your data is valid and try again!"); return; } data1d = p4DImage->getRawData(); N = p4DImage->getXDim(); M = p4DImage->getYDim(); P = p4DImage->getZDim(); sc = p4DImage->getCDim(); bool ok1; if(sc==1) { c=1; ok1=true; } else { c = QInputDialog::getInteger(parent, "Channel", "Enter channel NO:", 1, 1, sc, 1, &ok1); } if(!ok1) return; in_sz[0] = N; in_sz[1] = M; in_sz[2] = P; in_sz[3] = sc; PARA.inimg_file = p4DImage->getFileName(); } else { int datatype = 0; if (!simple_loadimage_wrapper(callback,PARA.inimg_file.toStdString().c_str(), data1d, in_sz, datatype)) { fprintf (stderr, "Error happens in reading the subject file [%s]. Exit. \n",PARA.inimg_file.toStdString().c_str()); return; } if(PARA.channel < 1 || PARA.channel > in_sz[3]) { fprintf (stderr, "Invalid channel number. \n"); return; } N = in_sz[0]; M = in_sz[1]; P = in_sz[2]; sc = in_sz[3]; c = PARA.channel; } //main neuron reconstruction code cout<<"Start Rivulet"<<endl; printf("Image Size: %d, %d, %d\n", in_sz[0], in_sz[1], in_sz[2]); // Binarize Image with theshold const unsigned char threshold = PARA.threshold; const unsigned char stepsize = PARA.stepsize; const unsigned char gap = PARA.gap; const unsigned char dumpbranch = PARA.dumpbranch; const unsigned char connectrate = PARA.connectrate; const double percentage = PARA.percentage; cout<<"Tracing Parameters:"<<endl; printf("threshold:\t%d", threshold); printf("stepsize:\t%d", stepsize); printf("gap:\t%d", gap); printf("dumpbranch:\t%d", dumpbranch); printf("connectrate:\t%d", connectrate); printf("percentage:\t%f", percentage); int NVOX = M * N * P; // Distance Transform float * bdist1d = 0; cout<<"DT..."<<endl; unsigned char* binary_data1d; try { binary_data1d = new unsigned char[NVOX]; // Make a copy of the original data for radius estimation } catch(...) {v3d_msg("Cannot allocate memory for B."); return;} std::copy(data1d, data1d + NVOX, binary_data1d); // Fast marching distance transform proposed in APP2 fastmarching_dt(data1d, bdist1d, N, M, P, 2, threshold); // Using the Image Operation found in vaa3d_tools/hackathon/zhi/snake_tracing/TracingCore/ in for some simple Image Processing IM = new ImageOperation; int in_sz_int[4]; for(int i = 0; i < 4; i++) { in_sz_int[i] = (int)in_sz[i]; } IM->Imcreate(data1d, in_sz_int); // std::cout<<"image operation work or not?"<<std::endl; IM->computeHessian(PARA.sigma, PARA.alpha_one, PARA.alpha_two); std::cout<<"=== Hessian computation Finished..."<<std::endl; //----------------------------vesselness begin V3DLONG l_npixels_vessel; l_npixels_vessel = in_sz_int[0] * in_sz_int[1] * in_sz_int[2]; cout<<"l_npixels_vessel"<<l_npixels_vessel<<endl; GradientImageType::IndexType index; unsigned char *p_vessel = new unsigned char[l_npixels_vessel](); unsigned char *vp_tmp = p_vessel; ImageType::RegionType rg = (IM->finalim->GetLargestPossibleRegion()); ImageType::SizeType sz = rg.GetSize(); for(V3DLONG Z = 0;Z < in_sz[2]; Z++) for(V3DLONG Y = 0;Y < in_sz[1]; Y++) for(V3DLONG X = 0;X < in_sz[0]; X++) { index[0] = X; index[1] = Y; index[2] = Z; *vp_tmp = (unsigned char)(IM->finalim->GetPixel(index) * 100); vp_tmp++; } // cout<<"Before the vesselness image is saved."<<endl; // QString str_outimg_filename = PARA.inimg_file + "_vesselness.v3draw"; // saveImage(qPrintable(str_outimg_filename), p_vessel, in_sz, V3D_UINT8); // cout<<"After the vesselness image is saved."<<endl; cout<<"the vesselness image is binaried with threshold."<<endl; // binarize data for (int i=0; i<NVOX; i++) { // binary_data1d[i] = binary_data1d[i] > threshold? 1 : 0; binary_data1d[i] = p_vessel[i] > threshold? 1 : 0; } // Find the source point float maxd; V3DLONG maxidx = findmax(bdist1d, NVOX, &maxd); Point sourcepoint = ind2sub(maxidx, in_sz); // Make Speed Image for (int i = 0; i < NVOX - 1; i++) { float s = pow(bdist1d[i] / maxd, 4); bdist1d[i] = s == 0 ? 1e-10 : s; } // Marching on the Speed Image int sp[3]; sp[0] = (int)sourcepoint.x; sp[1] = (int)sourcepoint.y; sp[2] = (int)sourcepoint.z; double* bdist1d_double = float2double(bdist1d, NVOX); // printf("Source Point -- x: %d, y: %d, z: %d\n", (int)sourcepoint.x, (int)sourcepoint.y, (int)sourcepoint.z); double* oT = msfm(bdist1d_double, in_sz, sp, false, false, false); // Original Timemap if (bdist1d_double) {delete [] bdist1d_double; bdist1d_double = 0;} double* T = new double[NVOX]; // Timemap for tracing which is going to be erased copy(oT, oT + NVOX, T); vector<swcnode> tree; bool prune = true; // Calculate the gradient of the Distance map cout<<"Calculating Gradient"<<endl; double* grad = distgradient(T, in_sz); // cout<<"Gradient Calculated"<<endl; bool * B; try {B = new bool[NVOX];} catch(...) {v3d_msg("Cannot allocate memory for B."); return;} for (int i=0; i<NVOX; i++) { B[i] = false; } bool * tB; try {tB = new bool[NVOX];} catch(...) {v3d_msg("Cannot allocate memory for tB."); return;} for (int i=0; i<NVOX; i++) { tB[i] = false; } vector<float> lconfidence; // Mask T with 0 where 0 in original image for (int i=0; i<NVOX; i++) { T[i] = binary_data1d[i] ==0 ? 0 : T[i]; } // Start Tracing cout<<"Start Tracing"<<endl; cout<<" '.,\n 'b *\n '$ #.\n $: #:\n *# @):\n :@,@): ,.**:'\n , :@@*: ..**'\n '#o. .:(@'.@*\"'\n 'bq,..:,@@*' ,*\n ,p$q8,:@)' .p*'\n ' '@@Pp@@*'\n Y7'.'\n :@):.\n .:@:'.\n .::(@:. \n"<<endl; MyMarker marker; // Only for radius estimation std::clock_t start = std::clock(); while(true) { cout<<"."; // cout<<"N Branches:"<<tree.size()<<endl; double maxt; int maxidx = findmax(T, NVOX, &maxt); Point startpoint = ind2sub((V3DLONG)maxidx, in_sz); // Trace the shortest path from the farthest point to the source point Path l = shortestpath2(T, grad, binary_data1d, in_sz, startpoint, sourcepoint, stepsize, gap); // cout<<"after shortestpath2"<<endl; int pathlen = l.l.size(); //Get radius of each point from distance transform vector<float> radius(pathlen); for (int i=0; i< pathlen; i++) { V3DLONG idx = sub2ind(l.l[i].x, l.l[i].y, l.l[i].z, in_sz); // radius[i] = bdist1d[idx] < 1.0 ? 1.0 : bdist1d[idx]; marker.x = l.l[i].x; marker.y = l.l[i].y; marker.z = l.l[i].z; radius[i] = markerRadius(data1d, in_sz, marker, threshold, 2); } // Remove traced from the time map binarysphere3d(tB, in_sz, l.l, radius); tB[maxidx] = 1; V3DLONG bsum = 0; V3DLONG vsum = 0; for (int i=0; i<NVOX; i++) { T[i] = tB[i] == true ? -1 : T[i]; B[i] = tB[i] || B[i]; bsum += B[i] && binary_data1d[i] != 0? 1 : 0; vsum += binary_data1d[i]; } // Add l to tree if ( !(l.dump && dumpbranch) ) { float conf = addbranch2tree(&tree, l, connectrate, radius, binary_data1d, in_sz); lconfidence.push_back(conf); } else { // cout<<"Branch dumped"<<endl; } // Compute the coverage percent double percent = (double)bsum / (double)vsum; // cout<<"Percent:"<<percent* 100<<endl; if (percent >= percentage) { break; } } double duration = (std::clock() - start) / (double) CLOCKS_PER_SEC; cout<<"Tracing took "<<duration<<" seconds"<<endl; // Free up memory if (bdist1d) {delete [] bdist1d; bdist1d = 0;} if (oT) {delete [] oT; oT = 0;} if (T) {delete [] T; T = 0;} if (grad) {delete [] grad; grad = 0;} if (B) {delete [] B; B = 0;} if (binary_data1d) {delete [] binary_data1d; binary_data1d = 0;} //Output NeuronTree nt; QList <NeuronSWC> listNeuron; QHash <int, int> hashNeuron; listNeuron.clear(); hashNeuron.clear(); NeuronSWC S; for (int i = 0; i < tree.size(); i++) { S.n = tree[i].id; S.type = tree[i].type; S.x = tree[i].p.x; S.y = tree[i].p.y; S.z = tree[i].p.z; S.r = tree[i].radius; S.pn = tree[i].parent; listNeuron.append(S); hashNeuron.insert(S.n, listNeuron.size() - 1); } nt.n = -1; nt.on = true; nt.listNeuron = listNeuron; nt.hashNeuron = hashNeuron; QString swc_name = PARA.inimg_file + "_Rivulet.swc"; nt.name = "Rivulet"; writeSWC_file(swc_name.toStdString().c_str(),nt); celebrate(); cout<<"δὶς ἐς τὸν αὐτὸν ποταμὸν οὐκ ἂν ἐμβαίης. -- Ἡράκλειτος"<<endl; // if (bmenu) // { // msgBox.done(0); // } v3d_msg(QString("Now you can drag and drop the generated swc fle [%1] into Vaa3D.").arg(swc_name.toStdString().c_str()),bmenu); if(!bmenu) { if(data1d) {delete []data1d; data1d = 0;} } // v3d_msg(QString("Now you can drag and drop the generated swc fle [%1] into Vaa3D.").arg(swc_name.toStdString().c_str()),bmenu); return; }
bool anisodiff_func(V3DPluginCallback2 &callback, QWidget *parent, input_PARA &PARA, bool bmenu) { unsigned char* p_img_input = 0; V3DLONG sz_img_input[4]; if(bmenu) { v3dhandle curwin = callback.currentImageWindow(); if (!curwin) { QMessageBox::information(0, "", "You don't have any image open in the main window."); return false; } Image4DSimple* p4DImage = callback.getImage(curwin); if (!p4DImage) { QMessageBox::information(0, "", "The image pointer is invalid. Ensure your data is valid and try again!"); return false; } if(p4DImage->getDatatype()!=V3D_UINT8) { QMessageBox::information(0, "", "Please convert the image to be UINT8 and try again!"); return false; } if(p4DImage->getCDim()!=1) { QMessageBox::information(0, "", "The input image is not one channel image!"); return false; } p_img_input = p4DImage->getRawData(); sz_img_input[0] = p4DImage->getXDim(); sz_img_input[1] = p4DImage->getYDim(); sz_img_input[2] = p4DImage->getZDim(); sz_img_input[3] = 1; } else { int datatype = 0; if (!simple_loadimage_wrapper(callback,PARA.inimg_file.toStdString().c_str(), p_img_input, sz_img_input, datatype)) { fprintf (stderr, "Error happens in reading the subject file [%s]. Exit. \n",PARA.inimg_file.toStdString().c_str()); return false; } if(PARA.channel < 1 || PARA.channel > sz_img_input[3]) { fprintf (stderr, "Invalid channel number. \n"); return false; } if(datatype !=1) { fprintf (stderr, "Please convert the image to be UINT8 and try again!\n"); return false; } } //----------------------------------------------------------------------------------------- printf("1. Find the bounding box and crop image. \n"); long l_boundbox_min[3],l_boundbox_max[3];//xyz V3DLONG sz_img_crop[4]; long l_npixels_crop; unsigned char *p_img8u_crop=0; { //find bounding box unsigned char ***p_img8u_3d=0; if(!new3dpointer(p_img8u_3d,sz_img_input[0],sz_img_input[1],sz_img_input[2],p_img_input)) { printf("ERROR: Fail to allocate memory for the 4d pointer of image.\n"); if(p_img8u_3d) {delete3dpointer(p_img8u_3d,sz_img_input[0],sz_img_input[1],sz_img_input[2]);} return false; } l_boundbox_min[0]=sz_img_input[0]; l_boundbox_min[1]=sz_img_input[1]; l_boundbox_min[2]=sz_img_input[2]; l_boundbox_max[0]=0; l_boundbox_max[1]=0; l_boundbox_max[2]=0; for(long X=0;X<sz_img_input[0];X++) for(long Y=0;Y<sz_img_input[1];Y++) for(long Z=0;Z<sz_img_input[2];Z++) if(p_img8u_3d[Z][Y][X]>0.1) { if(l_boundbox_min[0]>X) l_boundbox_min[0]=X; if(l_boundbox_max[0]<X) l_boundbox_max[0]=X; if(l_boundbox_min[1]>Y) l_boundbox_min[1]=Y; if(l_boundbox_max[1]<Y) l_boundbox_max[1]=Y; if(l_boundbox_min[2]>Z) l_boundbox_min[2]=Z; if(l_boundbox_max[2]<Z) l_boundbox_max[2]=Z; } printf(">>boundingbox: x[%ld~%ld],y[%ld~%ld],z[%ld~%ld]\n",l_boundbox_min[0],l_boundbox_max[0], l_boundbox_min[1],l_boundbox_max[1], l_boundbox_min[2],l_boundbox_max[2]); //crop image sz_img_crop[0]=l_boundbox_max[0]-l_boundbox_min[0]+1; sz_img_crop[1]=l_boundbox_max[1]-l_boundbox_min[1]+1; sz_img_crop[2]=l_boundbox_max[2]-l_boundbox_min[2]+1; sz_img_crop[3]=1; l_npixels_crop=sz_img_crop[0]*sz_img_crop[1]*sz_img_crop[2]; p_img8u_crop=new(std::nothrow) unsigned char[l_npixels_crop](); if(!p_img8u_crop) { printf("ERROR: Fail to allocate memory for p_img32f_crop!\n"); if(p_img8u_3d) {delete3dpointer(p_img8u_3d,sz_img_input[0],sz_img_input[1],sz_img_input[2]);} return false; } unsigned char *p_tmp=p_img8u_crop; for(long Z=0;Z<sz_img_crop[2];Z++) for(long Y=0;Y<sz_img_crop[1];Y++) for(long X=0;X<sz_img_crop[0];X++) { *p_tmp = p_img8u_3d[Z+l_boundbox_min[2]][Y+l_boundbox_min[1]][X+l_boundbox_min[0]]; p_tmp++; } if(p_img8u_3d) {delete3dpointer(p_img8u_3d,sz_img_input[0],sz_img_input[1],sz_img_input[2]);} } //saveImage("d:/SVN/Vaa3D_source_code/v3d_external/released_plugins/v3d_plugins/anisodiffusion_littlequick/crop.raw",p_img8u_crop,sz_img_crop,1); //----------------------------------------------------------------------------------------- //convert image data type to float printf("2. Convert image data to float and scale to [0~255]. \n"); float *p_img32f_crop=0; { p_img32f_crop=new(std::nothrow) float[l_npixels_crop](); if(!p_img32f_crop) { printf("ERROR: Fail to allocate memory for p_img32f_crop!\n"); if(p_img8u_crop) {delete []p_img8u_crop; p_img8u_crop=0;} if(p_img32f_crop) {delete []p_img32f_crop; p_img32f_crop=0;} return false; } //find the maximal intensity value float d_maxintensity_input=0.0; for(long i=0;i<l_npixels_crop;i++) if(p_img8u_crop[i]>d_maxintensity_input) d_maxintensity_input=p_img8u_crop[i]; //convert and rescale for(long i=0;i<l_npixels_crop;i++) p_img32f_crop[i]=p_img8u_crop[i]/d_maxintensity_input*255.0; printf(">>d_maxintensity=%.2f\n",d_maxintensity_input); //free input image to save memory //if(p_img_input) {delete []p_img_input; p_img_input=0;} if(p_img8u_crop) {delete []p_img8u_crop; p_img8u_crop=0;} } //----------------------------------------------------------------------------------------- //do anisotropic diffusion printf("3. Do anisotropic diffusion... \n"); float *p_img32f_crop_output=0; if(!q_AnisoDiff3D(p_img32f_crop,sz_img_crop,p_img32f_crop_output)) { printf("ERROR: q_AnisoDiff3D() return false!\n"); if(p_img8u_crop) {delete []p_img8u_crop; p_img8u_crop=0;} if(p_img32f_crop) {delete []p_img32f_crop; p_img32f_crop=0;} if(p_img32f_crop_output) {delete []p_img32f_crop_output; p_img32f_crop_output=0;} return false; } if(p_img32f_crop) {delete []p_img32f_crop; p_img32f_crop=0;} //----------------------------------------------------------------------------------------- printf("4. Reconstruct processed crop image back to original size. \n"); unsigned char *p_img8u_output=0; long l_npixels=sz_img_input[0]*sz_img_input[1]*sz_img_input[2]*sz_img_input[3]; { p_img8u_output=new(std::nothrow) unsigned char[l_npixels](); if(!p_img8u_output) { printf("ERROR: Fail to allocate memory for p_img8u_output!\n"); if(p_img32f_crop_output) {delete []p_img32f_crop_output; p_img32f_crop_output=0;} return false; } //copy original image data to output image for(long i=0;i<l_npixels;i++) p_img8u_output[i]=p_img_input[i]; unsigned char ***p_img8u_3d=0; if(!new3dpointer(p_img8u_3d,sz_img_input[0],sz_img_input[1],sz_img_input[2],p_img8u_output)) { printf("ERROR: Fail to allocate memory for the 4d pointer of image.\n"); if(p_img8u_output) {delete []p_img8u_output; p_img8u_output=0;} if(p_img32f_crop_output) {delete []p_img32f_crop_output; p_img32f_crop_output=0;} return false; } float *p_tmp=p_img32f_crop_output; for(long Z=0;Z<sz_img_crop[2];Z++) for(long Y=0;Y<sz_img_crop[1];Y++) for(long X=0;X<sz_img_crop[0];X++) { p_img8u_3d[Z+l_boundbox_min[2]][Y+l_boundbox_min[1]][X+l_boundbox_min[0]]=(unsigned char)(*p_tmp); p_tmp++; } if(p_img8u_3d) {delete3dpointer(p_img8u_3d,sz_img_input[0],sz_img_input[1],sz_img_input[2]);} if(p_img32f_crop_output) {delete []p_img32f_crop_output; p_img32f_crop_output=0;} } //----------------------------------------------------------------------------------------- //save or display if(bmenu) { printf("5. Display the processed image in Vaa3D. \n"); //push result image back to v3d v3dhandle newwin=callback.newImageWindow("output"); Image4DSimple img4D_output; img4D_output.setData(p_img8u_output,sz_img_input[0],sz_img_input[1],sz_img_input[2],1,V3D_UINT8); callback.setImage(newwin,&img4D_output); callback.updateImageWindow(newwin); callback.open3DWindow(newwin); } else { printf("5. Save the processed image to file. \n"); QString str_outimg_filename = PARA.inimg_file + "_anisodiff.raw"; saveImage(qPrintable(str_outimg_filename),p_img8u_output,sz_img_input,1); if(p_img8u_output) {delete []p_img8u_output; p_img8u_output=0;} } printf(">>Program complete success!\n"); return true; }
void reconstruction_func(V3DPluginCallback2 &callback, QWidget *parent, input_PARA &PARA, bool bmenu) { unsigned char* data1d = 0; Image4DSimple* p4DImage; V3DLONG N,M,P,sc,c; V3DLONG in_sz[4]; if(bmenu) { v3dhandle curwin = callback.currentImageWindow(); if (!curwin) { QMessageBox::information(0, "", "You don't have any image open in the main window."); return; } p4DImage = callback.getImage(curwin); if (!p4DImage) { QMessageBox::information(0, "", "The image pointer is invalid. Ensure your data is valid and try again!"); return; } if(p4DImage->getDatatype()!=V3D_UINT8) { QMessageBox::information(0, "", "Please convert the image to be UINT8 and try again!"); return; } data1d = p4DImage->getRawData(); N = p4DImage->getXDim(); M = p4DImage->getYDim(); P = p4DImage->getZDim(); sc = p4DImage->getCDim(); unsigned char * inimg1d = p4DImage->getRawDataAtChannel(-1); bool ok1; if(sc==1) { c=1; ok1=true; } else { c = QInputDialog::getInteger(parent, "Channel", "Enter channel NO:", 1, 1, sc, 1, &ok1); } if(!ok1) return; in_sz[0] = N; in_sz[1] = M; in_sz[2] = P; in_sz[3] = sc; PARA.inimg_file = p4DImage->getFileName(); } else { int datatype = 0; if (!simple_loadimage_wrapper(callback,PARA.inimg_file.toStdString().c_str(), data1d, in_sz, datatype)) { fprintf (stderr, "Error happens in reading the subject file [%s]. Exit. \n",PARA.inimg_file.toStdString().c_str()); return; } if(PARA.channel < 1 || PARA.channel > in_sz[3]) { fprintf (stderr, "Invalid channel number. \n"); return; } if(datatype !=1) { fprintf (stderr, "Please convert the image to be UINT8 and try again!\n"); return; } N = in_sz[0]; M = in_sz[1]; P = in_sz[2]; sc = in_sz[3]; c = PARA.channel; } //main neuron reconstruction code //// THIS IS WHERE THE DEVELOPERS SHOULD ADD THEIR OWN NEURON TRACING CODE int se; V3DLONG pagesz = N*M*P; unsigned char *data1d_1ch; try {data1d_1ch = new unsigned char [pagesz];} catch(...) {v3d_msg("cannot allocate memory for data1d_1ch."); return;} for(V3DLONG i = 0; i < pagesz; i++) data1d_1ch[i] = data1d[i+(c-1)*pagesz]; Image4DSimple * p4dImageNew = 0; p4dImageNew = new Image4DSimple; if(!p4dImageNew->createImage(N,M,P,1, V3D_UINT8)) return; memcpy(p4dImageNew->getRawData(), data1d_1ch, pagesz); unsigned char * indata1d = p4dImageNew->getRawDataAtChannel(0); // fstream file; // file.open("file.swc", ios::out); fstream filelog; filelog.open("filelog.swc", ios::out); /* if (!file) { printf("Error opening file!\n"); exit(1); }*/ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // BW Function V3DLONG tb = in_sz[0]*in_sz[1]*in_sz[2]*p4DImage->getUnitBytes(); unsigned char * nm = NULL; try { nm = new unsigned char [tb]; } catch (...) { throw("Fail to allocate memory in Image Thresholding plugin."); } unsigned char * imdilate = NULL; try { imdilate = new unsigned char [tb]; } catch (...) { throw("Fail to allocate memory in Image Thresholding plugin."); } vector<MyMarker*> outswc[3]; float * phi = 0; vector<MyMarker *> outtree[3]; V3DLONG max_loc = 0; double max_val = -1; for (V3DLONG i=0;i<tb;i++) { if (indata1d[i]>=1) nm[i] = 255; else nm[i] = 0; } in_sz[0] = N; in_sz[1] = M; in_sz[2] = P; in_sz[3] = sc; int j = 0; QString swc_name = PARA.inimg_file + "_Cwlab_ver1.swc"; QByteArray temp = swc_name.toLatin1(); char* path = temp.data(); ofstream file(path); file << "#Supervisor: Prof Ching-Wei Wang ([email protected])\n#Authors: Ching-Wei Wang, M. Hilmil Muchtar Aditya Pradana ([email protected]), Cheng-Ta Huang ([email protected])\n#Institute: Medical Image Research Center, National Taiwan University of Science & Technology\n#Web: http://www-o.ntust.edu.tw/~cweiwang/\n#License: This plugin uses the same license as Vaa3D.\n"; for (int iteration=0;iteration<3;iteration++) { in_sz[0] = N; in_sz[1] = M; in_sz[2] = P; in_sz[3] = sc; se = 1; // strell if (iteration!=0) { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Closing // Create 3D image // dilate for (V3DLONG i=0;i<tb;i++) { if (nm[i]==255) { imdilate[i] = 255; for (V3DLONG j=0;j<se;j++) { for (V3DLONG k=0;k<se;k++) { for (V3DLONG l=0;l<se;l++) { if ((((i+(in_sz[0]*in_sz[1]*j))+(in_sz[0]*(k+1)))-(1*(l+1)))>=0 && (((i+(in_sz[0]*in_sz[1]*j))+(in_sz[0]*(k+1)))+(1*(l+1)))>=0 && ((i+(in_sz[0]*in_sz[1]*(j+1))-(in_sz[0]*(k+1)))-(1*(l+1)))>=0 && ((i+(in_sz[0]*in_sz[1]*(j+1))-(in_sz[0]*(k+1)))+(1*(l+1)))>=0 && (((i-(in_sz[0]*in_sz[1]*j))+(in_sz[0]*(k+1)))-(1*(l+1)))>=0 && (((i-(in_sz[0]*in_sz[1]*j))+(in_sz[0]*(k+1)))+(1*(l+1)))>=0 && ((i-(in_sz[0]*in_sz[1]*(j+1))-(in_sz[0]*(k+1)))-(1*(l+1)))>=0 && ((i-(in_sz[0]*in_sz[1]*(j+1))-(in_sz[0]*(k+1)))+(1*(l+1)))>=0) { //back //bottom mid //left imdilate[((i+(in_sz[0]*in_sz[1]*j))+(in_sz[0]*(k+1)))-(1*(l+1))] = 255; //back //bottom mid //right imdilate[((i+(in_sz[0]*in_sz[1]*j))+(in_sz[0]*(k+1)))+(1*(l+1))] = 255; //back //top mid //left imdilate[(i+(in_sz[0]*in_sz[1]*(j+1))-(in_sz[0]*(k+1)))-(1*(l+1))] = 255; //back //top mid //right imdilate[(i+(in_sz[0]*in_sz[1]*(j+1))-(in_sz[0]*(k+1)))+(1*(l+1))] = 255; //front //bottom mid //left imdilate[((i-(in_sz[0]*in_sz[1]*j))+(in_sz[0]*(k+1)))-(1*(l+1))] = 255; //front //bottom mid //right imdilate[((i-(in_sz[0]*in_sz[1]*j))+(in_sz[0]*(k+1)))+(1*(l+1))] = 255; //from //top mid //left imdilate[(i-(in_sz[0]*in_sz[1]*(j+1))-(in_sz[0]*(k+1)))-(1*(l+1))] = 255; //from //top mid //right imdilate[(i-(in_sz[0]*in_sz[1]*(j+1))-(in_sz[0]*(k+1)))+(1*(l+1))] = 255; } } } } } else { imdilate[i] = 0; } } } else if (iteration==2) { //erode for (V3DLONG i=0;i<tb;i++) { //front //right //top // imdilate[i-(in_sz[0]*in_sz[1]*se)-se-(se*in_sz[0])] //front //right //bottom // imdilate[i-(in_sz[0]*in_sz[1]*se)-se+(se*in_sz[0])] //front //left //top // imdilate[i-(in_sz[0]*in_sz[1]*se)+se-(se*in_sz[0])] //front //left //bottom // imdilate[i-(in_sz[0]*in_sz[1]*se)+se+(se*in_sz[0])] //back //right //top // imdilate[i+(in_sz[0]*in_sz[1]*se)-se-(se*in_sz[0])] //back //right //bottom // imdilate[i+(in_sz[0]*in_sz[1]*se)-se+(se*in_sz[0])] //back //left //top // imdilate[i+(in_sz[0]*in_sz[1]*se)+se-(se*in_sz[0])] //back //left //bottom // imdilate[i+(in_sz[0]*in_sz[1]*se)+se+(se*in_sz[0])] if (nm[i]!=imdilate[i]) { if ((i-(in_sz[0]*in_sz[1]*(se-1))-(se-1)-((se-1)*in_sz[0]))>=0 && (i-(in_sz[0]*in_sz[1]*se)-se+(se*in_sz[0]))>=0 && (i-(in_sz[0]*in_sz[1]*se)+se-(se*in_sz[0]))>=0 && (i-(in_sz[0]*in_sz[1]*se)+se+(se*in_sz[0]))>=0 && (i+(in_sz[0]*in_sz[1]*se)-se-(se*in_sz[0]))>=0 && (i+(in_sz[0]*in_sz[1]*se)-se+(se*in_sz[0]))>=0 && (i+(in_sz[0]*in_sz[1]*se)+se-(se*in_sz[0]))>=0 && (i+(in_sz[0]*in_sz[1]*se)+se+(se*in_sz[0]))) { if(imdilate[i-(in_sz[0]*in_sz[1]*(se-1))-(se-1)-((se-1)*in_sz[0])]!=255 || imdilate[i-(in_sz[0]*in_sz[1]*se)-se+(se*in_sz[0])]!=255 || imdilate[i-(in_sz[0]*in_sz[1]*se)+se-(se*in_sz[0])]!=255 || imdilate[i-(in_sz[0]*in_sz[1]*se)+se+(se*in_sz[0])]!=255 || imdilate[i+(in_sz[0]*in_sz[1]*se)-se-(se*in_sz[0])]!=255 || imdilate[i+(in_sz[0]*in_sz[1]*se)-se+(se*in_sz[0])]!=255 || imdilate[i+(in_sz[0]*in_sz[1]*se)+se-(se*in_sz[0])]!=255 || imdilate[i+(in_sz[0]*in_sz[1]*se)+se+(se*in_sz[0])]!=255) { nm[i] = 0; } else { nm[i] = 255; } } } } } if (iteration==0 || iteration==2) { indata1d = nm; } else if (iteration==1) { indata1d = imdilate; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// in_sz[3] = 1; double dfactor_xy = 1, dfactor_z = 1; if (in_sz[0]<=256 && in_sz[2]<=256 && in_sz[2]<=256) { dfactor_z = dfactor_xy = 1; } else if (in_sz[0] >= 2*in_sz[2] || in_sz[1] >= 2*in_sz[2]) { if (in_sz[2]<=256) { double MM = in_sz[0]; if (MM<in_sz[1]) MM=in_sz[1]; dfactor_xy = MM / 256.0; dfactor_z = 1; } else { double MM = in_sz[0]; if (MM<in_sz[1]) MM=in_sz[1]; if (MM<in_sz[2]) MM=in_sz[2]; dfactor_xy = dfactor_z = MM / 256.0; } } else { double MM = in_sz[0]; if (MM<in_sz[1]) MM=in_sz[1]; if (MM<in_sz[2]) MM=in_sz[2]; dfactor_xy = dfactor_z = MM / 256.0; } printf("dfactor_xy=%5.3f\n", dfactor_xy); printf("dfactor_z=%5.3f\n", dfactor_z); if (dfactor_z>1 || dfactor_xy>1) { v3d_msg("enter ds code", 0); V3DLONG out_sz[4]; unsigned char * outimg=0; if (!downsampling_img_xyz( indata1d, in_sz, dfactor_xy, dfactor_z, outimg, out_sz)) return; Image4DSimple * p4dImageNew2 = 0; p4dImageNew2 = new Image4DSimple; p4dImageNew2->setData(outimg, out_sz[0], out_sz[1], out_sz[2], out_sz[3], V3D_UINT8); indata1d = p4dImageNew2->getRawDataAtChannel(0); in_sz[0] = p4dImageNew2->getXDim(); in_sz[1] = p4dImageNew2->getYDim(); in_sz[2] = p4dImageNew2->getZDim(); in_sz[3] = p4dImageNew2->getCDim(); } cout<<"Start detecting cellbody"<<endl; float * phi = 0; vector<MyMarker> inmarkers; fastmarching_dt_XY(indata1d, phi, in_sz[0], in_sz[1], in_sz[2],2, 10); V3DLONG sz0 = in_sz[0]; V3DLONG sz1 = in_sz[1]; V3DLONG sz2 = in_sz[2]; V3DLONG sz01 = sz0 * sz1; V3DLONG tol_sz = sz01 * sz2; for(V3DLONG i = 0; i < tol_sz; i++) { if(phi[i] > max_val) { max_val = phi[i]; max_loc = i; } } MyMarker max_marker(max_loc % sz0, max_loc % sz01 / sz0, max_loc / sz01); inmarkers.push_back(max_marker); cout<<"======================================="<<endl; cout<<"Construct the neuron tree"<<endl; v3d_msg("8bit", 0); fastmarching_tree(inmarkers[0], indata1d, outtree[iteration], in_sz[0], in_sz[1], in_sz[2], 2, 10, false); cout<<"======================================="<<endl; //save a copy of the ini tree cout<<"Save the initial unprunned tree"<<endl; vector<MyMarker*> & inswc = outtree[iteration]; if (1) { V3DLONG tmpi; vector<MyMarker*> tmpswc; for (tmpi=0; tmpi<inswc.size(); tmpi++) { MyMarker * curp = new MyMarker(*(inswc[tmpi])); tmpswc.push_back(curp); if (dfactor_xy>1) inswc[tmpi]->x *= dfactor_xy; inswc[tmpi]->x += (0); if (dfactor_xy>1) inswc[tmpi]->x += dfactor_xy/2; if (dfactor_xy>1) inswc[tmpi]->y *= dfactor_xy; inswc[tmpi]->y += (0); if (dfactor_xy>1) inswc[tmpi]->y += dfactor_xy/2; if (dfactor_z>1) inswc[tmpi]->z *= dfactor_z; inswc[tmpi]->z += (0); if (dfactor_z>1) inswc[tmpi]->z += dfactor_z/2; } /* if (iteration==0) { saveSWC_file(QString(PARA.inimg_file).append("_ini1.swc").toStdString(), inswc); } else if (iteration==1) { saveSWC_file(QString(PARA.inimg_file).append("_ini2.swc").toStdString(), inswc); } else { saveSWC_file(QString(PARA.inimg_file).append("_ini3.swc").toStdString(), inswc); }*/ for (tmpi=0; tmpi<inswc.size(); tmpi++) { inswc[tmpi]->x = tmpswc[tmpi]->x; inswc[tmpi]->y = tmpswc[tmpi]->y; inswc[tmpi]->z = tmpswc[tmpi]->z; } for(tmpi = 0; tmpi < tmpswc.size(); tmpi++) delete tmpswc[tmpi]; tmpswc.clear(); } cout<<"Pruning neuron tree"<<endl; v3d_msg("start to use happ.\n", 0); happ(inswc, outswc[iteration], indata1d, in_sz[0], in_sz[1], in_sz[2],10, 5, 0.3333); if (p4dImageNew) {delete p4dImageNew; p4dImageNew=0;} //free buffe inmarkers[0].x *= dfactor_xy; inmarkers[0].y *= dfactor_xy; inmarkers[0].z *= dfactor_z; for(V3DLONG i = 0; i < outswc[iteration].size(); i++) { if (dfactor_xy>1) outswc[iteration][i]->x *= dfactor_xy; outswc[iteration][i]->x += 0; if (dfactor_xy>1) outswc[iteration][i]->x += dfactor_xy/2; if (dfactor_xy>1) outswc[iteration][i]->y *= dfactor_xy; outswc[iteration][i]->y += 0; if (dfactor_xy>1) outswc[iteration][i]->y += dfactor_xy/2; if (dfactor_z>1) outswc[iteration][i]->z *= dfactor_z; outswc[iteration][i]->z += 0; if (dfactor_z>1) outswc[iteration][i]->z += dfactor_z/2; outswc[iteration][i]->radius *= dfactor_xy; //use xy for now } //re-estimate the radius using the original image double real_thres = 40; V3DLONG szOriginalData[4] = {N,M,P, 1}; int method_radius_est = 2; map<MyMarker*,int>ind; for(V3DLONG i = 0; i < outswc[iteration].size(); i++) { ind[outswc[iteration][i]] = i+1; } for(V3DLONG i = 0; i < outswc[iteration].size(); i++) { //printf(" node %ld of %ld.\n", i, outswc.size()); outswc[iteration][i]->radius = markerRadius(data1d_1ch, szOriginalData, *(outswc[iteration][i]), real_thres, method_radius_est); int parentId = (outswc[iteration][i]->parent == 0) ? -1 : ind[outswc[iteration][i]->parent]; if(iteration==1) { if (parentId!=-1) parentId = parentId + outswc[0].size(); } if(iteration==2) { if (parentId!=-1) parentId = parentId + outswc[0].size() + outswc[1].size(); } j++; file << j << " " << outswc[iteration][i]->type << " " << outswc[iteration][i]->x << " " << outswc[iteration][i]->y << " " << outswc[iteration][i]->z << " " << outswc[iteration][i]->radius << " " << parentId << endl ; } } //Output // QString swc_name1 = PARA.inimg_file + "_APP2_ported1.swc"; // QString swc_name2 = PARA.inimg_file + "_APP2_ported2.swc"; // QString swc_name3 = PARA.inimg_file + "_APP2_ported3.swc"; // NeuronTree nt; // nt.name = "tracing method"; // writeSWC_file(swc_name.toStdString().c_str(),nt); // saveSWC_file(swc_name1.toStdString(), outswc[0]); // saveSWC_file(swc_name2.toStdString(), outswc[1]); // saveSWC_file(swc_name3.toStdString(), outswc[2]); //Combine image /* V3DLONG size_of_neuron[3], max_size, num_neuron; for (int iteration=0;iteration<3;iteration++) { size_of_neuron[iteration] = outswc[iteration].size(); } max_size = *max_element(size_of_neuron,size_of_neuron+3); for (int iteration=0;iteration<3;iteration++) { if (max_size==size_of_neuron[iteration]) num_neuron = iteration; } */ if(phi){delete [] phi; phi = 0;} //for(V3DLONG i = 0; i < outtree.size(); i++) delete outtree[i]; //outtree.clear(); if(data1d_1ch){delete []data1d_1ch; data1d_1ch = 0;} if(!bmenu) { if(data1d) {delete []data1d; data1d = 0;} } v3d_msg(QString("Now you can drag and drop the generated swc fle [%1] into Vaa3D.").arg(swc_name.toStdString().c_str()),bmenu); return; }
void reconstruction_func(V3DPluginCallback2 &callback, QWidget *parent, input_PARA &PARA, bool bmenu) { unsigned char* data1d = 0; V3DLONG N,M,P,sc,c; V3DLONG in_sz[4]; if(bmenu) { v3dhandle curwin = callback.currentImageWindow(); if (!curwin) { QMessageBox::information(0, "", "You don't have any image open in the main window."); return; } Image4DSimple* p4DImage = callback.getImage(curwin); if (!p4DImage) { QMessageBox::information(0, "", "The image pointer is invalid. Ensure your data is valid and try again!"); return; } if(p4DImage->getDatatype()!=V3D_UINT8) { QMessageBox::information(0, "", "Please convert the image to be UINT8 and try again!"); return; } data1d = p4DImage->getRawData(); N = p4DImage->getXDim(); M = p4DImage->getYDim(); P = p4DImage->getZDim(); sc = p4DImage->getCDim(); bool ok1; if(sc==1) { c=1; ok1=true; } else { c = QInputDialog::getInteger(parent, "Channel", "Enter channel NO:", 1, 1, sc, 1, &ok1); } if(!ok1) return; in_sz[0] = N; in_sz[1] = M; in_sz[2] = P; in_sz[3] = sc; PARA.inimg_file = p4DImage->getFileName(); } else { int datatype = 0; if (!simple_loadimage_wrapper(callback,PARA.inimg_file.toStdString().c_str(), data1d, in_sz, datatype)) { fprintf (stderr, "Error happens in reading the subject file [%s]. Exit. \n",PARA.inimg_file.toStdString().c_str()); return; } if(PARA.channel < 1 || PARA.channel > in_sz[3]) { fprintf (stderr, "Invalid channel number. \n"); return; } if(datatype !=1) { fprintf (stderr, "Please convert the image to be UINT8 and try again!\n"); return; } N = in_sz[0]; M = in_sz[1]; P = in_sz[2]; sc = in_sz[3]; c = PARA.channel; } //main neuron reconstruction code //// THIS IS WHERE THE DEVELOPERS SHOULD ADD THEIR OWN NEURON TRACING CODE V3DLONG pagesz = N*M*P; unsigned char *data1d_1ch; try {data1d_1ch = new unsigned char [pagesz];} catch(...) {v3d_msg("cannot allocate memory for data1d_1ch."); return;} for(V3DLONG i = 0; i < pagesz; i++) data1d_1ch[i] = data1d[i+(c-1)*pagesz]; Image4DSimple * p4dImageNew = 0; p4dImageNew = new Image4DSimple; if(!p4dImageNew->createImage(N,M,P,1, V3D_UINT8)) return; memcpy(p4dImageNew->getRawData(), data1d_1ch, pagesz); unsigned char * indata1d = p4dImageNew->getRawDataAtChannel(0); in_sz[3] = 1; double dfactor_xy = 1, dfactor_z = 1; if (in_sz[0]<=256 && in_sz[2]<=256 && in_sz[2]<=256) { dfactor_z = dfactor_xy = 1; } else if (in_sz[0] >= 2*in_sz[2] || in_sz[1] >= 2*in_sz[2]) { if (in_sz[2]<=256) { double MM = in_sz[0]; if (MM<in_sz[1]) MM=in_sz[1]; dfactor_xy = MM / 256.0; dfactor_z = 1; } else { double MM = in_sz[0]; if (MM<in_sz[1]) MM=in_sz[1]; if (MM<in_sz[2]) MM=in_sz[2]; dfactor_xy = dfactor_z = MM / 256.0; } } else { double MM = in_sz[0]; if (MM<in_sz[1]) MM=in_sz[1]; if (MM<in_sz[2]) MM=in_sz[2]; dfactor_xy = dfactor_z = MM / 256.0; } printf("dfactor_xy=%5.3f\n", dfactor_xy); printf("dfactor_z=%5.3f\n", dfactor_z); if (dfactor_z>1 || dfactor_xy>1) { v3d_msg("enter ds code", 0); V3DLONG out_sz[4]; unsigned char * outimg=0; if (!downsampling_img_xyz( indata1d, in_sz, dfactor_xy, dfactor_z, outimg, out_sz)) return; p4dImageNew->setData(outimg, out_sz[0], out_sz[1], out_sz[2], out_sz[3], V3D_UINT8); indata1d = p4dImageNew->getRawDataAtChannel(0); in_sz[0] = p4dImageNew->getXDim(); in_sz[1] = p4dImageNew->getYDim(); in_sz[2] = p4dImageNew->getZDim(); in_sz[3] = p4dImageNew->getCDim(); } vector<MyMarker *> outtree; cout<<"Start detecting cellbody"<<endl; float * phi = 0; vector<MyMarker> inmarkers; fastmarching_dt_XY(indata1d, phi, in_sz[0], in_sz[1], in_sz[2],2, 10); V3DLONG sz0 = in_sz[0]; V3DLONG sz1 = in_sz[1]; V3DLONG sz2 = in_sz[2]; V3DLONG sz01 = sz0 * sz1; V3DLONG tol_sz = sz01 * sz2; V3DLONG max_loc = 0; double max_val = phi[0]; for(V3DLONG i = 0; i < tol_sz; i++) { if(phi[i] > max_val) { max_val = phi[i]; max_loc = i; } } MyMarker max_marker(max_loc % sz0, max_loc % sz01 / sz0, max_loc / sz01); inmarkers.push_back(max_marker); cout<<"======================================="<<endl; cout<<"Construct the neuron tree"<<endl; v3d_msg("8bit", 0); fastmarching_tree(inmarkers[0], indata1d, outtree, in_sz[0], in_sz[1], in_sz[2], 2, 10, false); cout<<"======================================="<<endl; //save a copy of the ini tree cout<<"Save the initial unprunned tree"<<endl; vector<MyMarker*> & inswc = outtree; if (1) { V3DLONG tmpi; vector<MyMarker*> tmpswc; for (tmpi=0; tmpi<inswc.size(); tmpi++) { MyMarker * curp = new MyMarker(*(inswc[tmpi])); tmpswc.push_back(curp); if (dfactor_xy>1) inswc[tmpi]->x *= dfactor_xy; inswc[tmpi]->x += (0); if (dfactor_xy>1) inswc[tmpi]->x += dfactor_xy/2; if (dfactor_xy>1) inswc[tmpi]->y *= dfactor_xy; inswc[tmpi]->y += (0); if (dfactor_xy>1) inswc[tmpi]->y += dfactor_xy/2; if (dfactor_z>1) inswc[tmpi]->z *= dfactor_z; inswc[tmpi]->z += (0); if (dfactor_z>1) inswc[tmpi]->z += dfactor_z/2; } saveSWC_file(QString(PARA.inimg_file).append("_ini.swc").toStdString(), inswc); for (tmpi=0; tmpi<inswc.size(); tmpi++) { inswc[tmpi]->x = tmpswc[tmpi]->x; inswc[tmpi]->y = tmpswc[tmpi]->y; inswc[tmpi]->z = tmpswc[tmpi]->z; } for(tmpi = 0; tmpi < tmpswc.size(); tmpi++) delete tmpswc[tmpi]; tmpswc.clear(); } cout<<"Pruning neuron tree"<<endl; vector<MyMarker*> outswc; v3d_msg("start to use happ.\n", 0); happ(inswc, outswc, indata1d, in_sz[0], in_sz[1], in_sz[2],10, 5, 0.3333); if (p4dImageNew) {delete p4dImageNew; p4dImageNew=0;} //free buffe inmarkers[0].x *= dfactor_xy; inmarkers[0].y *= dfactor_xy; inmarkers[0].z *= dfactor_z; for(V3DLONG i = 0; i < outswc.size(); i++) { if (dfactor_xy>1) outswc[i]->x *= dfactor_xy; outswc[i]->x += 0; if (dfactor_xy>1) outswc[i]->x += dfactor_xy/2; if (dfactor_xy>1) outswc[i]->y *= dfactor_xy; outswc[i]->y += 0; if (dfactor_xy>1) outswc[i]->y += dfactor_xy/2; if (dfactor_z>1) outswc[i]->z *= dfactor_z; outswc[i]->z += 0; if (dfactor_z>1) outswc[i]->z += dfactor_z/2; outswc[i]->radius *= dfactor_xy; //use xy for now } //re-estimate the radius using the original image double real_thres = 40; V3DLONG szOriginalData[4] = {N,M,P, 1}; int method_radius_est = 2; for(V3DLONG i = 0; i < outswc.size(); i++) { //printf(" node %ld of %ld.\n", i, outswc.size()); outswc[i]->radius = markerRadius(data1d_1ch, szOriginalData, *(outswc[i]), real_thres, method_radius_est); } //Output QString swc_name = PARA.inimg_file + "_APP2_ported.swc"; // NeuronTree nt; // nt.name = "tracing method"; // writeSWC_file(swc_name.toStdString().c_str(),nt); saveSWC_file(swc_name.toStdString(), outswc); if(phi){delete [] phi; phi = 0;} for(V3DLONG i = 0; i < outtree.size(); i++) delete outtree[i]; outtree.clear(); if(data1d_1ch){delete []data1d_1ch; data1d_1ch = 0;} if(!bmenu) { if(data1d) {delete []data1d; data1d = 0;} } v3d_msg(QString("Now you can drag and drop the generated swc fle [%1] into Vaa3D.").arg(swc_name.toStdString().c_str()),bmenu); return; }
void reconstruction_func(V3DPluginCallback2 &callback, QWidget *parent, input_PARA &PARA, bool bmenu) { unsigned char* data1d = 0; V3DLONG N,M,P,sc,c; V3DLONG in_sz[4]; v3dhandle curwin; if(bmenu) { curwin = callback.currentImageWindow(); v3dhandle curwin = callback.currentImageWindow(); if (!curwin) { QMessageBox::information(0, "", "You don't have any image open in the main window."); return; } Image4DSimple* p4DImage = callback.getImage(curwin); if (!p4DImage) { QMessageBox::information(0, "", "The image pointer is invalid. Ensure your data is valid and try again!"); return; } data1d = p4DImage->getRawData(); N = p4DImage->getXDim(); M = p4DImage->getYDim(); P = p4DImage->getZDim(); sc = p4DImage->getCDim(); in_sz[0] = N; in_sz[1] = M; in_sz[2] = P; in_sz[3] = sc; PARA.inimg_file = p4DImage->getFileName(); } else { int datatype = 0; if (!simple_loadimage_wrapper(callback,PARA.inimg_file.toStdString().c_str(), data1d, in_sz, datatype)) { fprintf (stderr, "Error happens in reading the subject file [%s]. Exit. \n",PARA.inimg_file.toStdString().c_str()); return; } N = in_sz[0]; M = in_sz[1]; P = in_sz[2]; sc = in_sz[3]; } //main neuron reconstruction code //// THIS IS WHERE THE DEVELOPERS SHOULD ADD THEIR OWN NEURON TRACING CODE // ofstream oImgInfofile; string sImgPath = PARA.inimg_file.toStdString(); g_sAppDir = normalizePath(parentPath(sImgPath)); // g_sImageInfoPath = g_sAppDir + g_sImageInfoName; // g_sInputRawFilePath = g_sAppDir + g_sInputRawFileName; QString swc_name = PARA.inimg_file + "_nctuTW.swc"; g_sOutSwcFilePath = swc_name.toStdString(); //g_sOutSwcFilePath = g_sAppDir+ g_sOutSwcFileName; size_t nDataSize = N * M * P * sc ; width = N; height = M; zSize = P; // oImgInfofile.open(g_sImageInfoPath.data(), ios::out|ios::binary); // if(oImgInfofile.is_open()){ // oImgInfofile << N << " " << M << " " << P << endl; // oImgInfofile.close(); // } imgBuf_raw = new unsigned char [nDataSize]; memcpy(imgBuf_raw, data1d, nDataSize); // ofstream oRawFile; // oRawFile.open(g_sInputRawFilePath.data(), ios::out|ios::binary); // if(oRawFile.is_open()){ // oRawFile.write((char *)data1d, nDataSize); // oRawFile.close(); // } /* // For debug if(nParaState == QDialog::Accepted){ std::string sPara = "Threshold = " + toString(g_rThreshold) + "; " + "Soma = (" + toString(g_nSomaX) + ", " + toString(g_nSomaY) + ", " + toString(g_nSomaZ) + ")"; v3d_msg(QString(sPara.c_str())); } */ QDlgPara* pqDlgPara; g_nSomaX = -1; g_nSomaY = -1; g_nSomaZ = -1; int nParaState = 1; if(bmenu) //ui { LandmarkList Landmark; Landmark = callback.getLandmark(curwin); if(Landmark.size()>0) { g_nSomaX = Landmark.at(0).x-1; g_nSomaY = Landmark.at(0).y-1; g_nSomaZ = Landmark.at(0).z-1; } pqDlgPara = new QDlgPara(parent); nParaState = pqDlgPara->exec(); } else //command line { QList<ImageMarker> file_inmarkers; if(!PARA.inmarker_file.isEmpty()) { file_inmarkers = readMarker_file(PARA.inmarker_file); g_nSomaX = file_inmarkers.at(0).x; g_nSomaY = file_inmarkers.at(0).y; g_nSomaZ = file_inmarkers.at(0).z; } else { g_nSomaX = -1; g_nSomaY = -1; g_nSomaZ = -1; } g_rThreshold = PARA.threshold; } if(nParaState) { NeuronTracingMain(); v3d_msg(QString("Now you can drag and drop the generated swc fle [%1] into Vaa3D.").arg(swc_name.toStdString().c_str()),bmenu); } if(bmenu) delete pqDlgPara; bmenu=true; //Output // NeuronTree nt; //QString swc_name = PARA.inimg_file + "_nctuTW.swc"; // nt.name = "nctuTW"; // writeSWC_file(swc_name.toStdString().c_str(),nt); //QString swc_name(g_sOutSwcFilePath.data()); //Output if(!bmenu) { if(data1d) {delete []data1d; data1d = 0;} } delete [] imgBuf_raw; return; }
bool GVFplugin::dofunc(const QString & func_name, const V3DPluginArgList & input, V3DPluginArgList & output, V3DPluginCallback2 & callback, QWidget * parent) { if (func_name == tr("gvf_segmentation")) { int c=1; gvfsegPara segpara; // default values segpara.diffusionIteration = 5; segpara.fusionThreshold = 3; segpara.minRegion = 10; vector<char*> infiles, inparas, outfiles; if(input.size() >= 1) infiles = *((vector<char*> *)input.at(0).p); if(input.size() >= 2) { inparas = *((vector<char*> *)input.at(1).p); if(inparas.size() >= 1) c = atoi(inparas.at(0)); if(inparas.size() >= 2) segpara.diffusionIteration = atoi(inparas.at(1)); if(inparas.size() >= 3) segpara.fusionThreshold = atoi(inparas.at(2)); if(inparas.size() >= 4) segpara.minRegion = atoi(inparas.at(3)); if(output.size() >= 1) outfiles = *((vector<char*> *)output.at(0).p); } char * inimg_file = ((vector<char*> *)(input.at(0).p))->at(0); char * outimg_file = ((vector<char*> *)(output.at(0).p))->at(0); cout<<"channel choice "<<c<<endl; cout<<"diffusion Iterations "<<segpara.diffusionIteration<<endl; cout<<"fusion threshold "<<segpara.fusionThreshold<<endl; cout<<"minimum region size "<<segpara.minRegion<<endl; cout<<"inimg_file = "<<inimg_file<<endl; cout<<"outimg_file = "<<outimg_file<<endl; // check the input parameters for invalid choices: if ((segpara.diffusionIteration<1)||(segpara.fusionThreshold<1)||(segpara.minRegion)<0) { cout<< "* * * * * * * * * * * * * "<<endl; cout<< "*"<<endl; cout<< "INVALID parameter selection, type "<<endl; cout<<" vaa3d -x gvf_cellseg -f help "<<endl; cout<<"for more information"<<endl; cout<< "* * * * * * * * * * * * * "<<endl; cout<<""<<endl; return false; } V3DLONG in_sz[4]; int datatype; unsigned char * data1d = 0; if(!simple_loadimage_wrapper(callback, inimg_file, data1d, in_sz, datatype)) { cerr<<"load image "<<inimg_file<<" error!"<<endl; return false; } // allocate memory for the images Vol3DSimple <unsigned char> * tmp_inimg = 0; Vol3DSimple <USHORTINT16> * tmp_outimg = 0; try { tmp_inimg = new Vol3DSimple <unsigned char> (in_sz[0], in_sz[1], in_sz[2]); tmp_outimg = new Vol3DSimple <USHORTINT16> (in_sz[0], in_sz[1], in_sz[2]); } 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 false; } //load image // Image4DSimple * temp4D = callback.loadImage(inimg_file); in_sz[0]=temp4D->getXDim(); in_sz[1]=temp4D->getYDim(); in_sz[2]=temp4D->getZDim(); in_sz[3]=temp4D->getCDim(); if (in_sz[3]==1) { c=1; cout<< "Image only has 1 channel, segmenting channel 1"<<endl; } if ((c>in_sz[3])||(c<1)) { cout<< "* * * * * * * * * * * * * "<<endl; cout<< "*"<<endl; cout<< "INVALID CHANNEL SELECTION: User selected channel "<<c<< "; image has "<< in_sz[3] << " channels."<<endl; cout<< " aborting segmentation !"<<endl; cout<<"*"<<endl; cout<< "* * * * * * * * * * * * * "<<endl; cout<<""<<endl; return false; } //transfer single channel of data from Image4DSimple to old Vol3DSimple class memcpy((void *)tmp_inimg->getData1dHandle(), (void *)temp4D->getRawDataAtChannel(c-1), in_sz[0]*in_sz[1]*in_sz[2]); //now do computation using external function call bool b_res = gvfCellSeg(tmp_inimg, tmp_outimg, segpara); // clear out temporary space if (tmp_inimg) {delete tmp_inimg; tmp_inimg=0;} // now write to file in_sz[3]=1;//for single channel output from gvfCellSeg simple_saveimage_wrapper(callback, outimg_file, (unsigned char *)tmp_outimg->getData1dHandle(), in_sz, 2); //the output of gvfCellSeg is in 16bit // clear out temporary space if (tmp_outimg) {delete tmp_outimg; tmp_outimg=0;} if (temp4D) {delete temp4D; temp4D=0;} cout<<"Finished GVF Segmentation"<<endl; } else if (func_name == tr("help")) { cout<<endl; cout<<endl; cout<<" GVF segmentation plugin usage : vaa3d -x gvf_cellseg -f gvf_segmentation -i <input filename> -o <output filename -p <c> <iter> <fusion> <size>"<<endl; cout<<" parameters: (default values in parentheses) "<<endl; cout<<"c = channel of input file to use for segmentation (1) "<<endl; cout<<"iter = number of diffusion iterations (must be > 0) (5) "<<endl; cout<<"fusion = fusion size threshold (must be > 0) (3) "<<endl; cout<<"size = minimum region size in voxels (10)"<<endl; } else return false; return true; }
void processImage(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* p4DImage = callback.getImage(curwin); QString imgname = callback.getImageName(curwin); if (!p4DImage) { v3d_msg("The image pointer is invalid. Ensure your data is valid and try again!"); return; } int tmpx,tmpy,tmpz,x1,y1,z1; LandmarkList listLandmarks = callback.getLandmark(curwin); LocationSimple tmpLocation(0,0,0); int marknum = listLandmarks.count(); if(marknum ==0) { v3d_msg("No markers in the current image, please double check."); return; } UndirectedGraph g(marknum); for (int i=0;i<marknum;i++) { tmpLocation = listLandmarks.at(i); tmpLocation.getCoord(tmpx,tmpy,tmpz); x1 = tmpx; y1 = tmpy; z1 = tmpz; for (int j=0;j<marknum;j++) { EdgeQuery edgeq = edge(i, j, *&g); if (!edgeq.second && i!=j) { tmpLocation = listLandmarks.at(j); tmpLocation.getCoord(tmpx,tmpy,tmpz); double Vedge = sqrt(double(x1-tmpx)*double(x1-tmpx) + double(y1-tmpy)*double(y1-tmpy) + double(z1-tmpz)*double(z1-tmpz)); add_edge(i, j, LastVoted(i, Weight(Vedge)), *&g); } } } // property_map<UndirectedGraph, edge_weight_t>::type weightmap = get(edge_weight, *&g); vector < graph_traits < UndirectedGraph >::vertex_descriptor > p(num_vertices(*&g)); prim_minimum_spanning_tree(*&g, &p[0]); NeuronTree marker_MST; QList <NeuronSWC> listNeuron; QHash <int, int> hashNeuron; listNeuron.clear(); hashNeuron.clear(); for (std::size_t i = 0; i != p.size(); ++i) { NeuronSWC S; tmpLocation = listLandmarks.at(i); tmpLocation.getCoord(tmpx,tmpy,tmpz); int pn; if(p[i] == i) pn = -1; else pn = p[i] + 1; S.n = i+1; S.type = 7; S.x = tmpx; S.y = tmpy; S.z = tmpz; S.r = 1; S.pn = pn; listNeuron.append(S); hashNeuron.insert(S.n, listNeuron.size()-1); } marker_MST.n = -1; marker_MST.on = true; marker_MST.listNeuron = listNeuron; marker_MST.hashNeuron = hashNeuron; /* double** markEdge = new double*[marknum]; for(int i = 0; i < marknum; i++) { markEdge[i] = new double[marknum]; } for (int i=0;i<marknum;i++) { tmpLocation = listLandmarks.at(i); tmpLocation.getCoord(tmpx,tmpy,tmpz); x1 = tmpx; y1 = tmpy; z1 = tmpz; for (int j=0;j<marknum;j++) { tmpLocation = listLandmarks.at(j); tmpLocation.getCoord(tmpx,tmpy,tmpz); markEdge[i][j] = sqrt(double(x1-tmpx)*double(x1-tmpx) + double(y1-tmpy)*double(y1-tmpy) + double(z1-tmpz)*double(z1-tmpz)); } } //NeutronTree structure NeuronTree marker_MST; QList <NeuronSWC> listNeuron; QHash <int, int> hashNeuron; listNeuron.clear(); hashNeuron.clear(); //set node NeuronSWC S; tmpLocation = listLandmarks.at(0); tmpLocation.getCoord(tmpx,tmpy,tmpz); S.n = 1; S.type = 7; S.x = tmpx; S.y = tmpy; S.z = tmpz; S.r = 1; S.pn = -1; listNeuron.append(S); hashNeuron.insert(S.n, listNeuron.size()-1); int* pi = new int[marknum]; for(int i = 0; i< marknum;i++) pi[i] = 0; pi[0] = 1; int indexi,indexj; for(int loop = 0; loop<marknum;loop++) { double min = INF; for(int i = 0; i<marknum; i++) { if (pi[i] == 1) { for(int j = 0;j<marknum; j++) { if(pi[j] == 0 && min > markEdge[i][j]) { min = markEdge[i][j]; indexi = i; indexj = j; } } } } if(indexi>=0) { tmpLocation = listLandmarks.at(indexj); tmpLocation.getCoord(tmpx,tmpy,tmpz); S.n = indexj+1; S.type = 7; S.x = tmpx; S.y = tmpy; S.z = tmpz; S.r = 1; S.pn = indexi+1; listNeuron.append(S); hashNeuron.insert(S.n, listNeuron.size()-1); }else { break; } pi[indexj] = 1; indexi = -1; indexj = -1; } marker_MST.n = -1; marker_MST.on = true; marker_MST.listNeuron = listNeuron; marker_MST.hashNeuron = hashNeuron; */ QString outfilename = imgname + "_boost_marker.swc"; if (outfilename.startsWith("http", Qt::CaseInsensitive)) { QFileInfo ii(outfilename); outfilename = QDir::home().absolutePath() + "/" + ii.fileName(); } //v3d_msg(QString("The anticipated output file is [%1]").arg(outfilename)); writeSWC_file(outfilename,marker_MST); v3d_msg(QString("You have totally [%1] markers for the file [%2] and the computed MST has been saved to the file [%3]").arg(marknum).arg(imgname).arg(outfilename)); return; }
void reconstruction_func(V3DPluginCallback2 &callback, QWidget *parent, input_PARA &PARA, bool bmenu) { unsigned char* data1d = 0; V3DLONG N,M,P,sc,c; V3DLONG in_sz[4]; if(bmenu) { v3dhandle curwin = callback.currentImageWindow(); if (!curwin) { QMessageBox::information(0, "", "You don't have any image open in the main window."); return; } Image4DSimple* p4DImage = callback.getImage(curwin); if (!p4DImage) { QMessageBox::information(0, "", "The image pointer is invalid. Ensure your data is valid and try again!"); return; } data1d = p4DImage->getRawData(); N = p4DImage->getXDim(); M = p4DImage->getYDim(); P = p4DImage->getZDim(); sc = p4DImage->getCDim(); bool ok1; if(sc==1) { c=1; ok1=true; } else { c = QInputDialog::getInteger(parent, "Channel", "Enter channel NO:", 1, 1, sc, 1, &ok1); } if(!ok1) return; in_sz[0] = N; in_sz[1] = M; in_sz[2] = P; in_sz[3] = sc; PARA.inimg_file = p4DImage->getFileName(); } else { int datatype = 0; if (!simple_loadimage_wrapper(callback,PARA.inimg_file.toStdString().c_str(), data1d, in_sz, datatype)) { fprintf (stderr, "Error happens in reading the subject file [%s]. Exit. \n",PARA.inimg_file.toStdString().c_str()); return; } if(PARA.channel < 1 || PARA.channel > in_sz[3]) { fprintf (stderr, "Invalid channel number. \n"); return; } N = in_sz[0]; M = in_sz[1]; P = in_sz[2]; sc = in_sz[3]; c = PARA.channel; } //main neuron reconstruction code //// THIS IS WHERE THE DEVELOPERS SHOULD ADD THEIR OWN NEURON TRACING CODE if (!proc(callback, parent,data1d,in_sz,PARA.inimg_file)) return; //Output QString swc_name = PARA.inimg_file + "_fastmarching_spanningtree.swc"; // NeuronTree nt; // nt.name = "tracing method"; // writeSWC_file(swc_name.toStdString().c_str(),nt); if(!bmenu) { if(data1d) {delete []data1d; data1d = 0;} } v3d_msg(QString("Now you can drag and drop the generated swc fle [%1] into Vaa3D.").arg(swc_name.toStdString().c_str()),bmenu); return; }