/********************************************************************************** * Returns a new, gaussian-noise corrupted image from the given image ***********************************************************************************/ Image4DSimple* CImageUtils::addGaussianNoise( Image4DSimple* im, // input image float w) // gaussian noise weight (1 = only noise, 0 = no noise) throw (tf::RuntimeException) { // checks if(!im || !im->getRawData()) throw tf::RuntimeException("in CImageUtils::addGaussianNoise(): invalid image data"); if(im->getTDim() > 1) throw tf::RuntimeException(tf::strprintf("in CImageUtils::addGaussianNoise(): image has TDim = %d (5D not supported)", im->getTDim())); // allocate new image Image4DSimple* imout = new Image4DSimple(); imout->setXDim(im->getXDim()); imout->setYDim(im->getYDim()); imout->setZDim(im->getZDim()); imout->setCDim(im->getCDim()); imout->setTDim(im->getTDim()); imout->setDatatype(im->getDatatype()); V3DLONG data_size = imout->getTotalBytes(); unsigned char* data = new unsigned char[data_size]; imout->setRawDataPointer(data); // data corruption if(imout->getDatatype() == V3D_UINT8) { unsigned char* data_in = im->getRawData(); for(V3DLONG k=0; k<data_size; k++) data[k] = static_cast<tf::uint8>((1-w)*data_in[k] + w*(rand()%256) +0.5f); } else if(imout->getDatatype() == V3D_UINT16) { unsigned short* data_in = (unsigned short*)(im->getRawData()); for(V3DLONG k=0; k<data_size/2; k++) data[k] = static_cast<tf::uint16>((1-w)*data_in[k] + w*(rand()%65535) +0.5f); } else throw tf::RuntimeException("in CImageUtils::addGaussianNoise(): image is neither UINT8 nor UINT16 (not supported)"); return imout; }
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 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 imfilling(V3DPluginCallback &callback, QWidget *parent) { v3dhandleList win_list = callback.getImageWindowList(); if(win_list.size()<1) { QMessageBox::information(0, title, QObject::tr("No image is open.")); return; } ImFillDialog dialog(callback, parent); if (dialog.exec()!=QDialog::Accepted) return; int start_t = clock(); // record time point dialog.update(); int i1 = dialog.i1; int ch = dialog.ch_rgb; bool mean_thresh = dialog.mean_thresh; int thresh, range; if(mean_thresh) { thresh = dialog.thresh; range = dialog.range; } //qDebug() << " test... " << thresh << range; bool use_marker = true; Image4DSimple* subject = callback.getImage(win_list[i1]); ROIList pRoiList=callback.getROI(win_list[i1]); QString m_InputFileName = callback.getImageName(win_list[i1]); 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; } //also get the landmark from the subject LandmarkList list_landmark_sub=callback.getLandmark(win_list[i1]); if(list_landmark_sub.size()<1) { use_marker = false; } else { QMessageBox msgBox; msgBox.setText("The marker has been choosen."); msgBox.setInformativeText("Do you want to use your first marker as a seed to tell image background?"); msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); msgBox.setDefaultButton(QMessageBox::Ok); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Ok: // Ok was clicked break; case QMessageBox::Cancel: // Cancel was clicked return; break; default: // should never be reached break; } } unsigned char* pSbject = subject->getRawData(); long sz0 = subject->getXDim(); long sz1 = subject->getYDim(); long sz2 = subject->getZDim(); long sz3 = subject->getCDim(); long pagesz_sub = sz0*sz1*sz2; //--------------------------------------------------------------------------------------------------------------------------------------------------- //finding the bounding box of ROI bool vxy=true,vyz=true,vzx=true; // 3 2d-views QRect b_xy = pRoiList.at(0).boundingRect(); QRect b_yz = pRoiList.at(1).boundingRect(); QRect b_zx = pRoiList.at(2).boundingRect(); if(b_xy.left()==-1 || b_xy.top()==-1 || b_xy.right()==-1 || b_xy.bottom()==-1) vxy=false; if(b_yz.left()==-1 || b_yz.top()==-1 || b_yz.right()==-1 || b_yz.bottom()==-1) vyz=false; if(b_zx.left()==-1 || b_zx.top()==-1 || b_zx.right()==-1 || b_zx.bottom()==-1) vzx=false; long bpos_x, bpos_y, bpos_z, bpos_c, epos_x, epos_y, epos_z, epos_c; // 8 cases if(vxy && vyz && vzx) // all 3 2d-views { bpos_x = qBound(long(0), long(qMax(b_xy.left(), b_zx.left())), sz0-1); bpos_y = qBound(long(0), long(qMax(b_xy.top(), b_yz.top())), sz1-1); bpos_z = qBound(long(0), long(qMax(b_yz.left(), b_zx.top())), sz2-1); epos_x = qBound(long(0), long(qMin(b_xy.right(), b_zx.right())), sz0-1); epos_y = qBound(long(0), long(qMin(b_xy.bottom(), b_yz.bottom())), sz1-1); epos_z = qBound(long(0), long(qMin(b_yz.right(), b_zx.bottom())), sz2-1); } else if(!vxy && vyz && vzx) // 2 of 3 { bpos_x = qBound(long(0), long(qMax(0, b_zx.left())), sz0-1); bpos_y = qBound(long(0), long(qMax(0, b_yz.top())), sz1-1); bpos_z = qBound(long(0), long(qMax(b_yz.left(), b_zx.top())), sz2-1); epos_x = qBound(long(0), long(fmin(sz0-1, b_zx.right())), sz0-1); epos_y = qBound(long(0), long(fmin(sz1-1, b_yz.bottom())), sz1-1); epos_z = qBound(long(0), long(qMin(b_yz.right(), b_zx.bottom())), sz2-1); } else if(vxy && !vyz && vzx) { bpos_x = qBound(long(0), long(qMax(b_xy.left(), b_zx.left())), sz0-1); bpos_y = qBound(long(0), long(qMax(b_xy.top(), 0)), sz1-1); bpos_z = qBound(long(0), long(qMax(0, b_zx.top())), sz2-1); epos_x = qBound(long(0), long(qMin(b_xy.right(), b_zx.right())), sz0-1); epos_y = qBound(long(0), long(fmin(b_xy.bottom(), sz1-1)), sz1-1); epos_z = qBound(long(0), long(fmin(sz2-1, b_zx.bottom())), sz2-1); } else if(vxy && vyz && !vzx) { bpos_x = qBound(long(0), long(qMax(b_xy.left(), 0)), sz0-1); bpos_y = qBound(long(0), long(qMax(b_xy.top(), b_yz.top())), sz1-1); bpos_z = qBound(long(0), long(qMax(b_yz.left(), 0)), sz2-1); epos_x = qBound(long(0), long(fmin(b_xy.right(), sz0-1)), sz0-1); epos_y = qBound(long(0), long(qMin(b_xy.bottom(), b_yz.bottom())), sz1-1); epos_z = qBound(long(0), long(fmin(b_yz.right(), sz2-1)), sz2-1); } else if(vxy && !vyz && !vzx) // only 1 of 3 { bpos_x = qBound(long(0), long(qMax(b_xy.left(), 0)), sz0-1); bpos_y = qBound(long(0), long(qMax(b_xy.top(), 0)), sz1-1); bpos_z = 0; epos_x = qBound(long(0), long(fmin(b_xy.right(), sz0-1)), sz0-1); epos_y = qBound(long(0), long(fmin(b_xy.bottom(), sz1-1)), sz1-1); epos_z = sz2-1; } else if(!vxy && vyz && !vzx) { bpos_x = 0; bpos_y = qBound(long(0), long(qMax(0, b_yz.top())), sz1-1); bpos_z = qBound(long(0), long(qMax(b_yz.left(), 0)), sz2-1); epos_x = sz0-1; epos_y = qBound(long(0), long(fmin(sz1-1, b_yz.bottom())), sz1-1); epos_z = qBound(long(0), long(fmin(b_yz.right(), sz2-1)), sz2-1); } else if(!vxy && !vyz && vzx) { bpos_x = qBound(long(0), long(qMax(0, b_zx.left())), sz0-1); bpos_y = 0; bpos_z = qBound(long(0), long(qMax(0, b_zx.top())), sz2-1); epos_x = qBound(long(0), long(fmin(sz0-1, b_zx.right())), sz0-1); epos_y = sz1-1; epos_z = qBound(long(0), long(fmin(sz2-1, b_zx.bottom())), sz2-1); } else // 0 { bpos_x = 0; bpos_y = 0; bpos_z = 0; epos_x = sz0-1; epos_y = sz1-1; epos_z = sz2-1; } //qDebug("x %d y %d z %d x %d y %d z %d ",bpos_x,bpos_y,bpos_z,epos_x,epos_y,epos_z); //ROI extraction long sx = (epos_x-bpos_x)+1; long sy = (epos_y-bpos_y)+1; long sz = (epos_z-bpos_z)+1; long sc = sz3; // 0,1,2 //choose the channel stack long pagesz = sx*sy*sz; double meanv=0; long offset_sub = ch*pagesz_sub; //------------------------------------------------------------------------------------------------------------------------------------ // scans time int i_progress=0; int num_progress = 4; // haw many scanning process // QProgressDialog progress("Filling hole...", "Abort Image Filling", 0, num_progress, parent); progress.setWindowModality(Qt::WindowModal); // first scan progress.setValue(++i_progress); unsigned char *data1d = new unsigned char [pagesz]; if (!data1d) { printf("Fail to allocate memory.\n"); return; } else { for(long k=bpos_z; k<=epos_z; k++) { long offset_z = k*sz0*sz1; long offset_crop_z = (k-bpos_z)*sx*sy; for(long j=bpos_y; j<=epos_y; j++) { long offset_y = j*sz0 + offset_z; long offset_crop_y = (j-bpos_y)*sx + offset_crop_z; for(long i=bpos_x; i<=epos_x; i++) { data1d[(i-bpos_x) + offset_crop_y] = pSbject[offset_sub + i+offset_y]; meanv += data1d[(i-bpos_x) + offset_crop_y]; } } } } meanv /= pagesz; qDebug("mean value %lf", meanv); //---------------------------------------------------------------------------------------------------------------------------------- // preprocess the landmarker int seed_x, seed_y, seed_z; unsigned char seed_val; int range_val=3; if(use_marker) { seed_x = list_landmark_sub[0].x -1; // notice 0-based and 1-based difference seed_y = list_landmark_sub[0].y -1; seed_z = list_landmark_sub[0].z -1; seed_val = pSbject[seed_z*sz0*sz1 + seed_y*sz0 + seed_x + offset_sub]; } else { if(mean_thresh) { seed_val = thresh; range_val = range; qDebug() << "seed value" << seed_val; for(long k=bpos_z; k<=epos_z; k++) { long offset_crop_z = (k-bpos_z)*sx*sy; for(long j=bpos_y; j<=epos_y; j++) { long offset_crop_y = (j-bpos_y)*sx + offset_crop_z; for(long i=bpos_x; i<=epos_x; i++) { if(i==bpos_x || i==epos_x || j==bpos_y || j==epos_y || k==bpos_z || k==epos_z) continue; if(data1d[(i-bpos_x) + offset_crop_y] == seed_val) { seed_x = (i-bpos_x) ; seed_y = (j-bpos_y); seed_z = (k-bpos_z); break; } } } } } else { seed_val = 0; range_val = meanv; qDebug() << "seed value" << seed_val; if(seed_val<0) seed_val = 0; for(long k=bpos_z; k<=epos_z; k++) { long offset_crop_z = (k-bpos_z)*sx*sy; for(long j=bpos_y; j<=epos_y; j++) { long offset_crop_y = (j-bpos_y)*sx + offset_crop_z; for(long i=bpos_x; i<=epos_x; i++) { if(i==bpos_x || i==epos_x || j==bpos_y || j==epos_y || k==bpos_z || k==epos_z) continue; if(data1d[(i-bpos_x) + offset_crop_y] == seed_val) { seed_x = (i-bpos_x) ; seed_y = (j-bpos_y); seed_z = (k-bpos_z); break; } } } } } } qDebug("x %d y %d z %d thresh %d range %d intensity %d", seed_x, seed_y, seed_z, seed_val, range_val, data1d[seed_z*sx*sy + seed_y*sx + seed_x]); //---------------------------------------------------------------------------------------------------------------------------------- // de-alloc //if (pSbject) {delete []pSbject; pSbject=0;} // image visualized in v3d now // second scan progress.setValue(++i_progress); // 3D region growing //---------------------------------------------------------------------------------------------------------------------------------- int end_preprocess = clock(); printf("time eclapse %d s for preprocessing!\n", (end_preprocess-start_t)/1000000); enum states {Known, Alive, FarAway, Trial, BOUNDARY}; long offset_y, offset_z; offset_y=sx; offset_z=sx*sy; long neighborhood_6[6] = {-1, 1, -offset_y, offset_y, -offset_z, offset_z}; long neighborhood_26[26] = {-1, 1, -offset_y, offset_y, -offset_z, offset_z, -offset_y-1, -offset_y+1, -offset_y-offset_z, -offset_y+offset_z, offset_y-1, offset_y+1, offset_y-offset_z, offset_y+offset_z, offset_z-1, offset_z+1, -offset_z-1, -offset_z+1, -1-offset_y-offset_z, -1-offset_y+offset_z, -1+offset_y-offset_z, -1+offset_y+offset_z, 1-offset_y-offset_z, 1-offset_y+offset_z, 1+offset_y-offset_z, 1+offset_y+offset_z}; long neighbors = 26; long bound_idx = (sz-1)*sx*sy + (sy-1)*sx + sx-1; //Fast Marching HeapMinSort heap(pagesz); // initial state heap unsigned char* state = new unsigned char[pagesz]; unsigned char* phi = new unsigned char [pagesz]; bool* inserted = new bool [pagesz]; for(long k = 0; k < sz; k++) { long idxk = k*offset_z; for(long j = 0; j < sy; j++) { long idxj = idxk + j*offset_y; for(long i = 0, idx = idxj; i < sx; i++, idx++) { phi[idx] = 255; state[idx] = BOUNDARY; inserted[idx] = false; if(i==0 || i==sx-1 || j==0 || j==sy-1 || k==0 || k==sz-1) continue; if( i==seed_x && j==seed_y && k==seed_z ) { heap.insert(idx, 0); phi[idx] = 0; state[idx] = Known; inserted[idx] = true; } else state[idx] = FarAway; } } } // // // progress.setValue(++i_progress); long count=1; long wc=0; // del a point from the heap long idx; float weight; while( heap.del(&idx, &weight) ) { if( state[idx] == Alive ) continue; // using region growing critera here if( state[idx] != Known ) { for(int ineighbor=0; ineighbor<neighbors; ineighbor++) { long n_idx = idx + neighborhood_26[ineighbor]; if(n_idx<bound_idx && n_idx>0) { if(phi[n_idx] == 0 && (fabs(data1d[idx] - seed_val)<=range_val)) { phi[idx] = 0; break; } } } } else { phi[idx] = 0; } count--; wc++; //set processed one to state "Alive" state[idx] = Alive; //find new neighbors and added to heap for(int ineighbor=0; ineighbor<neighbors; ineighbor++) { long n_idx = idx + neighborhood_26[ineighbor]; if(n_idx<bound_idx && n_idx>0) { if( (state[n_idx]==FarAway || state[n_idx]==Trial) && inserted[n_idx]==false) { heap.insert(n_idx, phi[n_idx]+wc); count++; state[n_idx] = Trial; inserted[n_idx] = true; } } } } // de-alloc if (inserted) {delete []inserted; inserted=0;} if (state) {delete []state; state=0;} //---------------------------------------------------------------------------------------------------------------------------------- // third scan progress.setValue(++i_progress); int end_rgn = clock(); printf("time eclapse %d s for region growing!\n", (end_rgn-end_preprocess)/1000000); // dist transform //---------------------------------------------------------------------------------------------------------------------------------- long sz_data[4]; sz_data[0]=sx; sz_data[1]=sy; sz_data[2]=sz; sz_data[3]=1; long *pDist = new long [pagesz]; if (!pDist) { printf("Fail to allocate memory.\n"); return; } long *pLabel = new long [pagesz]; if (!pLabel) { printf("Fail to allocate memory.\n"); return; } unsigned char *pData = new unsigned char [2*pagesz]; // first filled and second dist map if (!pData) { printf("Fail to allocate memory.\n"); return; } for(long k = 0; k < sz; k++) { long idxk = k*offset_z; for(long j = 0; j < sy; j++) { long idxj = idxk + j*offset_y; for(long i = 0, idx = idxj; i < sx; i++, idx++) { if(i==0 || i==sx-1 || j==0 || j==sy-1 || k==0 || k==sz-1 || phi[idx]==0) // background and boundary { pData[idx] = 0; pData[idx + pagesz] = 0; } else { pData[idx] = 1; //data1d[idx]; pData[idx + pagesz] = 1; } } } } // de-alloc if (phi) {delete []phi; phi=0;} // dist transform dt3d_binary(pData, pDist, pLabel, sz_data, 1); long maxtest=0, mintest=INF; for(long i=0; i<pagesz; i++) { long tmp=pDist[i]; if(maxtest<tmp) maxtest=tmp; if(mintest>tmp) mintest=tmp; } maxtest -= mintest; if(maxtest) { for(long i=0; i<pagesz; i++) { unsigned char tmp = 255*(pDist[i]-mintest)/maxtest; // image blending long tmp1 = tmp + data1d[i]; pData[i] = (tmp1>255)?255:tmp1; // sum pData[i + pagesz] = tmp; } } // de-alloc if (data1d) {delete []data1d; data1d=0;} // if (pDist) {delete []pDist; pDist=0;} if (pLabel) {delete []pLabel; pLabel=0;} //---------------------------------------------------------------------------------------------------------------------------------- int end_dist = clock(); printf("time eclapse %d s for dist computing!\n", (end_dist-end_rgn)/1000000); progress.setValue(num_progress); Image4DSimple p4DImage; p4DImage.setData((unsigned char*)pData, sx, sy, sz, 2, subject->datatype); v3dhandle newwin = callback.newImageWindow(); callback.setImage(newwin, &p4DImage); callback.setImageName(newwin, QString("filled_image")); callback.updateImageWindow(newwin); }
//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(); }
bool autotrace(const V3DPluginArgList & input, V3DPluginArgList & output,V3DPluginCallback2 &callback) { cout<<"Welcome to MOST tracing"<<endl; unsigned int c=1; int InitThreshold = 20; seed_size_all = 20; int slipsize=20; if (input.size()>=2) { vector<char*> paras = (*(vector<char*> *)(input.at(1).p)); cout<<paras.size()<<endl; if(paras.size() >= 1) c = atoi(paras.at(0)); if(paras.size() >= 2) InitThreshold = atoi(paras.at(1)); if(paras.size() >= 3) seed_size_all = atoi(paras.at(2)); if(paras.size() >= 4) slipsize = atoi(paras.at(3)); } char * inimg_file = ((vector<char*> *)(input.at(0).p))->at(0); cout<<"ch = "<<c<<endl; cout<<"threshold = "<<InitThreshold<<endl; cout<<"inimg_file = "<<inimg_file<<endl; cout<<"seedsize = "<<seed_size_all<<endl; cout<<"slipsize = "<<slipsize<<endl; Image4DSimple *subject = callback.loadImage(inimg_file); if(!subject || !subject->valid()) { v3d_msg("Fail to load the input image.",0); if (subject) {delete subject; subject=0;} return false; } if( c < 1 || c > subject->getCDim()) { v3d_msg("Invalid channel input.",0); if (subject) {delete subject; subject=0;} return false; } V3DLONG N = subject->getXDim(); V3DLONG M = subject->getYDim(); V3DLONG P = subject->getZDim(); V3DLONG pagesz = N*M*P; int datatype = subject->getDatatype(); unsigned char *data1d = subject->getRawDataAtChannel(c-1); unsigned char *output_image=0; switch (datatype) { case V3D_UINT8: try {output_image = new unsigned char [pagesz];} catch(...) {v3d_msg("cannot allocate memory for output_image.",0); return false;} for(V3DLONG i = 0; i<pagesz; i++) output_image[i] = data1d[i]; break; default: v3d_msg("Invalid data type. Do nothing.",0); return false; } MOSTImage img; img.setData( (unsigned char*)output_image, subject->getXDim(),subject->getYDim(),subject->getZDim(),subject->getCDim(),subject->getDatatype()); QString swcfile = QString(inimg_file) + "_MOST.swc"; LandmarkList seedList; QTime qtime_seed; qtime_seed.start(); if(1) { for(int i =1;i<=N;i+=20) img.auto_detect_seedx(seedList,i,InitThreshold,seed_size_all); } if(1) { for(int i =1;i<=M;i+=20) img.auto_detect_seedy(seedList,i,InitThreshold,seed_size_all); } if(1) { for(int i =1;i<=P;i+=20) img.auto_detect_seedz(seedList,i,InitThreshold,seed_size_all); } qDebug(" cost time seed = %g sec", qtime_seed.elapsed()*0.001); static long init_flag = 0; for(init_flag = 0;init_flag<subject->getTotalUnitNumberPerChannel();init_flag++) { visited.push_back(false); } // converte the formate NeuronTree vt; QTime qtime; qtime.start(); vt = img.trace_seed_list(seedList, visited,InitThreshold,1.0,1.0,1.0,swcfile,slipsize,0); qDebug(" cost time totol= %g sec", qtime.elapsed()*0.001); v3d_msg(QString("\nNow you can drag and drop the generated swc fle [%1] into Vaa3D.").arg(swcfile),0); if (subject) {delete subject; subject=0;} return true; }
void 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); }
// show different datatype data in V3D int datatype_converting(V3DPluginCallback2 &callback, QWidget *parent) { v3dhandleList win_list = callback.getImageWindowList(); if(win_list.size()<1) { v3d_msg("No image is open."); return -1; } // DTCDialog dialog(callback,parent); if (dialog.exec()!=QDialog::Accepted) return -1; dialog.update(); V3DLONG isub = dialog.isub; V3DLONG dt = dialog.dt; // ImagePixelType cnvrt_dt; if(dt==0) { cnvrt_dt = V3D_UINT8; } else if(dt==1) { cnvrt_dt = V3D_UINT16; } else if(dt==2) { cnvrt_dt = V3D_FLOAT32; } Image4DSimple* subject = callback.getImage(win_list[isub]); if (!subject) { QMessageBox::information(0, title, QObject::tr("Image does not exist.")); return -1; } unsigned char* subject1d = subject->getRawData(); V3DLONG sx = subject->getXDim(); V3DLONG sy = subject->getYDim(); V3DLONG sz = subject->getZDim(); V3DLONG sc = subject->getCDim(); V3DLONG sz_sub = sx*sy*sz*sc; ImagePixelType sub_dt = subject->getDatatype(); //Converting if(cnvrt_dt == V3D_UINT8) { unsigned char * data1d = NULL; try { data1d = new unsigned char [sz_sub]; } catch(...) { printf("Error allocating memory. \n"); return -1; } // if(sub_dt == V3D_UINT8) { converting<unsigned char, unsigned char>((unsigned char *)subject1d, data1d, sz_sub, cnvrt_dt); } else if(sub_dt == V3D_UINT16) { converting<unsigned short, unsigned char>((unsigned short *)subject1d, data1d, sz_sub, cnvrt_dt); } else if(sub_dt == V3D_FLOAT32) { converting<float, unsigned char>((float *)subject1d, data1d, sz_sub, cnvrt_dt); } //display Image4DSimple p4DImage; p4DImage.setData((unsigned char*)data1d, sx, sy, sz, sc, V3D_UINT8); // v3dhandle newwin = callback.newImageWindow(); callback.setImage(newwin, &p4DImage); callback.setImageName(newwin, "Converted Image"); callback.updateImageWindow(newwin); } else if(cnvrt_dt == V3D_UINT16) { unsigned short * data1d = NULL; try { data1d = new unsigned short [sz_sub]; } catch(...) { printf("Error allocating memory. \n"); return -1; } // if(sub_dt == V3D_UINT8) { converting<unsigned char, unsigned short>((unsigned char *)subject1d, data1d, sz_sub, cnvrt_dt); } else if(sub_dt == V3D_UINT16) { converting<unsigned short, unsigned short>((unsigned short *)subject1d, data1d, sz_sub, cnvrt_dt); } else if(sub_dt == V3D_FLOAT32) { converting<float, unsigned short>((float *)subject1d, data1d, sz_sub, cnvrt_dt); } //display Image4DSimple p4DImage; p4DImage.setData((unsigned char*)data1d, sx, sy, sz, sc, V3D_UINT16); // v3dhandle newwin = callback.newImageWindow(); callback.setImage(newwin, &p4DImage); callback.setImageName(newwin, "Converted Image"); callback.updateImageWindow(newwin); } else if(cnvrt_dt == V3D_FLOAT32) { float * data1d = NULL; try { data1d = new float [sz_sub]; } catch(...) { printf("Error allocating memory. \n"); return -1; } // if(sub_dt == V3D_UINT8) { converting<unsigned char, float>((unsigned char *)subject1d, data1d, sz_sub, cnvrt_dt); } else if(sub_dt == V3D_UINT16) { converting<unsigned short, float>((unsigned short *)subject1d, data1d, sz_sub, cnvrt_dt); } else if(sub_dt == V3D_FLOAT32) { converting<float, float>((float *)subject1d, data1d, sz_sub, cnvrt_dt); } //display Image4DSimple p4DImage; p4DImage.setData((unsigned char*)data1d, sx, sy, sz, sc, V3D_FLOAT32); // v3dhandle newwin = callback.newImageWindow(); callback.setImage(newwin, &p4DImage); callback.setImageName(newwin, "Converted Image"); callback.updateImageWindow(newwin); } else { printf("Currently this program only support UINT8, UINT16, and FLOAT32 data type.\n"); return -1; } // return 0; }
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); }