// 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 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 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); }
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 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 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; }
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; }
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 bwlabelimg(V3DPluginCallback2 &callback, QWidget *parent, int method_code) { v3dhandle curwin = callback.currentImageWindow(); if (!curwin) { v3d_msg("You don't have any image open in the main window."); return; } if (method_code!=3 && method_code!=2) { v3d_msg("Invalid BWLabel method code. You should never see this message. Report this bug to the developer"); return; } LabelImgObjectParaDialog dialog(callback, parent); if (!dialog.image) return; if (dialog.exec()!=QDialog::Accepted) return; V3DLONG ch = dialog.ch; V3DLONG th_idx = dialog.th_idx; double tt = dialog.thresh; V3DLONG volsz_thres = (dialog.b_filtersmallobjs) ? dialog.volsz : 0; //the threshold to filter out small objects int start_t = clock(); // record time Image4DSimple* subject = callback.getImage(curwin); QString m_InputFileName = callback.getImageName(curwin); if (!subject) { QMessageBox::information(0, title, QObject::tr("No image is open.")); return; } if (subject->getDatatype()!=V3D_UINT8) { QMessageBox::information(0, title, QObject::tr("This demo program only supports 8-bit data. Your current image data type is not supported.")); return; } if (th_idx==0 || th_idx==1) { double mm, vv; mean_and_std(subject->getRawDataAtChannel(ch), subject->getTotalUnitNumberPerChannel(), mm, vv); tt = (th_idx == 0) ? mm : mm+vv; v3d_msg(QString("in fast image object labeling: ch=%1 mean=%2 std=%2").arg(ch).arg(mm).arg(vv), 0); } Image4DProxy<Image4DSimple> pSub(subject); V3DLONG sz0 = subject->getXDim(); V3DLONG sz1 = subject->getYDim(); V3DLONG sz2 = subject->getZDim(); V3DLONG sz3 = subject->getCDim(); //---------------------------------------------------------------------------------------------------------------------------------- V3DLONG channelsz = sz0*sz1*sz2; unsigned short int *pLabel = 0; unsigned char *pData = 0; try { pLabel = new unsigned short int [channelsz]; pData = new unsigned char [channelsz]; } catch (...) { v3d_msg("Fail to allocate memory in Fast Object Labeling Plugin."); if (pLabel) {delete []pLabel; pLabel=0;} if (pData) {delete []pData; pData=0;} return; } unsigned char * pSubtmp = pSub.begin(); for(V3DLONG i = 0; i < channelsz; i++) { pData[i] = (pSubtmp[i]<=tt) ? 0 : 1; } // dist transform V3DLONG sz_data[4]; sz_data[0]=sz0; sz_data[1]=sz1; sz_data[2]=sz2; sz_data[3]=1; V3DLONG nobjs=0; if (method_code==3) { V3DLONG nh_code=26; //6,18,or 26 nobjs = findConnectedComponent(pData, sz_data, 3, nh_code, pLabel); } else if (method_code==2) { V3DLONG nh_code=8; //4 or 8 nobjs = findConnectedComponent(pData, sz_data, 2, nh_code, pLabel); } else { v3d_msg("Invalid BWLabelN method code. You should never see this message. Report this bug to the developer"); return; } if (pData) {delete []pData; pData=0;} if (volsz_thres>0) //filter out small objects { try { float * hh = new float [nobjs]; float * mapval = new float [nobjs]; V3DLONG j; for (j=0;j<nobjs;j++) {hh[j]=0; mapval[j]=j;} //of course, 0 also map to 0! for (j=0;j<channelsz;j++) { //pLabel[j]--; //it seems Fuhui's data is 1-based, so subtract 1. Is this correct? hh[pLabel[j]]++; } V3DLONG k=0; for (j=1;j<nobjs;j++) //start from 1 as it is the background! { if (hh[j]<volsz_thres) { mapval[j]=0; //if less than a thres, then map to 0, which is background } else { printf("Obj [%ld] = [%ld]\n", V3DLONG(j), V3DLONG(hh[j])); k++; mapval[j] = k; //otherwise map to a continous label-value } } for (j=0;j<channelsz;j++) pLabel[j] = mapval[pLabel[j]]; if (hh) {delete []hh; hh=0;} if (mapval) {delete []mapval; mapval=0;} } catch (...) { v3d_msg("Unable to allocate memory to filter small objects. Thus skip it."); } } //---------------------------------------------------------------------------------------------------------------------------------- int end_t = clock(); printf("time eclapse %d s for labeling objects!\n", (end_t-start_t)/1000000); Image4DSimple p4DImage; p4DImage.setData((unsigned char*)pLabel, sz0, sz1, sz2, 1, V3D_UINT16); v3dhandle newwin = callback.newImageWindow(); callback.setImage(newwin, &p4DImage); callback.setImageName(newwin, QString("Object-Labeled Image")); callback.updateImageWindow(newwin); }
void processImage(V3DPluginCallback2 &callback, QWidget *parent, const QString & menu_name) { 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); if (!p4DImage) { v3d_msg("The image pointer is invalid. Ensure your data is valid and try again!"); return; } unsigned char* data1d = p4DImage->getRawData(); V3DLONG sc = p4DImage->getCDim(); //input bool b_res; bool ok1; V3DLONG c=-1; if (menu_name==QString("Split Channels")) c = -1; else if (menu_name==QString("Extract One Channel")) { if (sc>1) //only need to ask if more than one channel { c = QInputDialog::getInteger(parent, "Channel", "Enter channel # (0, 1... for the 1st, 2nd... channels; -1 for all channels):", -1, -1, sc-1, 1, &ok1); if (!ok1) return; } } V3DLONG in_sz[4]; in_sz[0] = p4DImage->getXDim(); in_sz[1] = p4DImage->getYDim(); in_sz[2] = p4DImage->getZDim(); in_sz[3] = sc; // V3DLONG cb, ce, k; if (c<0) {cb=0; ce=sc-1;} else {cb = ce = c;} void * outimg=0; for (k=cb; k<=ce; k++) { switch(p4DImage->getDatatype()) { case V3D_UINT8: b_res = extract_a_channel(data1d, in_sz, k, outimg); break; case V3D_UINT16: b_res = extract_a_channel((unsigned short int *)data1d, in_sz, k, outimg); break; case V3D_FLOAT32: b_res = extract_a_channel((float *)data1d, in_sz, k, outimg); break; default: b_res = false; v3d_msg("Right now this plugin supports only UINT8/UINT16/FLOAT32 data. Do nothing."); return; } //display Image4DSimple * new4DImage = new Image4DSimple(); new4DImage->createImage(in_sz[0], in_sz[1], in_sz[2], 1, p4DImage->getDatatype()); memcpy(new4DImage->getRawData(), (unsigned char *)outimg, new4DImage->getTotalBytes()); v3dhandle newwin = callback.newImageWindow(); callback.setImage(newwin, new4DImage); callback.setImageName(newwin, QString("").setNum(k).prepend("_C").prepend(p4DImage->getFileName())); callback.updateImageWindow(newwin); } }
bool profile_swc_menu(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 false; } Image4DSimple * image = callback.getImage(curwin); OpenSWCDialog * openDlg = new OpenSWCDialog(0, &callback); if (!openDlg->exec()) return false; NeuronTree nt = openDlg->nt; QString swcFileName = openDlg->file_name; QString output_csv_file = swcFileName + QString(".csv"); float dilate_ratio = QInputDialog::getDouble(parent, "dilate_ratio", "Enter dialate ratio:", 3.0, 1.0, 100.0); int flip = QInputDialog::getInteger(parent, "flip in y ?", "Flip in Y (0/1):", 0, 0, 1); int invert = QInputDialog::getInteger(parent, "invert intensity ? (for calculating tubularities, signals should be brighter than background", "Invert Intensity (0/1):", 0, 0, 1); QList<IMAGE_METRICS> result_metrics = intensity_profile(nt, image, dilate_ratio,flip,invert,callback); if (result_metrics.isEmpty()) { cout<<"Error in intensity_profile() !"<<endl; return false; } //output writeMetrics2CSV(result_metrics, output_csv_file); IMAGE_METRICS m_stats = result_metrics[0]; QString disp_text = ""; disp_text += "Contrast-to-Background Ratio = " + QString::number(m_stats.cnr) + ";\n"; disp_text += "Dynamic Range = " + QString::number(m_stats.dy) + ";\n"; disp_text += "Mean FG Intensity = " + QString::number (m_stats.fg_mean) + ", STD = " + QString::number(m_stats.fg_std) + ";\n"; disp_text += "Mean BG Intensity = " + QString::number (m_stats.bg_mean) + ", STD = " + QString::number(m_stats.bg_std) + ";\n"; disp_text += "Mean Tubularity = " + QString::number(m_stats.tubularity_mean) + ", STD = " + QString::number(m_stats.tubularity_std) + ".\n"; disp_text += "\n Segment type-specific screening metrics are exported in: \n "+ output_csv_file +"\n"; /* ENSEMBLE_METRICS m_stats = stats_ensemble(result_metrics); //display metrics to the msg window QString disp_text = ""; disp_text += "Mean FG Intensity = " + QString::number (m_stats.mean_fg) + ", STD = " + QString::number(m_stats.std_fg) + ";\n"; disp_text += "Mean BG Intensity = " + QString::number(m_stats.mean_bg ) + ", STD = " + QString::number(m_stats.std_bg) + ";\n"; disp_text += "Mean Contrast-to-Background Ratio = " + QString::number(m_stats.mean_cnr) + ", STD = " + QString::number(m_stats.std_cnr) + ";\n"; disp_text += "Mean Dynamic Range = " + QString::number(m_stats.mean_dy) + ", STD = " + QString::number(m_stats.std_dy) + ";\n"; disp_text += "Mean Tubularity = " + QString::number(m_stats.mean_tubularity) + ", STD = " + QString::number(m_stats.std_tubularity) + ".\n"; disp_text += "\n Screening Metrics of each segment can be found in: \n "+ output_csv_file +"\n"; */ v3d_msg(disp_text); return true; }
bool do_AtlasGuidedStrAnno(V3DPluginCallback2 &callback, QString &qs_filename_img, QString &qs_filename_marker_input, // input files QString &qs_filename_atals_input, QString &qs_filename_celloi_input, QString &qs_filename_celloi_2_input, CSParas ¶s_str, CParas ¶s_anno, bool &b_use_celloi_2, // paras QString &qs_filename_atals_output, QString &qs_filename_seglabel_output ) // output files { //------------------------------------------------------------------------------------------------------------------------------------ printf("1. Import image. \n"); unsigned char *p_img_input=0; V3DLONG sz_img_input[4]; int datatype_input=0; if(!paras_str.b_imgfromV3D) { if(qs_filename_img.isEmpty()) { v3d_msg(QString("invalid image path!")); return false; } if(!simple_loadimage_wrapper(callback, (char *)qPrintable(qs_filename_img),p_img_input,sz_img_input,datatype_input)) { v3d_msg(QString("open file [%1] failed!").arg(qs_filename_img)); return false; } printf("\t>>read image file [%s] complete.\n",qPrintable(qs_filename_img)); } else { printf("\t>>import image from V3D. \n"); v3dhandleList h_wndlist=callback.getImageWindowList(); if(h_wndlist.size()<1) { v3d_msg(QString("Make sure there are at least 1 image in V3D!")); return false; } Image4DSimple* image=callback.getImage(callback.currentImageWindow()); p_img_input=image->getRawData(); //sz_img_input=new V3DLONG[4](); sz_img_input[0]=image->getXDim(); sz_img_input[1]=image->getYDim(); sz_img_input[2]=image->getZDim(); sz_img_input[3]=image->getCDim(); datatype_input=image->getDatatype(); } printf("\t\timage size: [w=%ld, h=%ld, z=%ld, c=%ld]\n",sz_img_input[0],sz_img_input[1],sz_img_input[2],sz_img_input[3]); printf("\t\tdatatype: %d\n",datatype_input); //------------------------------------------------------------------------------------------------------------------------------------ printf("2. Convert image datatype to uint8. \n"); unsigned char * p_img_8u=0; { V3DLONG l_npixels=sz_img_input[0]*sz_img_input[1]*sz_img_input[2]*sz_img_input[3]; p_img_8u=new unsigned char[l_npixels]; if(!p_img_8u) { printf("ERROR: Fail to allocate memory. Do nothing. \n"); if(p_img_input && !paras_str.b_imgfromV3D) {delete []p_img_input; p_img_input=0;} //if(sz_img_input) {delete []sz_img_input; sz_img_input=0;} return false; } if(datatype_input==1) { printf("\t>>convert image data from uint8 to uint8. \n"); for(V3DLONG i=0;i<l_npixels;i++) p_img_8u[i]=p_img_input[i]; } else if(datatype_input==2) { printf("\t>>convert image data from uint16 to uint8. \n"); double min,max; if(!rescale_to_0_255_and_copy((unsigned short int *)p_img_input,l_npixels,min,max,p_img_8u)) { printf("ERROR: rescale_to_0_255_and_copy() return false.\n"); if(p_img_8u) {delete []p_img_8u; p_img_8u=0;} if(p_img_input && !paras_str.b_imgfromV3D) {delete []p_img_input; p_img_input=0;} //if(sz_img_input) {delete []sz_img_input; sz_img_input=0;} return false; } } else if(datatype_input==4) { printf("\t>>convert image data from float to uint8. \n"); double min,max; if(!rescale_to_0_255_and_copy((float *)p_img_input,l_npixels,min,max,p_img_8u)) { printf("ERROR: rescale_to_0_255_and_copy() return false.\n"); if(p_img_8u) {delete []p_img_8u; p_img_8u=0;} if(p_img_input && !paras_str.b_imgfromV3D) {delete []p_img_input; p_img_input=0;} //if(sz_img_input) {delete []sz_img_input; sz_img_input=0;} return false; } } else { v3d_msg(QString("Unknown datatype!\n")); if(p_img_8u) {delete []p_img_8u; p_img_8u=0;} if(p_img_input && !paras_str.b_imgfromV3D) {delete []p_img_input; p_img_input=0;} //if(sz_img_input) {delete []sz_img_input; sz_img_input=0;} return false; } } //------------------------------------------------------------------------------------------------------------------------------------ printf("3. Import markers. \n"); //get initial head and tail marker position from V3D vector< vector<double> > vec2d_markers; if(!paras_str.b_markerfromV3D) { if(qs_filename_marker_input.isEmpty() || qs_filename_marker_input.toUpper()=="NULL") { v3d_msg(QString("Invalid marker path! Ignore it!"), 0); vec2d_markers.clear(); /* //commented by PHC 2013-08-21 if(p_img_8u) {delete []p_img_8u; p_img_8u=0;} if(p_img_input && !paras_str.b_imgfromV3D) {delete []p_img_input; p_img_input=0;} if(sz_img_input) {delete []sz_img_input; sz_img_input=0;} return false; */ } else { QList<ImageMarker> ql_markers=readMarker_file(qs_filename_marker_input); printf("\t>>read %d markers from file: %s.\n",ql_markers.size(),qPrintable(qs_filename_marker_input)); vector<double> vec_marker(3,0); for(V3DLONG i=0;i<ql_markers.size();i++) { vec_marker[0]=ql_markers[i].x; vec_marker[1]=ql_markers[i].y; vec_marker[2]=ql_markers[i].z; vec2d_markers.push_back(vec_marker); } } } else { printf("\t>>import markers from V3D. \n"); v3dhandleList h_wndlist=callback.getImageWindowList(); if(h_wndlist.size()<1) { v3d_msg(QString("Make sure there are at least 1 image in V3D!")); if(p_img_8u) {delete []p_img_8u; p_img_8u=0;} if(p_img_input && !paras_str.b_imgfromV3D) {delete []p_img_input; p_img_input=0;} //if(sz_img_input) {delete []sz_img_input; sz_img_input=0;} return false; } LandmarkList ml_makers=callback.getLandmark(callback.currentImageWindow()); vector<double> vec_marker(3,0); for(V3DLONG i=0;i<ml_makers.size();i++) { vec_marker[0]=ml_makers[i].x; vec_marker[1]=ml_makers[i].y; vec_marker[2]=ml_makers[i].z; vec2d_markers.push_back(vec_marker); } } //------------------------------------------------------------------------------------------------------------------------------------ printf("4. Read atlas apo file. \n"); QList<CellAPO> ql_atlasapo; ql_atlasapo=readAPO_file(qs_filename_atals_input); printf("\t>>read %d points from [%s]\n",ql_atlasapo.size(),qPrintable(qs_filename_atals_input)); if(ql_atlasapo.size()<=0) { v3d_msg(QString("Given atlas file is empty or invalid!")); if(p_img_8u) {delete []p_img_8u; p_img_8u=0;} if(p_img_input && !paras_str.b_imgfromV3D) {delete []p_img_input; p_img_input=0;} //if(sz_img_input) {delete []sz_img_input; sz_img_input=0;} return false; } //------------------------------------------------------------------------------------------------------------------------------------ printf("5. Read interesting cell file. \n"); QList<QString> ql_celloi_name; if(!readCelloi_file(qs_filename_celloi_input,ql_celloi_name)) { printf("ERROR: readCelloi_file() return false! \n"); if(p_img_8u) {delete []p_img_8u; p_img_8u=0;} if(p_img_input && !paras_str.b_imgfromV3D) {delete []p_img_input; p_img_input=0;} //if(sz_img_input) {delete []sz_img_input; sz_img_input=0;} return false; } printf("\t>>interesting cell:\n"); for(V3DLONG i=0;i<ql_celloi_name.size();i++) printf("\t\t%s\n",qPrintable(ql_celloi_name[i])); //------------------------------------------------------------------------------------------------------------------------------------ printf("6. Do Straightening. \n"); unsigned char *p_strimg=0; V3DLONG *sz_strimg=0; vector< vector< vector< vector<V3DLONG> > > > vec4d_mappingfield_str2ori; if(vec2d_markers.size()<2) { printf("\t>>marker num < 2, skip straightening.\n"); } else { printf("\t>>marker num >= 2, do straightening.\n"); V3DLONG l_width=paras_str.l_radius_cuttingplane*2+1; QList<ImageMarker> ql_marker; for(unsigned V3DLONG i=0;i<vec2d_markers.size();i++) { ImageMarker tmp; tmp.x=vec2d_markers[i][0]; tmp.y=vec2d_markers[i][1]; tmp.z=vec2d_markers[i][2]; ql_marker.push_back(tmp); } if(!q_celegans_restacking_xy( p_img_8u,sz_img_input, ql_marker,l_width, p_strimg,sz_strimg, vec4d_mappingfield_str2ori)) { printf("ERROR: q_celegans_restacking_xy() return false! \n"); if(p_img_8u) {delete []p_img_8u; p_img_8u=0;} if(p_img_input && !paras_str.b_imgfromV3D) {delete []p_img_input; p_img_input=0;} //if(sz_img_input) {delete []sz_img_input; sz_img_input=0;} return false; } } //------------------------------------------------------------------------------------------------------------------------------------ printf("7. Do Annotation. \n"); QList<CellAPO> ql_musclecell_output; unsigned char *p_img8u_seglabel=0; COutputInfo outputinfo; { unsigned char *p_img_anno=0; V3DLONG *sz_img_anno=0; if(vec2d_markers.size()<2) //on non-straightened image { p_img_anno=p_img_input; sz_img_anno=sz_img_input; } else //on straightened image { p_img_anno=p_strimg; sz_img_anno=sz_strimg; } if(paras_anno.l_mode==-1) //non-partial annotation { if(!q_atlas2image(paras_anno,callback, p_img_anno,sz_img_anno,ql_atlasapo,ql_celloi_name, ql_musclecell_output,p_img8u_seglabel,outputinfo)) { printf("ERROR: q_atlas2image() return false!\n"); if(p_strimg) {delete []p_strimg; p_strimg=0;} if(sz_strimg) {delete []sz_strimg; sz_strimg=0;} if(p_img_8u) {delete []p_img_8u; p_img_8u=0;} if(p_img_input && !paras_str.b_imgfromV3D) {delete []p_img_input; p_img_input=0;} //if(sz_img_input) {delete []sz_img_input; sz_img_input=0;} return false; } } else if(paras_anno.l_mode==4) //align dapi { if(!q_align_dapicells(paras_anno,callback, p_img_anno,sz_img_anno,ql_atlasapo,ql_celloi_name, ql_musclecell_output,outputinfo)) { printf("ERROR: q_atlas2image_partial() return false!\n"); if(p_strimg) {delete []p_strimg; p_strimg=0;} if(sz_strimg) {delete []sz_strimg; sz_strimg=0;} if(p_img_8u) {delete []p_img_8u; p_img_8u=0;} if(p_img_input && !paras_str.b_imgfromV3D) {delete []p_img_input; p_img_input=0;} //if(sz_img_input) {delete []sz_img_input; sz_img_input=0;} return false; } } else //partial annotation { if(!q_atlas2image_partial(paras_anno,callback, p_img_anno,sz_img_anno,ql_atlasapo,ql_celloi_name, ql_musclecell_output,outputinfo)) { printf("ERROR: q_atlas2image_partial() return false!\n"); if(p_strimg) {delete []p_strimg; p_strimg=0;} if(sz_strimg) {delete []sz_strimg; sz_strimg=0;} if(p_img_8u) {delete []p_img_8u; p_img_8u=0;} if(p_img_input && !paras_str.b_imgfromV3D) {delete []p_img_input; p_img_input=0;} //if(sz_img_input) {delete []sz_img_input; sz_img_input=0;} return false; } } } if(outputinfo.b_rotate90) v3d_msg("The deformed atlas maybe wrongly 90 degree rotated!\nCheck result!\n"); //------------------------------------------------------------------------------------------------------------------------------------ //warping the secondary interesting cells if provided based on the TPS paras obtained from the first group result QList<CellAPO> ql_cellio2_tps; if( b_use_celloi_2 || !qs_filename_celloi_2_input.isEmpty()) // b_use_celloi_2 = DLG_stranno.checkBox_celloi_2->isChecked() { printf("8-9. Warping the secondary interesting cells. \n"); QList<QString> ql_celloi2_name; if(!readCelloi_file(qs_filename_celloi_2_input,ql_celloi2_name)) { printf("ERROR: readCelloi_file() return false! \n"); return false; } vector<point3D64F> vec_cellio1_ori,vec_cellio1_tps,vec_cellio2_ori; QList<CellAPO> ql_cellio2_ori; point3D64F tmp; //extract first interesting cells for(V3DLONG i=0;i<ql_atlasapo.size();i++) { QString qs_cellname=ql_atlasapo[i].name; qs_cellname=qs_cellname.simplified(); qs_cellname=qs_cellname.toUpper(); ql_atlasapo[i].name=qs_cellname; for(V3DLONG j=0;j<ql_celloi_name.size();j++) { if(ql_celloi_name[j].contains("*")) { QString qs_cellnamevalid=ql_celloi_name[j]; qs_cellnamevalid.remove("*"); if(qs_cellname.contains(qs_cellnamevalid,Qt::CaseInsensitive)) { tmp.x=ql_atlasapo[i].x; tmp.y=ql_atlasapo[i].y; tmp.z=ql_atlasapo[i].z; vec_cellio1_ori.push_back(tmp); } } else if(qs_cellname.compare(ql_celloi_name[j],Qt::CaseInsensitive)==0) { tmp.x=ql_atlasapo[i].x; tmp.y=ql_atlasapo[i].y; tmp.z=ql_atlasapo[i].z; vec_cellio1_ori.push_back(tmp); } } } for(V3DLONG i=0;i<ql_musclecell_output.size();i++) { tmp.x=ql_musclecell_output[i].x; tmp.y=ql_musclecell_output[i].y; tmp.z=ql_musclecell_output[i].z; vec_cellio1_tps.push_back(tmp); } //extract secondary interesting cells for(V3DLONG i=0;i<ql_atlasapo.size();i++) { QString qs_cellname=ql_atlasapo[i].name; qs_cellname=qs_cellname.simplified(); qs_cellname=qs_cellname.toUpper(); ql_atlasapo[i].name=qs_cellname; for(V3DLONG j=0;j<ql_celloi2_name.size();j++) { if(ql_celloi2_name[j].contains("*")) { QString qs_cellnamevalid=ql_celloi2_name[j]; qs_cellnamevalid.remove("*"); if(qs_cellname.contains(qs_cellnamevalid,Qt::CaseInsensitive)) { ql_cellio2_ori.push_back(ql_atlasapo[i]); tmp.x=ql_atlasapo[i].x; tmp.y=ql_atlasapo[i].y; tmp.z=ql_atlasapo[i].z; vec_cellio2_ori.push_back(tmp); } } else if(qs_cellname.compare(ql_celloi2_name[j],Qt::CaseInsensitive)==0) { ql_cellio2_ori.push_back(ql_atlasapo[i]); tmp.x=ql_atlasapo[i].x; tmp.y=ql_atlasapo[i].y; tmp.z=ql_atlasapo[i].z; vec_cellio2_ori.push_back(tmp); } } } ql_cellio2_tps=ql_cellio2_ori; printf("\t>>[%d] cells in the secondary intereting cell group.\n",ql_cellio2_ori.size()); //compute TPS paras Matrix x4x4_affine,xnx4_c,xnxn_K; if(!q_TPS_cd(vec_cellio1_ori,vec_cellio1_tps,0,x4x4_affine,xnx4_c,xnxn_K)) { printf("ERROR: q_TPS_cd() return false!\n"); return false; } //compute TPS kernal matrix Matrix xmxn_K; if(!q_TPS_k(vec_cellio2_ori,vec_cellio1_ori,xmxn_K)) { printf("ERROR: q_TPS_k() return false!\n"); return false; } //warp the secondary cells Matrix x_ori(ql_cellio2_ori.size(),4),x_tps(ql_cellio2_ori.size(),4); for(V3DLONG i=0;i<ql_cellio2_ori.size();i++) { x_ori(i+1,1)=1.0; x_ori(i+1,2)=ql_cellio2_ori[i].x; x_ori(i+1,3)=ql_cellio2_ori[i].y; x_ori(i+1,4)=ql_cellio2_ori[i].z; } x_tps=x_ori*x4x4_affine+xmxn_K*xnx4_c; for(V3DLONG i=0;i<ql_cellio2_tps.size();i++) { ql_cellio2_tps[i].x=x_tps(i+1,2)/x_tps(1,1); ql_cellio2_tps[i].y=x_tps(i+1,3)/x_tps(1,1); ql_cellio2_tps[i].z=x_tps(i+1,4)/x_tps(1,1); } } //------------------------------------------------------------------------------------------------------------------------------------ printf("10. Map the annotated cell back to non-straightened image. \n"); QList<CellAPO> ql_musclecell_output_ori(ql_musclecell_output); //map back to non-straightened image if(vec2d_markers.size()>=2) { for(V3DLONG i=0;i<ql_musclecell_output.size();i++) { V3DLONG x=ql_musclecell_output[i].x; V3DLONG y=ql_musclecell_output[i].y; V3DLONG z=ql_musclecell_output[i].z; ql_musclecell_output_ori[i].x=vec4d_mappingfield_str2ori[y][x][z][0]; ql_musclecell_output_ori[i].y=vec4d_mappingfield_str2ori[y][x][z][1]; ql_musclecell_output_ori[i].z=vec4d_mappingfield_str2ori[y][x][z][2]; } } if(b_use_celloi_2 || !qs_filename_celloi_2_input.isEmpty()) // b_use_celloi_2=DLG_stranno.checkBox_celloi_2->isChecked() ql_musclecell_output_ori.append(ql_cellio2_tps); //save deformed point cloud to apo file if(!qs_filename_atals_output.isEmpty()) writeAPO_file(qPrintable(qs_filename_atals_output),ql_musclecell_output_ori); //show deformed atlas pts in V3D // if(!(paras_anno.b_showatlas || paras_anno.b_showsegmentation)) { v3dhandle curwin=callback.currentImageWindow(); // v3dhandle curwin=callback.getImageWindowList()[0]; callback.open3DWindow(curwin); LandmarkList curlist; for(int i=0;i<ql_musclecell_output_ori.size();i++) { LocationSimple s; s.x=ql_musclecell_output_ori[i].x+1;//note: marker coord start from 1 instead of 0 s.y=ql_musclecell_output_ori[i].y+1;//note: marker coord start from 1 instead of 0 s.z=ql_musclecell_output_ori[i].z+1;//note: marker coord start from 1 instead of 0 s.name=ql_musclecell_output_ori[i].name.toStdString(); s.radius=10; curlist << s; } callback.setLandmark(curwin,curlist); callback.updateImageWindow(curwin); callback.pushObjectIn3DWindow(curwin); } //------------------------------------------------------------------------------------------------------------------------------------ printf("11. Save segmentation label image to file. \n"); if(!qs_filename_seglabel_output.isEmpty() && p_img8u_seglabel) { V3DLONG sz_seglabelimg[4]={sz_img_input[0],sz_img_input[1],sz_img_input[2],1}; simple_saveimage_wrapper(callback, qPrintable(qs_filename_seglabel_output),p_img8u_seglabel,sz_seglabelimg,1); } //------------------------------------------------------------------------------------------------------------------------------------ //free memory printf(">>Free memory\n"); if(p_img8u_seglabel) {delete []p_img8u_seglabel; p_img8u_seglabel=0;} if(p_strimg) {delete []p_strimg; p_strimg=0;} if(sz_strimg) {delete []sz_strimg; sz_strimg=0;} if(p_img_8u) {delete []p_img_8u; p_img_8u=0;} if(p_img_input && !paras_str.b_imgfromV3D) {delete []p_img_input; p_img_input=0;} //if(sz_img_input) {delete []sz_img_input; sz_img_input=0;} //------------------------------------------------------------------------------------------------------------------------------------ v3d_msg("Program exit successfully!\n", 0); return true; }
//void startVesselTracing ( V3DPluginCallback2 &v3d, QWidget *parent ) void startVesselTracing(V3DPluginCallback2 &v3d,int xflag,int yflag,int zflag,int xbegin, int xend,int xdis,int ybegin,int yend,int ydis,int zbegin,int zend,int zdis,QString swcfile,int slipsize,int pruning_flag,int c) { v3dhandle curwin = v3d.currentImageWindow(); if (!curwin) { v3d_msg("You don't have any image open in the main window."); return; } //ensure the 3d viewer window is open; if not, then open it // v3d.open3DWindow(curwin); // get land mark list LandmarkList seedList = v3d.getLandmark(curwin); Image4DSimple* oldimg = v3d.getImage(curwin); unsigned char* data1d = oldimg->getRawDataAtChannel(c-1); ImagePixelType pixeltype = oldimg->getDatatype(); V3DLONG pagesz = oldimg->getTotalUnitNumberPerChannel(); unsigned char *output_image=0; switch (pixeltype) { case V3D_UINT8: try {output_image = new unsigned char [pagesz];} catch(...) {v3d_msg("cannot allocate memory for output_image."); return;} for(V3DLONG i = 0; i<pagesz; i++) output_image[i] = data1d[i]; break; default: v3d_msg("Invalid data type. Do nothing."); return; } V3DLONG in_sz[4]; in_sz[0] = oldimg->getXDim(); in_sz[1] = oldimg->getYDim(); in_sz[2] = oldimg->getZDim();in_sz[3] = 1; // simple_saveimage_wrapper(v3d, "temp.v3draw", (unsigned char *)output_image, in_sz, pixeltype); MOSTImage img; // set data img.setData( (unsigned char*)output_image, oldimg->getXDim(),oldimg->getYDim(),oldimg->getZDim(),oldimg->getCDim(),oldimg->getDatatype()); if ( seedList.isEmpty() ) { QTime qtime_seed; qtime_seed.start(); //img.auto_detect_seedz(seedList,img.getZDim()/2); if(xflag) { for(int i =xbegin;i<=xend;i+=xdis) img.auto_detect_seedx(seedList,i,InitThreshold,seed_size_all); // img.auto_detect_seedx(seedList,xend); } if(yflag) { for(int i =ybegin;i<=yend;i+=ydis) img.auto_detect_seedy(seedList,i,InitThreshold,seed_size_all); // img.auto_detect_seedy(seedList,yend); } if(zflag) { for(int i =zbegin;i<=zend;i+=zdis) img.auto_detect_seedz(seedList,i,InitThreshold,seed_size_all); //img.auto_detect_seedz(seedList,zend); } qDebug(" cost time seed = %g sec", qtime_seed.elapsed()*0.001); } // clear visited, only excute once static long init_flag = 0; /* if ( init_flag <= 0 ) { visited.fill( false, oldimg->getTotalUnitNumber()); init_flag ++; }*/ for(init_flag = 0;init_flag<oldimg->getTotalUnitNumber();init_flag++) { visited.push_back(false); } // converte the formate NeuronTree vt; QTime qtime; qtime.start(); vt = img.trace_seed_list(seedList, visited,InitThreshold,res_x_all,res_y_all,res_z_all,swcfile,slipsize,pruning_flag); qDebug(" cost time totol= %g sec", qtime.elapsed()*0.001); v3d_msg(QString("Now you can drag and drop the generated swc fle [%1] into Vaa3D.").arg(swcfile),1); // NeuronTree vt_old = v3d.getSWC(curwin); // visualization // v3d.setLandmark(curwin, seedList); // v3d.setSWC(curwin,vt); // v3d.pushObjectIn3DWindow(curwin); // v3d.updateImageWindow(curwin); //img.~MOSTImage(); }
void set_dialog(V3DPluginCallback2 &v3d, QWidget *parent) { int x_begin; int x_end; int x_distance; int y_begin; int y_end; int y_distance; int z_begin; int z_end; int z_distance; int pruning_flag; int c; QString swcfile; int sslip; x_flag = 0; y_flag = 0; z_flag = 0; pruning_flag = 0; v3dhandle curwin = v3d.currentImageWindow(); if (!curwin) { v3d_msg("You don't have any image open in the main window."); return; } Image4DSimple* img = v3d.getImage(curwin); if (!img || !img->valid()) return; AdaTDialog dialog; dialog.endx->setMaximum(img->getXDim()); dialog.endx->setMinimum(1); dialog.endx->setValue(img->getXDim()); dialog.endy->setMaximum(img->getYDim()); dialog.endy->setMinimum(1); dialog.endy->setValue(img->getYDim()); dialog.endz->setMaximum(img->getZDim()); dialog.endz->setMinimum(1); dialog.endz->setValue(img->getZDim()); dialog.ds->setText(QString(img->getFileName()) + "_MOST.swc"); dialog.channel->setMaximum(img->getCDim()); dialog.channel->setMinimum(1);dialog.channel->setValue(1); if (dialog.exec()!=QDialog::Accepted) return; else { InitThreshold = dialog.threshould_value->value(); res_x_all = dialog.resx->value(); res_y_all = dialog.resy->value(); res_z_all = dialog.resz->value(); seed_size_all = dialog.size->value(); sslip = dialog.slipsize->value(); swcfile = dialog.ds->text(); c = dialog.channel->value(); QFile file(swcfile); if (!file.open(QIODevice::WriteOnly|QIODevice::Text)) { v3d_msg("Cannot create the swc file to write, please try it again! "); return; } if(dialog.x_select->isChecked()) { x_flag =1; x_begin = dialog.beginx->value(); x_end = dialog.endx->value(); x_distance = dialog.distancex->value(); } if(dialog.y_select->isChecked()) { y_flag =1; y_begin = dialog.beginy->value(); y_end = dialog.endy->value(); y_distance = dialog.distancey->value(); } if(dialog.z_select->isChecked()) { z_flag =1; z_begin = dialog.beginz->value(); z_end = dialog.endz->value(); z_distance = dialog.distancez->value(); } // v3d.open3DWindow(curwin); if(dialog.pruning->isChecked()) { pruning_flag =1; } startVesselTracing(v3d,x_flag,y_flag,z_flag,x_begin,x_end,x_distance,y_begin,y_end,y_distance,z_begin,z_end,z_distance,swcfile,sslip,pruning_flag,c); } return; }
void reconstruction_func( V3DPluginCallback2 &callback, QWidget *parent, input_PARA &PARA, bool via_gui) { unsigned char *data1d = NULL; V3DLONG N, M, P, sc, c; V3DLONG in_sz[4]; if (via_gui) { 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 // show configure GUI window sigen::interface::Options options; bool retval = getConfig(parent, &options); if (!retval) { return; } // check config // v3d_msg((retval ? QString("OK") : QString("Cancel")), via_gui); // v3d_msg(QString("VT = %1\nDT = %2\nSM = %3\nCL = %4").arg(options.volume_threshold).arg(options.distance_threshold).arg(options.smoothing_level).arg(options.clipping_level), via_gui); // return; sigen::BinaryCube cube = convertToBinaryCube(data1d, /* unit_byte = */ 1, N, M, P, sc, c - 1); std::vector<int> out_n, out_type, out_pn; std::vector<double> out_x, out_y, out_z, out_r; sigen::interface::Extract( cube, out_n, out_type, out_x, out_y, out_z, out_r, out_pn, options); // construct NeuronTree NeuronTree nt; nt.name = "SIGEN"; nt.comment = "SIGEN"; for (int i = 0; i < (int)out_n.size(); ++i) { NeuronSWC pt; pt.n = out_n[i]; pt.type = out_type[i]; pt.x = out_x[i]; pt.y = out_y[i]; pt.z = out_z[i]; pt.r = out_r[i]; pt.pn = out_pn[i]; nt.listNeuron.push_back(pt); } QString swc_name = PARA.inimg_file + "_SIGEN.swc"; writeSWC_file(swc_name.toStdString().c_str(), nt); if (!via_gui) { if (data1d) { delete[] data1d; data1d = NULL; } } v3d_msg(QString("Now you can drag and drop the generated swc fle [%1] into Vaa3D.").arg(swc_name.toStdString().c_str()), via_gui); }
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 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 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 FL_cellseg(V3DPluginCallback2 &callback, QWidget *parent) { v3dhandle curwin = callback.currentImageWindow(); if (!curwin) { v3d_msg("You don't have any image open in the main window."); return; } Image4DSimple* subject = callback.getImage(curwin); QString m_InputFileName = callback.getImageName(curwin); if (!subject) { QMessageBox::information(0, title, QObject::tr("No image is open.")); return; } if (subject->getDatatype()!=V3D_UINT8) { QMessageBox::information(0, title, QObject::tr("This demo program only supports 8-bit data. Your current image data type is not supported.")); return; } V3DLONG sz0 = subject->getXDim(); V3DLONG sz1 = subject->getYDim(); V3DLONG sz2 = subject->getZDim(); V3DLONG sz3 = subject->getCDim(); Image4DProxy<Image4DSimple> pSub(subject); //---------------------------------------------------------------------------------------------------------------------------------- V3DLONG channelsz = sz0*sz1*sz2; float *pLabel = 0; unsigned char *pData = 0; //get the segmentation parameters segParameter segpara; dialog_watershed_para *p_mydlg=0; if (!p_mydlg) p_mydlg = new dialog_watershed_para(&segpara, subject); int res = p_mydlg->exec(); if (res!=QDialog::Accepted) return; else p_mydlg->fetchData(&segpara); if (p_mydlg) {delete p_mydlg; p_mydlg=0;} // now allocate memory and do computation int start_t = clock(); Vol3DSimple <unsigned char> * tmp_inimg = 0; Vol3DSimple <USHORTINT16> * tmp_outimg = 0; try { tmp_inimg = new Vol3DSimple <unsigned char> (sz0, sz1, sz2); tmp_outimg = new Vol3DSimple <USHORTINT16> (sz0, sz1, sz2); } catch (...) { v3d_msg("Unable to allocate memory for processing. Do nothing."); if (tmp_inimg) {delete tmp_inimg; tmp_inimg=0;} if (tmp_outimg) {delete tmp_outimg; tmp_outimg=0;} return; } //do computation memcpy((void *)tmp_inimg->getData1dHandle(), (void *)subject->getRawDataAtChannel(segpara.channelNo), sz0*sz1*sz2); bool b_res = FL_cellseg(tmp_inimg, tmp_outimg, segpara); if (tmp_inimg) {delete tmp_inimg; tmp_inimg=0;} //free the space immediately for better use of memory if (!b_res) { v3d_msg("Fail to do the cell segmentation using FL_cellseg().\n"); } else { V3DLONG new_sz0 = tmp_outimg->sz0(); V3DLONG new_sz1 = tmp_outimg->sz1(); V3DLONG new_sz2 = tmp_outimg->sz2(); V3DLONG new_sz3 = 1; V3DLONG tunits = new_sz0*new_sz1*new_sz2*new_sz3; USHORTINT16 * outvol1d = new USHORTINT16 [tunits]; USHORTINT16 * tmpImg_d1d = (USHORTINT16 *)(tmp_outimg->getData1dHandle()); memcpy((void *)outvol1d, (void *)tmp_outimg->getData1dHandle(), tunits*sizeof(USHORTINT16)); if (tmp_outimg) {delete tmp_outimg; tmp_outimg=0;} //free the space immediately for better use of memory Image4DSimple p4DImage; p4DImage.setData((unsigned char*)outvol1d, sz0, sz1, sz2, 1, V3D_UINT16); v3dhandle newwin = callback.newImageWindow(); callback.setImage(newwin, &p4DImage); callback.setImageName(newwin, QString("Segmented Image")); callback.updateImageWindow(newwin); } //---------------------------------------------------------------------------------------------------------------------------------- int end_t = clock(); printf("time eclapse %d s for labeling objects!\n", (end_t-start_t)/1000000); }
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 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; 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 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 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 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 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; }
int v3dneuron_tracing(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; } v3dhandle curwin = callback.currentImageWindow(); LandmarkList landmarks = callback.getLandmark(curwin); if(landmarks.empty()) { v3d_msg("Please set a landmark!"); return 0; } QList <ImageMarker> imagemarks; for(int i = 0; i < landmarks.size(); i++) { ImageMarker m; LocationSimple l = landmarks.at(i); m.x = l.x; m.y = l.y; m.z = l.z; imagemarks.push_back(m); } system("rm -f /tmp/mymarks.marker"); system("rm -f /tmp/tmp_out*"); writeMarker_file("/tmp/mymarks.marker",imagemarks); QString img_file = callback.getImageName(curwin); bool ok; QString nt_path = QInputDialog::getText(0, QObject::tr("Set path"), QObject::tr("v3dneuron_tracing path : "), QLineEdit::Normal, "~/Local/bin/v3dneuron_tracing", &ok); //QString paras = QObject::tr("v3dneuron_tracing -s %1 -S /tmp/mymarks.marker -o /tmp/tmp_out").arg(img_file); QString paras = QObject::tr("%1 -s \"%2\" -S /tmp/mymarks.marker -o /tmp/tmp_out").arg(nt_path).arg(img_file); qDebug(paras.toStdString().c_str()); //QMessageBox::information(0,"",paras); system(paras.toStdString().c_str()); NeuronTree nt = readSWC_file("/tmp/tmp_out_0.swc"); //nt.editable = false; callback.setSWC(curwin, nt); callback.updateImageWindow(curwin); callback.open3DWindow(curwin); //callback.getView3DControl(curwin)->setShowSurfObjects(2); //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("v3dneuron_tracing")); //callback.updateImageWindow(newwin); return 1; }