Exemple #1
0
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));
	}
Exemple #3
0
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 reconstruction_func(V3DPluginCallback2 &callback, QWidget *parent, input_PARA &PARA, bool bmenu)
{
    unsigned char* data1d = 0;
    V3DLONG N,M,P,sc,c;
    V3DLONG in_sz[4];
    if(bmenu)
    {
        v3dhandle curwin = callback.currentImageWindow();
        if (!curwin)
        {
            QMessageBox::information(0, "", "You don't have any image open in the main window.");
            return;
        }

        Image4DSimple* p4DImage = callback.getImage(curwin);

        if (!p4DImage)
        {
            QMessageBox::information(0, "", "The image pointer is invalid. Ensure your data is valid and try again!");
            return;
        }

        if(p4DImage->getDatatype()!=V3D_UINT8)
        {
            QMessageBox::information(0, "", "Please convert the image to be UINT8 and try again!");
            return;
        }
        data1d = p4DImage->getRawData();
        N = p4DImage->getXDim();
        M = p4DImage->getYDim();
        P = p4DImage->getZDim();
        sc = p4DImage->getCDim();

        bool ok1;

        if(sc==1)
        {
            c=1;
            ok1=true;
        }
        else
        {
            c = QInputDialog::getInteger(parent, "Channel",
                                             "Enter channel NO:",
                                             1, 1, sc, 1, &ok1);
        }

        if(!ok1)
            return;

        in_sz[0] = N;
        in_sz[1] = M;
        in_sz[2] = P;
        in_sz[3] = sc;


        PARA.inimg_file = p4DImage->getFileName();
    }
    else
    {
        int datatype = 0;
        if (!simple_loadimage_wrapper(callback,PARA.inimg_file.toStdString().c_str(), data1d, in_sz, datatype))
        {
            fprintf (stderr, "Error happens in reading the subject file [%s]. Exit. \n",PARA.inimg_file.toStdString().c_str());
            return;
        }
        if(PARA.channel < 1 || PARA.channel > in_sz[3])
        {
            fprintf (stderr, "Invalid channel number. \n");
            return;
        }

        if(datatype !=1)
        {
            fprintf (stderr, "Please convert the image to be UINT8 and try again!\n");
            return;
        }
        N = in_sz[0];
        M = in_sz[1];
        P = in_sz[2];
        sc = in_sz[3];
        c = PARA.channel;
    }

    //main neuron reconstruction code

    //// THIS IS WHERE THE DEVELOPERS SHOULD ADD THEIR OWN NEURON TRACING CODE

    V3DLONG pagesz = N*M*P;
    unsigned char *data1d_1ch;
    try {data1d_1ch = new unsigned char [pagesz];}
    catch(...)  {v3d_msg("cannot allocate memory for data1d_1ch."); return;}

    for(V3DLONG i = 0; i < pagesz; i++)
        data1d_1ch[i] = data1d[i+(c-1)*pagesz];

    Image4DSimple * p4dImageNew = 0;
    p4dImageNew = new Image4DSimple;

    if(!p4dImageNew->createImage(N,M,P,1, V3D_UINT8))
        return;

    memcpy(p4dImageNew->getRawData(), data1d_1ch, pagesz);

    unsigned char * indata1d = p4dImageNew->getRawDataAtChannel(0);

    in_sz[3] = 1;
    double dfactor_xy = 1, dfactor_z = 1;

    if (in_sz[0]<=256 && in_sz[2]<=256 && in_sz[2]<=256)
    {
        dfactor_z = dfactor_xy = 1;
    }
    else if (in_sz[0] >= 2*in_sz[2] || in_sz[1] >= 2*in_sz[2])
    {
        if (in_sz[2]<=256)
        {
            double MM = in_sz[0];
            if (MM<in_sz[1]) MM=in_sz[1];
            dfactor_xy = MM / 256.0;
            dfactor_z = 1;
        }
        else
        {
            double MM = in_sz[0];
            if (MM<in_sz[1]) MM=in_sz[1];
            if (MM<in_sz[2]) MM=in_sz[2];
            dfactor_xy = dfactor_z = MM / 256.0;
        }
    }
    else
    {
        double MM = in_sz[0];
        if (MM<in_sz[1]) MM=in_sz[1];
        if (MM<in_sz[2]) MM=in_sz[2];
        dfactor_xy = dfactor_z = MM / 256.0;
    }

    printf("dfactor_xy=%5.3f\n", dfactor_xy);
    printf("dfactor_z=%5.3f\n", dfactor_z);

    if (dfactor_z>1 || dfactor_xy>1)
    {
        v3d_msg("enter ds code", 0);

        V3DLONG out_sz[4];
        unsigned char * outimg=0;
        if (!downsampling_img_xyz( indata1d, in_sz, dfactor_xy, dfactor_z, outimg, out_sz))
            return;

        p4dImageNew->setData(outimg, out_sz[0], out_sz[1], out_sz[2], out_sz[3], V3D_UINT8);

        indata1d = p4dImageNew->getRawDataAtChannel(0);
        in_sz[0] = p4dImageNew->getXDim();
        in_sz[1] = p4dImageNew->getYDim();
        in_sz[2] = p4dImageNew->getZDim();
        in_sz[3] = p4dImageNew->getCDim();
    }

    vector<MyMarker *> outtree;

    cout<<"Start detecting cellbody"<<endl;

    float * phi = 0;
    vector<MyMarker> inmarkers;

    fastmarching_dt_XY(indata1d, phi, in_sz[0], in_sz[1], in_sz[2],2, 10);

    V3DLONG sz0 = in_sz[0];
    V3DLONG sz1 = in_sz[1];
    V3DLONG sz2 = in_sz[2];
    V3DLONG sz01 = sz0 * sz1;
    V3DLONG tol_sz = sz01 * sz2;

    V3DLONG max_loc = 0;
    double max_val = phi[0];
    for(V3DLONG i = 0; i < tol_sz; i++)
    {
        if(phi[i] > max_val)
        {
            max_val = phi[i];
            max_loc = i;
        }
    }
    MyMarker max_marker(max_loc % sz0, max_loc % sz01 / sz0, max_loc / sz01);
    inmarkers.push_back(max_marker);

    cout<<"======================================="<<endl;
    cout<<"Construct the neuron tree"<<endl;

    v3d_msg("8bit", 0);

    fastmarching_tree(inmarkers[0], indata1d, outtree, in_sz[0], in_sz[1], in_sz[2], 2, 10, false);
    cout<<"======================================="<<endl;

    //save a copy of the ini tree
    cout<<"Save the initial unprunned tree"<<endl;
    vector<MyMarker*> & inswc = outtree;

    if (1)
    {
        V3DLONG tmpi;

        vector<MyMarker*> tmpswc;
        for (tmpi=0; tmpi<inswc.size(); tmpi++)
        {
            MyMarker * curp = new MyMarker(*(inswc[tmpi]));
            tmpswc.push_back(curp);

            if (dfactor_xy>1) inswc[tmpi]->x *= dfactor_xy;
            inswc[tmpi]->x += (0);
            if (dfactor_xy>1) inswc[tmpi]->x += dfactor_xy/2;

            if (dfactor_xy>1) inswc[tmpi]->y *= dfactor_xy;
            inswc[tmpi]->y += (0);
            if (dfactor_xy>1) inswc[tmpi]->y += dfactor_xy/2;

            if (dfactor_z>1) inswc[tmpi]->z *= dfactor_z;
            inswc[tmpi]->z += (0);
            if (dfactor_z>1)  inswc[tmpi]->z += dfactor_z/2;
        }

        saveSWC_file(QString(PARA.inimg_file).append("_ini.swc").toStdString(), inswc);

        for (tmpi=0; tmpi<inswc.size(); tmpi++)
        {
            inswc[tmpi]->x = tmpswc[tmpi]->x;
            inswc[tmpi]->y = tmpswc[tmpi]->y;
            inswc[tmpi]->z = tmpswc[tmpi]->z;
        }

        for(tmpi = 0; tmpi < tmpswc.size(); tmpi++)
            delete tmpswc[tmpi];
        tmpswc.clear();
    }

    cout<<"Pruning neuron tree"<<endl;

    vector<MyMarker*> outswc;
    v3d_msg("start to use happ.\n", 0);
    happ(inswc, outswc, indata1d, in_sz[0], in_sz[1], in_sz[2],10, 5, 0.3333);

    if (p4dImageNew) {delete p4dImageNew; p4dImageNew=0;} //free buffe

    inmarkers[0].x *= dfactor_xy;
    inmarkers[0].y *= dfactor_xy;
    inmarkers[0].z *= dfactor_z;


    for(V3DLONG i = 0; i < outswc.size(); i++)
    {
        if (dfactor_xy>1) outswc[i]->x *= dfactor_xy;
        outswc[i]->x += 0;
        if (dfactor_xy>1) outswc[i]->x += dfactor_xy/2;

        if (dfactor_xy>1) outswc[i]->y *= dfactor_xy;
        outswc[i]->y += 0;
        if (dfactor_xy>1) outswc[i]->y += dfactor_xy/2;

        if (dfactor_z>1) outswc[i]->z *= dfactor_z;
        outswc[i]->z += 0;
        if (dfactor_z>1)  outswc[i]->z += dfactor_z/2;

        outswc[i]->radius *= dfactor_xy; //use xy for now
    }

    //re-estimate the radius using the original image
    double real_thres = 40;

    V3DLONG szOriginalData[4] = {N,M,P, 1};

    int method_radius_est = 2;
    for(V3DLONG i = 0; i < outswc.size(); i++)
    {
        //printf(" node %ld of %ld.\n", i, outswc.size());
        outswc[i]->radius = markerRadius(data1d_1ch, szOriginalData, *(outswc[i]), real_thres, method_radius_est);
    }
    //Output

   QString swc_name = PARA.inimg_file + "_APP2_ported.swc";
   // NeuronTree nt;
   // nt.name = "tracing method";
   // writeSWC_file(swc_name.toStdString().c_str(),nt);

    saveSWC_file(swc_name.toStdString(), outswc);


    if(phi){delete [] phi; phi = 0;}
    for(V3DLONG i = 0; i < outtree.size(); i++) delete outtree[i];
    outtree.clear();
    if(data1d_1ch){delete []data1d_1ch; data1d_1ch = 0;}


    if(!bmenu)
    {
        if(data1d) {delete []data1d; data1d = 0;}
    }

    v3d_msg(QString("Now you can drag and drop the generated swc fle [%1] into Vaa3D.").arg(swc_name.toStdString().c_str()),bmenu);

    return;
}
void reconstruction_func(V3DPluginCallback2 &callback, QWidget *parent, input_PARA &PARA, bool bmenu)
{
    unsigned char* data1d = 0;
    V3DLONG N,M,P,sc,c;
    V3DLONG in_sz[4];
    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;
}
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;
}
Exemple #8
0
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 reconstruction_func(V3DPluginCallback2 &callback, QWidget *parent, input_PARA &PARA, bool bmenu)
{
    unsigned char* data1d = 0;
    V3DLONG N,M,P,sc,c;
    V3DLONG in_sz[4];
    if(bmenu)
    {
        v3dhandle curwin = callback.currentImageWindow();
        if (!curwin)
        {
            QMessageBox::information(0, "", "You don't have any image open in the main window.");
            return;
        }

        Image4DSimple* p4DImage = callback.getImage(curwin);

        if (!p4DImage)
        {
            QMessageBox::information(0, "", "The image pointer is invalid. Ensure your data is valid and try again!");
            return;
        }


        data1d = p4DImage->getRawData();
        N = p4DImage->getXDim();
        M = p4DImage->getYDim();
        P = p4DImage->getZDim();
        sc = p4DImage->getCDim();

        bool ok1;

        if(sc==1)
        {
            c=1;
            ok1=true;
        }
        else
        {
            c = QInputDialog::getInteger(parent, "Channel",
                                             "Enter channel NO:",
                                             1, 1, sc, 1, &ok1);
        }

        if(!ok1)
            return;

        in_sz[0] = N;
        in_sz[1] = M;
        in_sz[2] = P;
        in_sz[3] = sc;

        PARA.inimg_file = p4DImage->getFileName();
    }
    else
    {
        int datatype = 0;
        if (!simple_loadimage_wrapper(callback,PARA.inimg_file.toStdString().c_str(), data1d, in_sz, datatype))
        {
            fprintf (stderr, "Error happens in reading the subject file [%s]. Exit. \n",PARA.inimg_file.toStdString().c_str());
            return;
        }
        if(PARA.channel < 1 || PARA.channel > in_sz[3])
        {
            fprintf (stderr, "Invalid channel number. \n");
            return;
        }
        N = in_sz[0];
        M = in_sz[1];
        P = in_sz[2];
        sc = in_sz[3];
        c = PARA.channel;
    }

    //main neuron reconstruction code

    //Stack *data1d_ch1 = C_Stack::make(GREY,(int)N,(int)M,(int)P);
    V3DLONG pagesz = N*M*P;
    V3DLONG offsetc = (c-1)*pagesz;

    size_t voxelNumber = ((size_t) N) * M * P;

    float *im3d = new float[voxelNumber];
    
    size_t voxelOffset = 0;
    float maxI = -FLT_MAX;
    float minI = FLT_MAX;

    for(V3DLONG z = 0; z < P; z++)
    {
         V3DLONG offsetk = z*M*N;
        for(V3DLONG y = 0; y < M; y++)
        {
            V3DLONG offsetj = y*N;
            for(V3DLONG x = 0; x < N; x++)
            {
              voxelOffset = offsetk + offsetj + x;
              float dataval = data1d[offsetc + voxelOffset];
              if (maxI < dataval) {
                maxI = dataval;
              }
              if (minI > dataval) {
                minI = dataval;
              }
              
              im3d[voxelOffset] = dataval;
              
                //double dataval = data1d[offsetc + offsetk + offsetj + x];
                //Set_Stack_Pixel(data1d_ch1,x,y,z,0,dataval);
            }
        }
    }

    //invert to bright field
    for (size_t i = 0; i < voxelNumber; ++i) {
      im3d[i] = (maxI - im3d[i])/(maxI - minI + 1e-10); 
    }
    QString swc_name = PARA.inimg_file + "_neutu_autotrace.swc";

#if defined(_MAC_APPLICATION_)
    std::string paramDir = QApplication::applicationDirPath().toStdString() +       "/../../../../" + NEUTU_PARAM_DIR;
#else
    std::string paramDir = QApplication::applicationDirPath().toStdString();
#endif

    std::string paramFile = paramDir + "/NeuTuAuto.Params.dat";
    std::cout << paramFile << std::endl;

    NeuTuAutoTraceOneStack(im3d, M, N, P, paramFile.c_str(), 
       swc_name.toStdString().c_str());


    delete []im3d;


    /*
    JNeuronTracer tracer;
    ZStack stack;
    stack.load(data1d_ch1,true);

    Stack *stackData = stack.c_stack();
    if (C_Stack::mode(stackData) > C_Stack::min(stackData)) {
      std::cout << "Bright field detected." << std::endl;
      Stack_Invert_Value(stackData);
    } else {
      std::cout << "Dark field detected." << std::endl;
    }

    //tracer.initTraceWorkspace(&stack);
    //tracer.initConnectionTestWorkspace();
    ZSwcTree *tree = tracer.trace(stackData);
    tree->setType(2);

    QString swc_name = PARA.inimg_file + "_neutu_autotrace.swc";
    tree->save(swc_name.toStdString().c_str());
    delete tree;
    */

    if(!bmenu)
    {
        if(data1d) {delete []data1d; data1d = 0;}
    }


    v3d_msg(QString("Now you can drag and drop the generated swc fle [%1] into Vaa3D.").arg(swc_name.toStdString().c_str()),bmenu);

    return;
}
void autotrace(V3DPluginCallback2 &callback, QWidget *parent)
{
    v3dhandle curwin = callback.currentImageWindow();
    if (!curwin)
    {
        QMessageBox::information(0, "", "You don't have any image open in the main window.");
        return;
    }

    Image4DSimple* p4DImage = callback.getImage(curwin);

    if (!p4DImage)
    {
        QMessageBox::information(0, "", "The image pointer is invalid. Ensure your data is valid and try again!");
        return;
    }

    //Mc_Stack *stack = NVInterface::makeStack(p4DImage);

    unsigned char* data1d = p4DImage->getRawData();
    V3DLONG N = p4DImage->getXDim();
    V3DLONG M = p4DImage->getYDim();
    V3DLONG P = p4DImage->getZDim();
    V3DLONG sc = p4DImage->getCDim();

    int in_sz[3];
    in_sz[0] = N;
    in_sz[1] = M;
    in_sz[2] = P;


    bool ok1;
    int c;

    if(sc==1)
    {
        c=1;
        ok1=true;
    }
    else
    {
        c = QInputDialog::getInteger(parent, "Channel",
                                         "Enter channel NO:",
                                         1, 1, sc, 1, &ok1);
    }

    if(!ok1)
        return;

    IM = new ImageOperation;
    Tracer = new OpenSnakeTracer;

   // IM->ImRead(callback.getImageName(curwin).toStdString().c_str());
    IM->Imcreate(data1d,in_sz);

    //preprocessing
    std::cout<<"Compute Gradient Vector Flow..."<<std::endl;
    IM->computeGVF(1000,5,0);
    std::cout<<"Compute Vesselness (CPU)..."<<std::endl;
    IM->ComputeGVFVesselness();
    std::cout<<"Detect Seed Points..."<<std::endl;
    IM->SeedDetection(IM->v_threshold,0,0);
    std::cout<<"Adjust Seed Points..."<<std::endl;
    IM->SeedAdjustment(10);
    std::cout<<"Preprocessing Finished..."<<std::endl;

    IM->ImComputeInitBackgroundModel(IM->v_threshold);
    IM->ImComputeInitForegroundModel();

    //tracing
    std::cout<<"--------------Tracing--------------"<<std::endl;
    IM->ImRefresh_LabelImage();
    Tracer->SetImage(IM);
    Tracer->use_multi_threads = true;
    Tracer->Init();
    Tracer->tracing_thread->stopped = false;


    float alpha = 0;
    int iter_num = 50;
    int ITER = 5;

    int pt_distance = 2;

    float beta = 0.05;
    float kappa = 1;
    float gamma = 1;
    float stretchingRatio = 3;

    int collision_dist = 1;
    int minimum_length = 5;
    bool automatic_merging = true;
    int max_angle = 99;
    bool freeze_body = true;
    int s_force = 1;
    int tracing_model = 0;
    int coding_method = 0;
    float sigma_ratio = 1;
    int border = 0;
    Tracer->setParas(pt_distance,gamma,stretchingRatio,minimum_length,collision_dist,5,5,automatic_merging,max_angle,
                     freeze_body,s_force,tracing_model,false,coding_method,sigma_ratio,border);
    IM->SetCodingMethod(0);

    Tracer->Open_Curve_Snake_Tracing();
    Tracer->RemoveSeeds();
            //tracing finished
    while( IM->SeedPt.GetSize() != IM->visit_label.sum() )
    {
       Tracer->Open_Curve_Snake_Tracing();
       Tracer->RemoveSeeds();
    }

    std::cout<<std::endl;
    std::cout<<"--------------Processing Finished--------------"<<std::endl;

    QString fileName = callback.getImageName(curwin) + "_snake.swc";
    QFile swc_file(fileName);

    PointList3D wrote_pt, All_Pt;
    if (swc_file.open(QFile::WriteOnly | QFile::Truncate))
    {
        QTextStream *out_txt;
        out_txt = new QTextStream(&swc_file);

        vnl_vector<int> *snake_visit_label;
        snake_visit_label = new vnl_vector<int>(Tracer->SnakeList.NSnakes);
        snake_visit_label->fill(0);
        int *point_id;
        point_id = new int[1];
        point_id[0] = 1;


        All_Pt.RemoveAllPts();

        std::vector<int> *branch_label;
        branch_label = new std::vector<int>[1];

        for( int i = 0; i < Tracer->SnakeList.NSnakes; i++ )
        {
            if( snake_visit_label[0](i) == 1 )
                continue;
            if( Tracer->SnakeList.valid_list[i] == 0 )
                continue;

            wrote_pt.RemoveAllPts();
            int snake_id = i;
            findBranch_Raw( snake_id, -1, Tracer->SnakeList.Snakes[i].Cu.GetFirstPt(), snake_visit_label, point_id, out_txt, &wrote_pt, &All_Pt, branch_label );

        }
    }

    v3d_msg(QString("Now you can drag and drop the generated swc fle [%1] into Vaa3D.").arg(fileName));
    return;

}
void reconstruction_func(V3DPluginCallback2 &callback, 
                         QWidget *parent, 
                         input_PARA &PARA, 
                         bool bmenu)
{
    cout<<"Welcome to NeuroStalker!!"<<endl;
    unsigned char* data1d = 0;
    V3DLONG N,M,P,sc,c;
    V3DLONG in_sz[4];
    Image4DSimple* p4DImage;

    if(bmenu)
    {
        v3dhandle curwin = callback.currentImageWindow();
        if (!curwin)
        {
            QMessageBox::information(0, "", "You don't have any image open in the main window.");
            return;
        }

        p4DImage = callback.getImage(curwin);

        if (!p4DImage)
        {
            QMessageBox::information(0, "", "The image pointer is invalid. Ensure your data is valid and try again!");
            return;
        }


        data1d = p4DImage->getRawData();
        N = p4DImage->getXDim();
        M = p4DImage->getYDim();
        P = p4DImage->getZDim();
        sc = p4DImage->getCDim();

        bool ok1;

        if(sc==1)
        {
            c=1;
            ok1=true;
        }
        else
        {
            c = QInputDialog::getInteger(parent, "Channel",
                                             "Enter channel NO:",
                                             1, 1, sc, 1, &ok1);
        }

        if(!ok1)
            return;

        in_sz[0] = N;
        in_sz[1] = M;
        in_sz[2] = P;
        in_sz[3] = sc;


        PARA.inimg_file = p4DImage->getFileName();
    }
    else
    {
        int datatype = 0;
        if (!simple_loadimage_wrapper(callback,PARA.inimg_file.toStdString().c_str(), data1d, in_sz, datatype))
        {
            fprintf (stderr, "Error happens in reading the subject file [%s]. Exit. \n",PARA.inimg_file.toStdString().c_str());
            return;
        }
        if(PARA.channel < 1 || PARA.channel > in_sz[3])
        {
            fprintf (stderr, "Invalid channel number. \n");
            return;
        }
        N = in_sz[0];
        M = in_sz[1];
        P = in_sz[2];
        sc = in_sz[3];
        c = PARA.channel;
    }

    if (PARA.unittest & 2)
    {
        cout<<"+++++ Running Unit-Tests +++++"<<endl;
        //TestRadius(data1d, in_sz);
    }

    // ------- Main neuron reconstruction code


    // Crop The image
    vectype boxlowsize;
    if (PARA.preprocessing & 1)
    {
        cout<<"=============== Cropping the image ==============="<<endl;
        V3DLONG sz_img_crop[4];
        unsigned char *p_img8u_crop = crop(in_sz, data1d, sz_img_crop, &boxlowsize, PARA.threshold);
        cout<<"boxlowsize: "<<boxlowsize[0]<<"boxlowsize: "<<boxlowsize[1]<<"boxlowsize: "<<boxlowsize[2]<<endl;    
        //cout<<"Saving cropped image to downsample.v3draw"<<endl;
        //saveImage("test/cropoutside.v3draw", p_img8u_crop, sz_img_crop, V3D_UINT8);
        if(!bmenu)
        {
            if (data1d) delete [] data1d;
        }
        data1d = p_img8u_crop;

        for (int i=0; i<4; i++){
            in_sz[i] = sz_img_crop[i];
        }
        //cout<<"boxlowsize: "<<boxlowsize[0]<<"boxlowsize: "<<boxlowsize[1]<<"boxlowsize: "<<boxlowsize[2]<<endl;    

        cout<<"=============== Image Cropped ==============="<<endl;
    }
       // Imcreate takes in_sz with int*

    // Downsample the image
    if (PARA.preprocessing & 2)
    {
        cout<<"=============== Downsampling the image..."<<endl;
        V3DLONG downsz[4];
        cout<<"Data size before downsample: "<<in_sz[0]<<","<<in_sz[1]<<","<<in_sz[2]<<endl;

        unsigned char* downdata1d = downsample(in_sz, c, data1d, downsz);
        data1d = downdata1d;
        in_sz[0] = downsz[0];
        in_sz[1] = downsz[1];
        in_sz[2] = downsz[2];
        in_sz[3] = downsz[3];
        cout<<"Data size after downsample: "<<in_sz[0]<<","<<in_sz[1]<<","<<in_sz[2]<<endl;
        //cout<<"Saving downsampled image to test/downsample.v3draw"<<endl;
        //saveImage("test/downsample.v3draw", downdata1d, downsz, V3D_UINT8);
        cout<<"=============== Image Downsampled..."<<endl;
    }



    // Using the Image Operation found in vaa3d_tools/hackathon/zhi/snake_tracing/TracingCore/ in for some simple Image Processing
    IM = new ImageOperation;

    // Imcreate takes in_sz with int*
    int in_sz_int[4];

    for(int i = 0; i < 4; i++)
    {
        in_sz_int[i] = (int)in_sz[i];
    }
    
    // Preprocessing
    IM->Imcreate(data1d, in_sz_int);
    std::cout<<"=== Compute Gradient Vector Flow..."<<std::endl;
    IM->computeGVF(1000, 5, 1);
    std::cout<<"=== Compute Vesselness (CPU)..."<<std::endl;
    IM->ComputeGVFVesselness();
    std::cout<<"=== Detect Seed Points..."<<std::endl;
    IM->SeedDetection(IM->v_threshold, 0, 0);
    std::cout<<"=== Adjust Seed Points..."<<std::endl;
    IM->SeedAdjustment(10);
    std::cout<<"=== Preprocessing Finished..."<<std::endl;
    
    //----------------------------vesselness begin
/*    V3DLONG l_npixels_vessel;
    l_npixels_vessel = in_sz_int[0] * in_sz_int[1] * in_sz_int[2];
    cout<<"l_npixels_vessel"<<l_npixels_vessel<<endl;
    GradientImageType::IndexType index;*/

    float vp;
/*    for (int i = 0; i < 10; ++i)
    {
        index[0] = 66 + i;
        index[1] = 208 + i;
        index[2] = 48 + i;
        vp = (float) (IM->IVessel)->GetPixel(index);
        cout<<"vp output: "<<vp<<endl;
    }*/
    const int testthreshold = IM->v_threshold;
    cout<<"testthreshold: "<<testthreshold<<endl;
/*    unsigned char *p_vessel = new(std::nothrow) unsigned char[l_npixels_vessel]();
    unsigned char * vp_tmp = p_vessel;
    for(V3DLONG Z = 0;Z < in_sz[2]; Z++)
        for(V3DLONG Y = 0;Y < in_sz[1]; Y++)
            for(V3DLONG X = 0;X < in_sz[0]; X++)
            {
                //cout<<"continue";
                index[0] = X;
                index[1] = Y;
                index[2] = Z;
                vp = (float) (IM->IVessel)->GetPixel(index);
                *vp_tmp = vp;
                vp_tmp++;
            }

    saveImage("test/Vesselness.v3draw", p_vessel, in_sz, V3D_UINT8);*/
    //---------------------------vesselness end

    // Adaptive thresholding here, may replace with graph cut
    //IM->ImComputeInitBackgroundModel(IM->v_threshold);
    //IM->ImComputeInitForegroundModel();

    // Get the Binary Image
    //replace simple threshold by adaptive thresholding
    //LabelImagePointer binaryimg = DeriveForegroundLabelImage(IM->I, ForegroundThreshold);
    LabelImagePointer binaryimg = DeriveForegroundLabelImage(IM->I, (int) PARA.threshold);

    // Save the binary img to visualise the segmentation
    unsigned short int * binaryimgbuffer =  binaryimg->GetBufferPointer();
    unsigned char * binaryimg2uchar = new unsigned char [in_sz[0]*in_sz[1]*in_sz[2]];
    for (int i = 0; i < in_sz[0]*in_sz[1]*in_sz[2]; i++)
    {
        binaryimg2uchar[i] = (unsigned char) ((double)(binaryimgbuffer[i]) * 255.0);
    }
    //saveImage("test/binaryimage.v3draw", binaryimg2uchar, in_sz, V3D_UINT8);

    vectype xpfinal, ypfinal, zpfinal, rfinal, pn, sn;

    // ------- Run Unit-Tests
    if (PARA.unittest & 2){
        cout<<"+++++ Running Unit-Tests +++++"<<endl;
        TestMatMath();
        TestPressureSampler(IM->I, IM->IGVF, binaryimg, IM->SeedPt, &xpfinal, &ypfinal, &zpfinal, &pn,  &rfinal, &sn);
        cout<<"All Tests Finished!!!!!!! G'Day!!"<<endl;
    }

    if (PARA.unittest & 1) 
    {
        //PressureSampler p(100, 100, IM->I, IM->IGVF, 10);
        TraceReal(IM->I, IM->IGVF, binaryimg, IM->SeedPt, &xpfinal, &ypfinal, &zpfinal, &pn,  &rfinal, &sn, PARA.step, PARA.stepsize);
    }
    cout<<"pn size: "<<pn.size()<<" xpoint size: "<<xpfinal.size()<<" ypoint size: "
            <<ypfinal.size()<<" zpoint size: "<<zpfinal.size()<<" rpoint size: "<<rfinal.size()<<endl; 
    //Output
    NeuronTree nt;
    QList <NeuronSWC> listNeuron;
    QHash <int, int> hashNeuron;
    listNeuron.clear();
    hashNeuron.clear();
    NeuronSWC S;
    for (int i = 0; i < ypfinal.size(); i++)
    {
        S.n = sn[i];
        S.type = 7;
        S.x = xpfinal[i] + boxlowsize[0];
        S.y = ypfinal[i] + boxlowsize[1];
        S.z = zpfinal[i] + boxlowsize[2];
        S.r = rfinal[i];
        S.pn = pn[i];
        listNeuron.append(S);
        hashNeuron.insert(S.n, listNeuron.size() - 1);       
    }
    nt.n = -1;
    nt.on = true;
    nt.listNeuron = listNeuron;
    nt.hashNeuron = hashNeuron;

    QString swc_name = PARA.inimg_file + "_NeuroStalker.swc";
    nt.name = "NeuroStalker";
    writeSWC_file(swc_name.toStdString().c_str(), nt);

    if(!bmenu)
    {
        if(data1d) {delete [] data1d; data1d = 0;}
    }

    v3d_msg(QString("Now you can drag and drop the generated swc fle [%1] into Vaa3D.").arg(swc_name.toStdString().c_str()),bmenu);

    return;
}
void 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 &paras_str, CParas &paras_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;

}
Exemple #17
0
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);
}
Exemple #18
0
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 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 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);
}
Exemple #23
0
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;
}
Exemple #24
0
// 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 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;
}
Exemple #26
0
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"));
    }
}