Exemplo n.º 1
0
bool loadIndexedStackFFMpeg( QByteArray* buffer, Image4DSimple& img, int channel, int num_channels,
                             long width, long height )
{
    try
    {
        FFMpegVideo video( buffer );
        if ( ! video.isOpen )
            return false;
        int sx = video.getWidth();
        int sy = video.getHeight();
        int sz = video.getNumberOfFrames();
        int sc = video.getNumberOfChannels();
        // cout << "Number of frames = " << sz << endl;

        if ( channel == 0 )
            img.createBlankImage( width, height, sz, num_channels, 1 ); // 1 byte = 8 bits per value

        Image4DProxy<Image4DSimple> proxy( &img );

        int frameCount = 0;
        for ( int z = 0; z < sz; ++z )
        {
            video.fetchFrame( z );
            // int z = frameCount;
            frameCount++;
            for ( int y = 0; y < height; ++y )
            {
                for ( int x = 0; x < width; ++x )
                {
                    proxy.put_at( x, y, z, channel,
                                  video.getPixelIntensity( x, y, ( FFMpegVideo::Channel )0 )
                                );
                }
            }
        }
        cout << "Number of frames found = " << frameCount << endl;

        return true;

    }
    catch ( ... ) {}

    return false;
}
Exemplo n.º 2
0
bool loadStackFFMpegAsGray( QUrl url, Image4DSimple& img )
{
    try
    {
        FFMpegVideo video( url );
        int sx = video.getWidth();
        int sy = video.getHeight();
        int sz = video.getNumberOfFrames();
        int sc = video.getNumberOfChannels();
        // cout << "Number of frames = " << sz << endl;

        img.createBlankImage( sx, sy, sz, 1, 1 ); // 1 byte = 8 bits per value
        Image4DProxy<Image4DSimple> proxy( &img );

        int frameCount = 0;
        for ( int z = 0; z < sz; ++z )
        {
            video.fetchFrame( z );
            // int z = frameCount;
            frameCount++;
            for ( int y = 0; y < sy; ++y )
            {
                for ( int x = 0; x < sx; ++x )
                {
                    // Use average of R,G,B as gray value
                    int val = 0;
                    for ( int c = 0; c < sc; ++c )
                    {
                        val += video.getPixelIntensity( x, y, ( FFMpegVideo::Channel )c );
                    }
                    val /= sc; // average of rgb
                    proxy.put_at( x, y, z, 0, val );
                }
            }
        }
        // cout << "Number of frames found = " << frameCount << endl;

        return true;

    }
    catch ( ... ) {}

    return false;
}
Exemplo n.º 3
0
bool loadStackFFMpeg( QUrl url, Image4DSimple& img )
{
    try
    {
        FFMpegVideo video( url );
        if ( ! video.isOpen )
            return false;
        int sx = video.getWidth();
        int sy = video.getHeight();
        int sz = video.getNumberOfFrames();
        int sc = video.getNumberOfChannels();
        // cout << "Number of frames = " << sz << endl;

        img.createBlankImage( sx, sy, sz, sc, 1 ); // 1 byte = 8 bits per value
        Image4DProxy<Image4DSimple> proxy( &img );

        int frameCount = 0;
        for ( int z = 0; z < sz; ++z )
        {
            video.fetchFrame( z );
            // int z = frameCount;
            frameCount++;
            for ( int c = 0; c < sc; ++c )
            {
                for ( int y = 0; y < sy; ++y )
                {
                    for ( int x = 0; x < sx; ++x )
                    {
                        proxy.put_at( x, y, z, c,
                                      video.getPixelIntensity( x, y, ( FFMpegVideo::Channel )c )
                                    );
                    }
                }
            }
        }
        cout << "Number of frames found = " << frameCount << endl;

        return true;

    }
    catch ( ... ) {}

    return false;
}
Exemplo n.º 4
0
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)"));
	}
}
Exemplo n.º 5
0
void imfilling(V3DPluginCallback &callback, QWidget *parent)
{
    v3dhandleList win_list = callback.getImageWindowList();
	
	if(win_list.size()<1) 
	{
		QMessageBox::information(0, title, QObject::tr("No image is open."));
		return;
	}
	
	ImFillDialog dialog(callback, parent);
	if (dialog.exec()!=QDialog::Accepted)
		return;
	
	int start_t = clock(); // record time point
	
	dialog.update();
	
	int i1 = dialog.i1;
	int ch = dialog.ch_rgb; 
	bool mean_thresh = dialog.mean_thresh;
	
	int thresh, range;
	
	if(mean_thresh)
	{
		thresh = dialog.thresh;
		range = dialog.range;
	}
	
	//qDebug() << " test... " << thresh << range;
	
	bool use_marker = true;
	
	Image4DSimple* subject = callback.getImage(win_list[i1]);
	ROIList pRoiList=callback.getROI(win_list[i1]);
	
	QString m_InputFileName = callback.getImageName(win_list[i1]);
	
	if (!subject)
	{
		QMessageBox::information(0, title, QObject::tr("No image is open."));
		return;
	}
	if (subject->getDatatype()!=V3D_UINT8)
	{
		QMessageBox::information(0, title, QObject::tr("This demo program only supports 8-bit data. Your current image data type is not supported."));
		return;
	}
	
	
	//also get the landmark from the subject
	LandmarkList list_landmark_sub=callback.getLandmark(win_list[i1]);
	if(list_landmark_sub.size()<1)
	{
		use_marker = false;
	}
	else
	{
		QMessageBox msgBox;
		msgBox.setText("The marker has been choosen.");
		msgBox.setInformativeText("Do you want to use your first marker as a seed to tell image background?");
		msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
		msgBox.setDefaultButton(QMessageBox::Ok);
		int ret = msgBox.exec();
		
		switch (ret) {
			case QMessageBox::Ok:
				// Ok was clicked
				break;

			case QMessageBox::Cancel:
				// Cancel was clicked
				return;
				break;
			default:
				// should never be reached
				break;
		}
	}

	
    unsigned char* pSbject = subject->getRawData();
	
	long sz0 = subject->getXDim();
    long sz1 = subject->getYDim();
    long sz2 = subject->getZDim();
	long sz3 = subject->getCDim();
	
	long pagesz_sub = sz0*sz1*sz2;
	
	//---------------------------------------------------------------------------------------------------------------------------------------------------
	//finding the bounding box of ROI
	bool vxy=true,vyz=true,vzx=true; // 3 2d-views
	
	QRect b_xy = pRoiList.at(0).boundingRect();
	QRect b_yz = pRoiList.at(1).boundingRect();
	QRect b_zx = pRoiList.at(2).boundingRect();
	
	if(b_xy.left()==-1 || b_xy.top()==-1 || b_xy.right()==-1 || b_xy.bottom()==-1)
		vxy=false;
	if(b_yz.left()==-1 || b_yz.top()==-1 || b_yz.right()==-1 || b_yz.bottom()==-1)
		vyz=false;
	if(b_zx.left()==-1 || b_zx.top()==-1 || b_zx.right()==-1 || b_zx.bottom()==-1)
		vzx=false;
		
	long bpos_x, bpos_y, bpos_z, bpos_c, epos_x, epos_y, epos_z, epos_c;
	
	// 8 cases
	if(vxy && vyz && vzx) // all 3 2d-views
	{
		bpos_x = qBound(long(0), long(qMax(b_xy.left(), b_zx.left())), sz0-1);
		bpos_y = qBound(long(0), long(qMax(b_xy.top(),  b_yz.top())), sz1-1);
		bpos_z = qBound(long(0), long(qMax(b_yz.left(), b_zx.top())), sz2-1);
		
		epos_x = qBound(long(0), long(qMin(b_xy.right(), b_zx.right())), sz0-1);
		epos_y = qBound(long(0), long(qMin(b_xy.bottom(), b_yz.bottom())), sz1-1);
		epos_z = qBound(long(0), long(qMin(b_yz.right(), b_zx.bottom())), sz2-1);
	}
	else if(!vxy && vyz && vzx) // 2 of 3
	{
		bpos_x = qBound(long(0), long(qMax(0, b_zx.left())), sz0-1);
		bpos_y = qBound(long(0), long(qMax(0,  b_yz.top())), sz1-1);
		bpos_z = qBound(long(0), long(qMax(b_yz.left(), b_zx.top())), sz2-1);
		
		epos_x = qBound(long(0), long(fmin(sz0-1, b_zx.right())), sz0-1);
		epos_y = qBound(long(0), long(fmin(sz1-1, b_yz.bottom())), sz1-1);
		epos_z = qBound(long(0), long(qMin(b_yz.right(), b_zx.bottom())), sz2-1);
	}
	else if(vxy && !vyz && vzx)
	{
		bpos_x = qBound(long(0), long(qMax(b_xy.left(), b_zx.left())), sz0-1);
		bpos_y = qBound(long(0), long(qMax(b_xy.top(),  0)), sz1-1);
		bpos_z = qBound(long(0), long(qMax(0, b_zx.top())), sz2-1);
		
		epos_x = qBound(long(0), long(qMin(b_xy.right(), b_zx.right())), sz0-1);
		epos_y = qBound(long(0), long(fmin(b_xy.bottom(), sz1-1)), sz1-1);
		epos_z = qBound(long(0), long(fmin(sz2-1, b_zx.bottom())), sz2-1);
	}
	else if(vxy && vyz && !vzx)
	{
		bpos_x = qBound(long(0), long(qMax(b_xy.left(), 0)), sz0-1);
		bpos_y = qBound(long(0), long(qMax(b_xy.top(),  b_yz.top())), sz1-1);
		bpos_z = qBound(long(0), long(qMax(b_yz.left(), 0)), sz2-1);
		
		epos_x = qBound(long(0), long(fmin(b_xy.right(), sz0-1)), sz0-1);
		epos_y = qBound(long(0), long(qMin(b_xy.bottom(), b_yz.bottom())), sz1-1);
		epos_z = qBound(long(0), long(fmin(b_yz.right(), sz2-1)), sz2-1);
	}
	else if(vxy && !vyz && !vzx) // only 1 of 3
	{
		bpos_x = qBound(long(0), long(qMax(b_xy.left(), 0)), sz0-1);
		bpos_y = qBound(long(0), long(qMax(b_xy.top(),  0)), sz1-1);
		bpos_z = 0;
		
		epos_x = qBound(long(0), long(fmin(b_xy.right(), sz0-1)), sz0-1);
		epos_y = qBound(long(0), long(fmin(b_xy.bottom(), sz1-1)), sz1-1);
		epos_z = sz2-1;
	}
	else if(!vxy && vyz && !vzx)
	{
		bpos_x = 0;
		bpos_y = qBound(long(0), long(qMax(0,  b_yz.top())), sz1-1);
		bpos_z = qBound(long(0), long(qMax(b_yz.left(), 0)), sz2-1);
		
		epos_x = sz0-1;
		epos_y = qBound(long(0), long(fmin(sz1-1, b_yz.bottom())), sz1-1);
		epos_z = qBound(long(0), long(fmin(b_yz.right(), sz2-1)), sz2-1);
	}
	else if(!vxy && !vyz && vzx)
	{
		bpos_x = qBound(long(0), long(qMax(0, b_zx.left())), sz0-1);
		bpos_y = 0;
		bpos_z = qBound(long(0), long(qMax(0, b_zx.top())), sz2-1);
		
		epos_x = qBound(long(0), long(fmin(sz0-1, b_zx.right())), sz0-1);
		epos_y = sz1-1;
		epos_z = qBound(long(0), long(fmin(sz2-1, b_zx.bottom())), sz2-1);
	}
	else // 0
	{
		bpos_x = 0;
		bpos_y = 0;
		bpos_z = 0;
		
		epos_x = sz0-1;
		epos_y = sz1-1;
		epos_z = sz2-1;
	}

	//qDebug("x %d y %d z %d x %d y %d z %d ",bpos_x,bpos_y,bpos_z,epos_x,epos_y,epos_z);

	//ROI extraction
	long sx = (epos_x-bpos_x)+1;
    long sy = (epos_y-bpos_y)+1;
    long sz = (epos_z-bpos_z)+1;
	long sc = sz3; // 0,1,2
	
	//choose the channel stack
	long pagesz = sx*sy*sz;
	
	double meanv=0;
	
	long offset_sub = ch*pagesz_sub;
	
	//------------------------------------------------------------------------------------------------------------------------------------
	// scans time
	int i_progress=0;
	int num_progress = 4; // haw many scanning process
	
	//
	QProgressDialog progress("Filling hole...", "Abort Image Filling", 0, num_progress, parent);
	progress.setWindowModality(Qt::WindowModal);
	
	// first scan
	progress.setValue(++i_progress); 
	
	unsigned char *data1d = new unsigned char [pagesz];
	if (!data1d) 
	{
		printf("Fail to allocate memory.\n");
		return;
	}
	else
	{
		for(long k=bpos_z; k<=epos_z; k++)
		{
			long offset_z = k*sz0*sz1;
			long offset_crop_z = (k-bpos_z)*sx*sy;
			for(long j=bpos_y; j<=epos_y; j++)
			{
				long offset_y = j*sz0 + offset_z;
				long offset_crop_y = (j-bpos_y)*sx + offset_crop_z;
				for(long i=bpos_x; i<=epos_x; i++)
				{
					data1d[(i-bpos_x) + offset_crop_y] = pSbject[offset_sub + i+offset_y];
					
					meanv += data1d[(i-bpos_x) + offset_crop_y];
				}
			}
		}
	}
	meanv /= pagesz;
	
	qDebug("mean value %lf", meanv);

	//----------------------------------------------------------------------------------------------------------------------------------
	// preprocess the landmarker
	int seed_x, seed_y, seed_z;
	unsigned char seed_val;
	int range_val=3;
	
	if(use_marker)
	{
		seed_x = list_landmark_sub[0].x -1; // notice 0-based and 1-based difference
		seed_y = list_landmark_sub[0].y -1;
		seed_z = list_landmark_sub[0].z -1;
		
		seed_val = pSbject[seed_z*sz0*sz1 + seed_y*sz0 + seed_x + offset_sub];
	
	}
	else
	{
		if(mean_thresh)
		{
			seed_val = thresh;
			range_val = range;
			
			qDebug() << "seed value" << seed_val;
			
			for(long k=bpos_z; k<=epos_z; k++)
			{
				long offset_crop_z = (k-bpos_z)*sx*sy;
				for(long j=bpos_y; j<=epos_y; j++)
				{
					long offset_crop_y = (j-bpos_y)*sx + offset_crop_z;
					for(long i=bpos_x; i<=epos_x; i++)
					{
						
						if(i==bpos_x || i==epos_x || j==bpos_y || j==epos_y || k==bpos_z || k==epos_z)
							continue;
						
						if(data1d[(i-bpos_x) + offset_crop_y] == seed_val)
						{
							seed_x = (i-bpos_x) ; seed_y = (j-bpos_y); seed_z = (k-bpos_z);
							break;
						}
					}
				}
			}
			
			
		}
		else
		{
			seed_val = 0;
			range_val = meanv;
			
			qDebug() << "seed value" << seed_val;
			
			if(seed_val<0) seed_val = 0;
			
			for(long k=bpos_z; k<=epos_z; k++)
			{
				long offset_crop_z = (k-bpos_z)*sx*sy;
				for(long j=bpos_y; j<=epos_y; j++)
				{
					long offset_crop_y = (j-bpos_y)*sx + offset_crop_z;
					for(long i=bpos_x; i<=epos_x; i++)
					{
						
						if(i==bpos_x || i==epos_x || j==bpos_y || j==epos_y || k==bpos_z || k==epos_z)
							continue;
						
						if(data1d[(i-bpos_x) + offset_crop_y] == seed_val)
						{
							seed_x = (i-bpos_x) ; seed_y = (j-bpos_y); seed_z = (k-bpos_z);
							break;
						}
					}
				}
			}
		
		}
	}
	
	
	qDebug("x %d y %d z %d thresh %d range %d intensity %d", seed_x, seed_y, seed_z, seed_val, range_val, data1d[seed_z*sx*sy + seed_y*sx + seed_x]);
	
	//----------------------------------------------------------------------------------------------------------------------------------
	
	// de-alloc
	//if (pSbject) {delete []pSbject; pSbject=0;} // image visualized in v3d now

	
	// second scan
	progress.setValue(++i_progress); 
	
	// 3D region growing
	//----------------------------------------------------------------------------------------------------------------------------------
	
	int end_preprocess = clock();
	
	printf("time eclapse %d s for preprocessing!\n", (end_preprocess-start_t)/1000000);
	
	enum states {Known, Alive, FarAway, Trial, BOUNDARY}; 
	
	long offset_y, offset_z;
	
	offset_y=sx;
	offset_z=sx*sy;
	
	long neighborhood_6[6] = {-1, 1, -offset_y, offset_y, -offset_z, offset_z}; 
	long neighborhood_26[26] = {-1, 1, -offset_y, offset_y, -offset_z, offset_z,
								-offset_y-1, -offset_y+1, -offset_y-offset_z, -offset_y+offset_z, 
								offset_y-1, offset_y+1, offset_y-offset_z, offset_y+offset_z,
								offset_z-1, offset_z+1, -offset_z-1, -offset_z+1,
								-1-offset_y-offset_z, -1-offset_y+offset_z, -1+offset_y-offset_z, -1+offset_y+offset_z,
								1-offset_y-offset_z, 1-offset_y+offset_z, 1+offset_y-offset_z, 1+offset_y+offset_z}; 
	long neighbors = 26;
	
	long bound_idx = (sz-1)*sx*sy + (sy-1)*sx + sx-1; 
	
	//Fast Marching
	HeapMinSort heap(pagesz);
	
	// initial state heap
	unsigned char* state = new unsigned char[pagesz]; 
	
	unsigned char* phi = new unsigned char [pagesz];
	
	bool* inserted = new bool [pagesz];
	
	for(long k = 0; k < sz; k++) 
	{				
		long idxk = k*offset_z;
		for(long j = 0;  j < sy; j++) 
		{
			long idxj = idxk + j*offset_y;
			
			for(long i = 0, idx = idxj; i < sx;  i++, idx++) 
			{
				
				phi[idx] = 255; 
				state[idx] = BOUNDARY; 
				inserted[idx] = false;
				
				if(i==0 || i==sx-1 || j==0 || j==sy-1 || k==0 || k==sz-1)
					continue;
				
				if( i==seed_x && j==seed_y && k==seed_z ) 
				{
					heap.insert(idx, 0); 
					phi[idx] = 0; 
					state[idx] = Known; 
					inserted[idx] = true;
				}
				else
					state[idx] = FarAway;
				
				
			}
		}
	}
	
//	//
//	progress.setValue(++i_progress); 
	
	long count=1;
	long wc=0;
	
	// del a point from the heap
	long idx;
	float weight; 
	while( heap.del(&idx, &weight) )
	{
		if( state[idx] == Alive ) continue; 		
		
		// using region growing critera here 
		if( state[idx] != Known )
		{
			for(int ineighbor=0; ineighbor<neighbors; ineighbor++)
			{
				long n_idx = idx + neighborhood_26[ineighbor]; 
				
				if(n_idx<bound_idx && n_idx>0)
				{
					
					if(phi[n_idx] == 0 && (fabs(data1d[idx] - seed_val)<=range_val))
					{
						phi[idx] = 0;
						break;
					}
					
				}
				
			}
		}
		else
		{
			phi[idx] = 0;
		}

		count--; wc++;
		
		//set processed one to state "Alive" 
		state[idx] = Alive; 
		
		//find new neighbors and added to heap
		for(int ineighbor=0; ineighbor<neighbors; ineighbor++)
		{
			long n_idx = idx + neighborhood_26[ineighbor]; 
			
			if(n_idx<bound_idx && n_idx>0)
			{
				if( (state[n_idx]==FarAway || state[n_idx]==Trial) && inserted[n_idx]==false)
				{
					heap.insert(n_idx, phi[n_idx]+wc);  count++;
					state[n_idx] = Trial; 
					inserted[n_idx] = true;
				}
			}
		}
		
	}

	// de-alloc
	if (inserted) {delete []inserted; inserted=0;}
	if (state) {delete []state; state=0;}
	
	//----------------------------------------------------------------------------------------------------------------------------------
	
	// third scan
	progress.setValue(++i_progress); 
	
	int end_rgn = clock();
	
	printf("time eclapse %d s for region growing!\n", (end_rgn-end_preprocess)/1000000);
	
	// dist transform
	//----------------------------------------------------------------------------------------------------------------------------------
	long sz_data[4];
	sz_data[0]=sx; sz_data[1]=sy; sz_data[2]=sz; sz_data[3]=1;
	
	long *pDist = new long [pagesz];
	if (!pDist) 
	{
		printf("Fail to allocate memory.\n");
		return;
	}
	long *pLabel = new long [pagesz];
	if (!pLabel) 
	{
		printf("Fail to allocate memory.\n");
		return;
	}
	unsigned char *pData = new unsigned char [2*pagesz]; // first filled and second dist map
	if (!pData) 
	{
		printf("Fail to allocate memory.\n");
		return;
	}
	
	for(long k = 0; k < sz; k++) 
	{				
		long idxk = k*offset_z;
		for(long j = 0;  j < sy; j++) 
		{
			long idxj = idxk + j*offset_y;
			for(long i = 0, idx = idxj; i < sx;  i++, idx++) 
			{
				
				if(i==0 || i==sx-1 || j==0 || j==sy-1 || k==0 || k==sz-1 || phi[idx]==0) // background and boundary
				{
					pData[idx] = 0;
					pData[idx + pagesz] = 0;
				}
				else 
				{

					pData[idx] = 1; //data1d[idx];
					pData[idx + pagesz] = 1;

				}
			}
		}
	
	}
	
	// de-alloc
	if (phi) {delete []phi; phi=0;}
	
	// dist transform
	dt3d_binary(pData, pDist, pLabel, sz_data, 1);
	
	long maxtest=0, mintest=INF;
	for(long i=0; i<pagesz; i++)
	{
		long tmp=pDist[i];
		
		if(maxtest<tmp) maxtest=tmp;
		if(mintest>tmp) mintest=tmp;
	}
	maxtest -= mintest;
	
	if(maxtest)
	{
		for(long i=0; i<pagesz; i++)
		{
			unsigned char tmp = 255*(pDist[i]-mintest)/maxtest;
	
			// image blending
			long tmp1 = tmp + data1d[i];
			
			pData[i] = (tmp1>255)?255:tmp1; // sum
			

			pData[i + pagesz] = tmp;
		}
	}
	
		
	// de-alloc
	if (data1d) {delete []data1d; data1d=0;} //
	if (pDist) {delete []pDist; pDist=0;}
	if (pLabel) {delete []pLabel; pLabel=0;}
	
	//----------------------------------------------------------------------------------------------------------------------------------

	
	int end_dist = clock();
	
	printf("time eclapse %d s for dist computing!\n", (end_dist-end_rgn)/1000000);
	
	
	progress.setValue(num_progress);

	
	Image4DSimple p4DImage;
	p4DImage.setData((unsigned char*)pData, sx, sy, sz, 2, subject->datatype);
	
	v3dhandle newwin = callback.newImageWindow();
	callback.setImage(newwin, &p4DImage);
	callback.setImageName(newwin, QString("filled_image"));
	callback.updateImageWindow(newwin);

	
}
Exemplo n.º 6
0
//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();
}
Exemplo n.º 7
0
bool autotrace(const V3DPluginArgList & input, V3DPluginArgList & output,V3DPluginCallback2 &callback)
{
    cout<<"Welcome to MOST tracing"<<endl;
    unsigned int c=1;
    int InitThreshold = 20;
    seed_size_all = 20;
    int slipsize=20;

    if (input.size()>=2)
    {
        vector<char*> paras = (*(vector<char*> *)(input.at(1).p));
        cout<<paras.size()<<endl;
        if(paras.size() >= 1) c = atoi(paras.at(0));
        if(paras.size() >= 2) InitThreshold = atoi(paras.at(1));
        if(paras.size() >= 3) seed_size_all = atoi(paras.at(2));
        if(paras.size() >= 4) slipsize = atoi(paras.at(3));
    }

    char * inimg_file = ((vector<char*> *)(input.at(0).p))->at(0);

    cout<<"ch = "<<c<<endl;
    cout<<"threshold = "<<InitThreshold<<endl;
    cout<<"inimg_file = "<<inimg_file<<endl;
    cout<<"seedsize = "<<seed_size_all<<endl;
    cout<<"slipsize = "<<slipsize<<endl;

    Image4DSimple *subject = callback.loadImage(inimg_file);
    if(!subject || !subject->valid())
    {
         v3d_msg("Fail to load the input image.",0);
         if (subject) {delete subject; subject=0;}
         return false;
    }

    if( c < 1 || c > subject->getCDim())
    {
         v3d_msg("Invalid channel input.",0);
         if (subject) {delete subject; subject=0;}
         return false;
    }

    V3DLONG N = subject->getXDim();
    V3DLONG M = subject->getYDim();
    V3DLONG P = subject->getZDim();

    V3DLONG pagesz = N*M*P;
    int datatype = subject->getDatatype();
    unsigned char *data1d = subject->getRawDataAtChannel(c-1);

    unsigned char *output_image=0;
    switch (datatype)
    {
    case V3D_UINT8:
        try {output_image = new unsigned char [pagesz];}
        catch(...)  {v3d_msg("cannot allocate memory for output_image.",0); return false;}
        for(V3DLONG i = 0; i<pagesz; i++)
            output_image[i] = data1d[i];


        break;
        default: v3d_msg("Invalid data type. Do nothing.",0); return false;
    }


    MOSTImage img;
    img.setData( (unsigned char*)output_image, subject->getXDim(),subject->getYDim(),subject->getZDim(),subject->getCDim(),subject->getDatatype());
    QString swcfile = QString(inimg_file) + "_MOST.swc";

    LandmarkList seedList;
    QTime qtime_seed;
    qtime_seed.start();
    if(1)
    {
        for(int i =1;i<=N;i+=20)
        img.auto_detect_seedx(seedList,i,InitThreshold,seed_size_all);
    }
    if(1)
    {
        for(int i =1;i<=M;i+=20)
        img.auto_detect_seedy(seedList,i,InitThreshold,seed_size_all);
    }
    if(1)
    {
        for(int i =1;i<=P;i+=20)
        img.auto_detect_seedz(seedList,i,InitThreshold,seed_size_all);
    }

    qDebug("  cost time seed = %g sec", qtime_seed.elapsed()*0.001);
    static long init_flag = 0;

    for(init_flag = 0;init_flag<subject->getTotalUnitNumberPerChannel();init_flag++)
    {
        visited.push_back(false);
    }

    // converte the formate
    NeuronTree vt;
    QTime qtime;
    qtime.start();
    vt = img.trace_seed_list(seedList, visited,InitThreshold,1.0,1.0,1.0,swcfile,slipsize,0);
    qDebug("  cost time totol= %g sec", qtime.elapsed()*0.001);

    v3d_msg(QString("\nNow you can drag and drop the generated swc fle [%1] into Vaa3D.").arg(swcfile),0);
    if (subject) {delete subject; subject=0;}
    return true;


}
Exemplo n.º 8
0
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;

}
Exemplo n.º 9
0
bool consensus_skeleton(vector<NeuronTree> & nt_list, QList<NeuronSWC> & merge_result, int method_code,V3DPluginCallback2 &callback)
{


    double CLUSTERING_RANGE =10;
    //potentially, there are invalid neuron trees (massive node points, no node points, looping)
    remove_outliers(nt_list);
    int neuronNum = nt_list.size();

    //initialize the image volume to record/accumulate the  location votes from neurons
    MyBoundingBox bbUnion = neuron_trees_bb(nt_list);

    Point3D offset = {bbUnion.min_x ,bbUnion.min_y ,bbUnion.min_z };
    float closeness = 1.0;
    V3DLONG  sz_x = ceil((bbUnion.max_x - bbUnion.min_x ) / closeness) +1; //+0.5 to round up from float to V3DLONG
    V3DLONG  sz_y = ceil((bbUnion.max_y - bbUnion.min_y ) / closeness) +1;
    V3DLONG  sz_z = ceil((bbUnion.max_z - bbUnion.min_z ) / closeness) +1;
    V3DLONG  tol_sz = sz_x * sz_y * sz_z;
    cout << "image size = " << tol_sz<<": " <<sz_x<<"x "<<sz_y<<" x"<<sz_z<< endl;

    unsigned char * img1d = new unsigned char[tol_sz];
    for(V3DLONG i = 0; i < tol_sz; i++) img1d[i] = 0;

    //count
    for (int j =0; j < nt_list.size(); j++){
        NeuronTree nt = nt_list[j];
        for (int i =0; i < nt.listNeuron.size(); i++)
        {
            NeuronSWC node = nt.listNeuron.at(i);
            V3DLONG id_x = (node.x-offset.x) +0.5; //round up
            V3DLONG id_y = (node.y-offset.y) +0.5;
            V3DLONG id_z = (node.z-offset.z) +0.5;
            V3DLONG idx = id_z * (sz_x*sz_y) + id_y * sz_x + id_x;
            if (idx <tol_sz ){
                img1d[idx] ++ ;}
            else{
                cout <<"error idx" <<endl;
            }
        }
    }

    //for debug only
    Image4DSimple *image = new Image4DSimple();
    image->setData(img1d, sz_x, sz_y, sz_z, 1, V3D_UINT8);
    callback.saveImage(image, "./vote_count_image.v3draw");

    //non-maximum suppresion
     vector<Point3D>  node_list;
     vector<unsigned int>  vote_list;
     non_max_suppresion (img1d,sz_x,sz_y,sz_z,offset,node_list,vote_list,3);
     cout << "After non_max supression:"<< endl;
     cout << "number of nodes:"<< node_list.size() << endl;
     cout << "maximum votes:" << v_min(vote_list) << endl;
     cout << "minimum votes:" << v_max(vote_list) << endl;

     Image4DSimple *image2 = new Image4DSimple();
     image2->setData(img1d, sz_x, sz_y, sz_z, 1, V3D_UINT8);
     callback.saveImage(image2, "./nms_image.v3draw");


     // for debug: save node_list to check locations
     QList<NeuronSWC> locationTree;
     for (int i=0;i<node_list.size();i++)
     {
         NeuronSWC tmp;
         tmp.x = node_list[i].x;
         tmp.y = node_list[i].y;
         tmp.z = node_list[i].z;

         tmp.type = 2; //edge votes
         tmp.pn = -1;  //parent id, form the edge
         tmp.r = double(vote_list[i])/neuronNum*3; //*3 for visulaization
         tmp.n = i+1;

         locationTree.append(tmp);
     }
    export_listNeuron_2swc(locationTree, "./testlocation.swc");

    printf("(2). compute adjacency matrix (vote for edges).\n");


    double * adjMatrix;
    V3DLONG * plist;
    V3DLONG num_nodes = node_list.size();
    try{
        adjMatrix = new double[num_nodes*num_nodes];
        plist = new V3DLONG[num_nodes];
        for (V3DLONG i=0;i<num_nodes*num_nodes;i++) adjMatrix[i] = 0;
    }
    catch (...)
    {
        fprintf(stderr,"fail to allocate memory.\n");
        if (adjMatrix) {delete[] adjMatrix; adjMatrix=0;}
        if (plist) {delete[] plist; plist=0;}
        return false;
    }


    for (int i=0;i<neuronNum;i++)
    {
        QHash<V3DLONG, V3DLONG > nodeMap;
        for (V3DLONG j=0;j<nt_list[i].listNeuron.size();j++)
        {
            NeuronSWC s = nt_list[i].listNeuron.at(j);
            Point3D cur;
            cur.x = s.x;
            cur.y = s.y;
            cur.z = s.z;

            //find its nearest node
            V3DLONG node_id = -1;// this node does not exist
            double min_dis = CLUSTERING_RANGE; //threshold to ignore mapping  (too far away)
            for (V3DLONG ni = 0; ni <node_list.size(); ni++)
            {
                Point3D p = node_list[ni];
                double dis = PointDistance(p,cur);

                if (dis < min_dis){
                    min_dis = dis;
                    node_id = ni;
                }
            }
            if (node_id > -1){
                nodeMap.insert( j, node_id);
            }
        }
        //maps.push_back(nodeMap);


        for (V3DLONG j=0;j<nt_list[i].listNeuron.size();j++)
        {
            NeuronSWC cur = nt_list[i].listNeuron[j];
            // if (cur.pn<0) continue;
            V3DLONG n_id,pn_id;
            n_id = nodeMap[j];
            if (n_id > 0){
                V3DLONG pidx = cur.pn-1;//nt_list[i].hashNeuron.value(cur.pn);  // find the index in nueon_list

                pn_id = nodeMap[pidx];
                if (pn_id > 0){
                    adjMatrix[n_id*num_nodes + pn_id] += 1;
                    adjMatrix[pn_id*num_nodes + n_id] += 1;
                    //cout<<adjMatrix[n_id*num_nodes + pn_id] <<endl;

                }
            }
        }

    }


    if (method_code ==0 ){
        long rootnode =100;
        printf("(3). computing minimum-spanning tree.\n");

        //if (!mst_dij(adjMatrix, num_nodes, plist, rootnode))
        if (!mst_prim(adjMatrix, num_nodes, plist, rootnode))

        {
            fprintf(stderr,"Error in minimum spanning tree!\n");
            return false;
        }

        printf("(3). genearate consensus graph swc file by assign parents (form edges).\n");

       // code the edge votes into type for visualization
       //         graph: duplicate swc nodes are allowed to accomandate mutiple parents for the child node, no root id,
        merge_result.clear();
        for (V3DLONG i = 0;i <num_nodes;i ++)
        {
            V3DLONG p = plist[i];
            //cout <<p<<endl;
            unsigned int edgeVote = adjMatrix[i*num_nodes + p];

            NeuronSWC tmp;
            tmp.x = node_list[i].x;
            tmp.y = node_list[i].y;
            tmp.z = node_list[i].z;

            tmp.type = edgeVote; //edge votes
            tmp.pn = p + 1;  //parent id, form the edge
            tmp.r = double(vote_list[i])/double(neuronNum);
            tmp.n = i+1;

            merge_result.append(tmp);

        }
    }

//### output vertices ( node lcoations)
//    V3DLONG count = 0;
//    for (V3DLONG i=0;i<num_nodes;i++)
//    {
//            NeuronSWC tmp;
//            tmp.x = node_list[i].x;
//            tmp.y = node_list[i].y;
//            tmp.z = node_list[i].z;
//           // tmp.fea_val.push_back(vote_list[i]);  //location votes are coded into radius

//            tmp.type = 0; //vertices (soma)
//            tmp.pn = -1;  //parent id, no edge
//            tmp.r = double(vote_list[i])/double(neuronNum); //location votes are coded into radius
//            tmp.n = count +1; //id start from 1
//            merge_result.append(tmp);
//            count++;
//    }

//    //output edges, go through half of the symmetric matrix, not directed graph
//    for (V3DLONG row = 0;row <num_nodes;row ++)
//    {
//        for (V3DLONG col = row+1;col < num_nodes;col++){
//            unsigned int edgeVote = adjMatrix[row*num_nodes + col];
//            if (edgeVote > 1)
//            {
//                NeuronSWC tmp;
//                tmp.x = node_list[row].x;
//                tmp.y = node_list[row].y;
//                tmp.z = node_list[row].z;

//                tmp.type = edgeVote; //edge votes
//                tmp.pn = col + 1;  //parent id  , form the edge
//                tmp.r = double(vote_list[row])/double(neuronNum);
//                tmp.n = count+1;

//                merge_result.append(tmp);
//                count++;
//            }
//        }
//    }

    // alternative
  if  (method_code == 1){
        merge_result.clear();
        V3DLONG count = 0;
        for (V3DLONG i=0;i<num_nodes;i++)
        {
                NeuronSWC tmp;
                tmp.x = node_list[i].x;
                tmp.y = node_list[i].y;
                tmp.z = node_list[i].z;
               // tmp.fea_val.push_back(vote_list[i]);  //location votes are coded into radius

                tmp.type = 0; //vertices (soma)
                tmp.pn = -1;  //parent id, no edge
                tmp.r = double(vote_list[i])/double(neuronNum); //location votes are coded into radius
                tmp.n = count +1; //id start from 1
                merge_result.append(tmp);
                count++;
        }

        //output edges, go through half of the symmetric matrix, not directed graph
        for (V3DLONG row = 0;row <num_nodes;row ++)
        {
            for (V3DLONG col = row+1;col < num_nodes;col++){
                unsigned int edgeVote = adjMatrix[row*num_nodes + col];
                if (edgeVote > 0)
                {
                    if (merge_result[row].pn == -1)
                    {//exsiting isolated vertex, modify parent id
                        merge_result[row].type = edgeVote; //edge votes
                        merge_result[row].pn = col + 1;  //parent id  , form the edge
                        merge_result[row].r = double(vote_list[row])/double(neuronNum);
                    }
                    else{
                      //add new edge  , via duplication nodes with different parent id and edge votes
                        NeuronSWC tmp;
                        tmp.x = node_list[row].x;
                        tmp.y = node_list[row].y;
                        tmp.z = node_list[row].z;

                        tmp.type = edgeVote; //edge votes
                        tmp.pn = col + 1;  //parent id  , form the edge
                        tmp.r = double(vote_list[row])/double(neuronNum);
                        tmp.n = count+1;

                        merge_result.append(tmp);
                        count++;
                    }

                }
            }
        }


}
    if (adjMatrix) {delete[] adjMatrix; adjMatrix = 0;}
    if (plist) {delete[] plist; plist=0;}


    return true;
}
Exemplo n.º 10
0
/**********************************************************************************
* Returns a new, gaussian-noise corrupted image from the given image
***********************************************************************************/
Image4DSimple* CImageUtils::addGaussianNoise(
        Image4DSimple* im,      // input image
        float w)                // gaussian noise weight (1 = only noise, 0 = no noise)
throw (tf::RuntimeException)
{
    // checks
    if(!im || !im->getRawData())
        throw tf::RuntimeException("in CImageUtils::addGaussianNoise(): invalid image data");
    if(im->getTDim() > 1)
        throw tf::RuntimeException(tf::strprintf("in CImageUtils::addGaussianNoise(): image has TDim = %d (5D not supported)", im->getTDim()));

    // allocate new image
    Image4DSimple* imout = new Image4DSimple();
    imout->setXDim(im->getXDim());
    imout->setYDim(im->getYDim());
    imout->setZDim(im->getZDim());
    imout->setCDim(im->getCDim());
    imout->setTDim(im->getTDim());
    imout->setDatatype(im->getDatatype());
    V3DLONG data_size = imout->getTotalBytes();
    unsigned char* data = new unsigned char[data_size];
    imout->setRawDataPointer(data);

    // data corruption
    if(imout->getDatatype() == V3D_UINT8)
    {
        unsigned char* data_in = im->getRawData();
        for(V3DLONG k=0; k<data_size; k++)
            data[k] = static_cast<tf::uint8>((1-w)*data_in[k] + w*(rand()%256) +0.5f);
    }
    else if(imout->getDatatype() == V3D_UINT16)
    {
        unsigned short* data_in = (unsigned short*)(im->getRawData());
        for(V3DLONG k=0; k<data_size/2; k++)
            data[k] = static_cast<tf::uint16>((1-w)*data_in[k] + w*(rand()%65535) +0.5f);
    }
    else
        throw tf::RuntimeException("in CImageUtils::addGaussianNoise(): image is neither UINT8 nor UINT16 (not supported)");

    return imout;
}
Exemplo n.º 11
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);
}
Exemplo n.º 12
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;

}
Exemplo n.º 13
0
void FL_cellseg(V3DPluginCallback2 &callback, QWidget *parent)
{
	v3dhandle curwin = callback.currentImageWindow();
	if (!curwin)
	{
		v3d_msg("You don't have any image open in the main window.");
		return;
	}
	
	Image4DSimple* subject = callback.getImage(curwin);
	QString m_InputFileName = callback.getImageName(curwin);
	
	if (!subject)
	{
		QMessageBox::information(0, title, QObject::tr("No image is open."));
		return;
	}
	if (subject->getDatatype()!=V3D_UINT8)
	{
		QMessageBox::information(0, title, QObject::tr("This demo program only supports 8-bit data. Your current image data type is not supported."));
		return;
	}

	V3DLONG sz0 = subject->getXDim();
    V3DLONG sz1 = subject->getYDim();
    V3DLONG sz2 = subject->getZDim();
	V3DLONG sz3 = subject->getCDim();
	
	Image4DProxy<Image4DSimple> pSub(subject);
	
	
	//----------------------------------------------------------------------------------------------------------------------------------
	V3DLONG channelsz = sz0*sz1*sz2;

	float *pLabel = 0;
	unsigned char *pData = 0;

	
	//get the segmentation parameters
	segParameter segpara;
	dialog_watershed_para *p_mydlg=0;
	if (!p_mydlg) p_mydlg = new dialog_watershed_para(&segpara, subject);
	int res = p_mydlg->exec();
	if (res!=QDialog::Accepted)
		return;
	else
		p_mydlg->fetchData(&segpara);
	if (p_mydlg) {delete p_mydlg; p_mydlg=0;}
	

	// now allocate memory and do computation
	int start_t = clock();
	
	Vol3DSimple <unsigned char> * tmp_inimg = 0;
	Vol3DSimple <USHORTINT16> * tmp_outimg = 0;
	
	try
	{
		tmp_inimg = new Vol3DSimple <unsigned char> (sz0, sz1, sz2);
		tmp_outimg = new Vol3DSimple <USHORTINT16> (sz0, sz1, sz2);
	}
	catch (...)
	{
		v3d_msg("Unable to allocate memory for processing. Do nothing.");
		if (tmp_inimg) {delete tmp_inimg; tmp_inimg=0;}
		if (tmp_outimg) {delete tmp_outimg; tmp_outimg=0;}
		return;
	}
	
	//do computation
	memcpy((void *)tmp_inimg->getData1dHandle(), (void *)subject->getRawDataAtChannel(segpara.channelNo), sz0*sz1*sz2);
	
	bool b_res = FL_cellseg(tmp_inimg, tmp_outimg, segpara);

	if (tmp_inimg) {delete tmp_inimg; tmp_inimg=0;} //free the space immediately for better use of memory
	if (!b_res)
	{
		v3d_msg("Fail to do the cell segmentation using FL_cellseg().\n");
	}
	else
	{
		V3DLONG new_sz0 = tmp_outimg->sz0();
		V3DLONG new_sz1 = tmp_outimg->sz1();
		V3DLONG new_sz2 = tmp_outimg->sz2();
		V3DLONG new_sz3 = 1;
		V3DLONG tunits = new_sz0*new_sz1*new_sz2*new_sz3;
		USHORTINT16 * outvol1d = new USHORTINT16 [tunits];
		
		USHORTINT16 * tmpImg_d1d = (USHORTINT16 *)(tmp_outimg->getData1dHandle());
		
		memcpy((void *)outvol1d, (void *)tmp_outimg->getData1dHandle(), tunits*sizeof(USHORTINT16));
		if (tmp_outimg) {delete tmp_outimg; tmp_outimg=0;} //free the space immediately for better use of memory
		
		Image4DSimple p4DImage;
		p4DImage.setData((unsigned char*)outvol1d, sz0, sz1, sz2, 1, V3D_UINT16);
		
		v3dhandle newwin = callback.newImageWindow();
		callback.setImage(newwin, &p4DImage);
		callback.setImageName(newwin, QString("Segmented Image"));
		callback.updateImageWindow(newwin);
	}
		

	//----------------------------------------------------------------------------------------------------------------------------------

	int end_t = clock();
	printf("time eclapse %d s for labeling objects!\n", (end_t-start_t)/1000000);
}
Exemplo n.º 14
0
void ThreadedTracer::run(){

qDebug()<<"loadScan input: "<<latestString;
//QString latestString = getFileString();
//    latestString =QString("/data/mat/BRL/DATA_FOR_GROUP/testDataForZhi/ZSeries-06092016-1407-8470/ZSeries-06092016-1407-8470_Cycle00001_Ch1_000001.ome.tif");
//    bool isAdaptive = 1;
//    int methodChoice = 1;

//LandmarkList inputRootList;
QString fString;
fString = QString("Cycle%1").arg(tileNumber,5,10,QLatin1Char('0'));
qDebug()<<tileNumber;

QList<LandmarkList> newTipsList;
LandmarkList newTargetList;

QFileInfo imageFileInfo = QFileInfo(latestString);
if (imageFileInfo.isReadable()){
    Image4DSimple * pNewImage = cb->loadImage(latestString.toLatin1().data());
    QDir imageDir =  imageFileInfo.dir();
    QStringList filterList;
    filterList.append(QString("*").append(fString).append("_Ch").append(channel).append("*.tif"));
    qDebug()<<"filterlist.first()"<<filterList.first();
    imageDir.setNameFilters(filterList);
    QStringList fileList = imageDir.entryList();

    //use this to id the number of images in the stack (in one channel?!)
    V3DLONG x = pNewImage->getXDim();
    V3DLONG y = pNewImage->getYDim();
    V3DLONG nFrames = fileList.length();

    V3DLONG tunits = x*y*nFrames;
    unsigned short int * total1dData = new unsigned short int [tunits];
    unsigned short int * total1dData_mip= new unsigned short int [x*y];
    for(V3DLONG i =0 ; i < x*y; i++)
        total1dData_mip[i] = 0;
    V3DLONG totalImageIndex = 0;
    double p_vmax=0;
    qDebug()<<"nFrames = "<<nFrames;
    for (int f=0; f<nFrames; f++){
        qDebug()<<fileList[f];
        Image4DSimple * pNewImage = cb->loadImage(imageDir.absoluteFilePath(fileList[f]).toLatin1().data());
        if (pNewImage->valid()){
            unsigned short int * data1d = 0;
            data1d = new unsigned short int [x*y];
            data1d = (unsigned short int*)pNewImage->getRawData();
            for (V3DLONG i = 0; i< (x*y); i++)
            {
                total1dData[totalImageIndex]= data1d[i];
                if(data1d[i] > p_vmax) p_vmax = data1d[i];
                if(total1dData_mip[i] < data1d[i]) total1dData_mip[i] = data1d[i];
                totalImageIndex++;
            }
            if(data1d) {delete []data1d; data1d = 0;}
        }else{
            qDebug()<<imageDir.absoluteFilePath(fileList[f])<<" failed!";
        }
    }

    Image4DSimple* total4DImage = new Image4DSimple;
    total4DImage->setData((unsigned char*)total1dData, x, y, nFrames, 1, V3D_UINT16);

    Image4DSimple* total4DImage_mip = new Image4DSimple;
    total4DImage_mip->setData((unsigned char*)total1dData_mip, x, y, 1, 1, V3D_UINT16);


    QString swcString = saveDirString;
    swcString.append("/x_").append(QString::number((int)tileLocation.x)).append("_y_").append(QString::number((int)tileLocation.y)).append("_").append(imageFileInfo.fileName()).append(fString).append(".swc");


    QString scanDataFileString = saveDirString;
    scanDataFileString.append("/").append("scanData.txt");
    qDebug()<<scanDataFileString;
    QFile saveTextFile;
    saveTextFile.setFileName(scanDataFileString);// add currentScanFile
    if (!saveTextFile.isOpen()){
        if (!saveTextFile.open(QIODevice::Text|QIODevice::Append  )){
            qDebug()<<"unable to save file!";
            return;}     }
    QTextStream outputStream;
    outputStream.setDevice(&saveTextFile);
    total4DImage->setOriginX(tileLocation.x);
    total4DImage->setOriginY(tileLocation.y);

    qDebug()<<total4DImage->getOriginX();


    outputStream<< (int) total4DImage->getOriginX()<<" "<< (int) total4DImage->getOriginY()<<" "<<swcString<<" "<< (int) x<<" "<< (int) y<<" "<<"\n";

    saveTextFile.close();
    V3DLONG mysz[4];
    mysz[0] = total4DImage->getXDim();
    mysz[1] = total4DImage->getYDim();
    mysz[2] = total4DImage->getZDim();
    mysz[3] = total4DImage->getCDim();

    tileLocation.ev_pc1 = (double) total4DImage->getXDim();
    tileLocation.ev_pc2 = (double) total4DImage->getYDim();


    QString imageSaveString = saveDirString;


    // add bit of code to image green - red channels. This will require an additional argument or another signal/slot combination to monitor the value of a combobox in the GUI...
    // add button to do || nT on mXtls




    //convert to 8bit image using 8 shiftnbits
    unsigned char * total1dData_8bit = 0;
    try
    {
        total1dData_8bit = new unsigned char [tunits];
    }
    catch (...)
    {
        v3d_msg("Fail to allocate memory in total1dData_8bit.\n");

        return;
    }
    double dn = pow(2.0, double(5));
    for (V3DLONG i=0;i<tunits;i++)
    {
        double tmp = (double)(total1dData[i]) / dn;
        if (tmp>255) total1dData_8bit[i] = 255;
        else
            total1dData_8bit[i] = (unsigned char)(tmp);
    }




    total4DImage->setData((unsigned char*)total1dData_8bit, x, y, nFrames, 1, V3D_UINT8);

    imageSaveString.append("/x_").append(QString::number((int)tileLocation.x)).append("_y_").append(QString::number((int)tileLocation.y)).append("_").append(imageFileInfo.fileName()).append(imageFileInfo.fileName()).append(fString).append(".v3draw");
    simple_saveimage_wrapper(*cb, imageSaveString.toLatin1().data(),(unsigned char *)total1dData_8bit, mysz, V3D_UINT8);
    qDebug()<<"=== immediately before tracing =====";
//-------------
    V3DPluginArgItem arg;
    V3DPluginArgList input;
    V3DPluginArgList output;

    QString full_plugin_name;
    QString func_name;

    arg.type = "random";std::vector<char*> arg_input;
    std:: string fileName_Qstring(imageSaveString.toStdString());char* fileName_string =  new char[fileName_Qstring.length() + 1]; strcpy(fileName_string, fileName_Qstring.c_str());
    arg_input.push_back(fileName_string);
    arg.p = (void *) & arg_input; input<< arg;

    char* char_swcout =  new char[swcString.length() + 1];strcpy(char_swcout, swcString.toStdString().c_str());
    arg.type = "random";std::vector<char*> arg_output;arg_output.push_back(char_swcout); arg.p = (void *) & arg_output; output<< arg;

    arg.type = "random";
    std::vector<char*> arg_para;



    arg_para.push_back("1");
    arg_para.push_back("1");
    full_plugin_name = "neuTube";
    func_name =  "neutube_trace";

    arg.p = (void *) & arg_para; input << arg;

    if(!cb->callPluginFunc(full_plugin_name,func_name,input,output))
    {

         qDebug()<<("Can not find the tracing plugin!\n");

         return;
    }
    emit done();

}else{
    qDebug()<<"invalid image";
}
}
Exemplo n.º 15
0
//return a list of predictions ? Or a mask image? 
//  Also need numbers of cells, and centers of cells
//work on local maxima
//use different preprocessing, feature extraction etc.
//1d_dimension is ROIDImension + 1
//Note: be aware of the order x, y, z are passed to submethods.
unsigned char* CellClassifier::annotateAnImage(V3DPluginCallback &callback, v3dhandle win, Image4DSimple* image, int ch, int grid, int dimension_1d)
{

   	 std::vector <LocationSimple> detectedPos;
   	 LandmarkList markerList;
     long sx=image->sz0, sy=image->sz1, sz=image->sz2; 
     long pagesz=sx*sy;
     long channelsz=sx*sy*sz;

     //smoothed and get local maxima
     //sensitive gaussian filtering radius
     //  ??????? use distance transform image???????
     
     int Wx = dimension_1d, Wy = dimension_1d, Wz = dimension_1d;  
     unsigned char * filtered = gaussianfiltering(image->getRawData(), sx, sy, sz, Wx, Wy, Wz);
     
     unsigned char * flag_lm = check_localMaxima_ker(filtered, sx, sy, sz, 0);
     
     
     //unsigned char * flag_lm = check_localMaxima(callback, image, ch); //062110

     unsigned char *results = new unsigned char [channelsz]; //prediction results.
     if (!results)
     {
        printf("Fail to allocate memory.\n");
        return NULL;
     }
     unsigned char *clearFlag = new unsigned char [channelsz]; //prediction results.
     if (!clearFlag)
     {
        printf("Fail to allocate memory.\n");
        return NULL;
     }
 
     //get model from file
     //string modelfile = "test_svm_model.txt";
     struct svm_model * pmodel = pclassifier->loadSVMModel(); 

     int r = dimension_1d/2;
     int prediction;
     int total = 0, cellcount = 0;
 
     //use (a somehow more restrict) template matching for adding some candidates.
     bool candidateflag = false;
     long cubesize = dimension_1d*dimension_1d*dimension_1d;
     double sigmax = (dimension_1d-1)/4.0, sigmay = (dimension_1d-1)/4.0, sigmaz = (dimension_1d-1)/4.0;
     double *g_1d = genGaussianKernel1D(dimension_1d, dimension_1d, dimension_1d, sigmax, sigmay, sigmaz);
     double curcoeff;
     //double coeff_th = 0.66; //will use average coeff of positive ones from training!!!!
     
     //init results
     for(long iz = 0; iz < sz; iz++)
     {
        long offsetk = iz*sx*sy;
        for(long iy = 0; iy < sy; iy++)
        {
            long offsetj = iy*sx;
            for(long ix = 0; ix < sx; ix++)
            {
               long idx = offsetk + offsetj + ix;
               results[idx] = 0;
               clearFlag[idx] = 1; //will be cleared later
             }
        }    
     }     

     //start search     
     int denied = 0;
     for(long iz = r; iz < sz-r; iz++)
     {
        long offsetk = iz*sx*sy;
        for(long iy = r; iy < sy-r; iy++)
        {
            long offsetj = iy*sx;
            for(long ix = r; ix < sx-r; ix++)
            {
               long idx = offsetk + offsetj + ix;
 
               //debug:
               //if(ix == 61 && iy==39 && iz==17) cout << "the missed one is here!!" << (int) flag_lm[idx] << endl;
               //if(ix == 63 && iy ==43 && iz ==16) cout << "the valley one (#3) is here!!" << (int) flag_lm[idx] << endl;;
               //if(ix == 65 && iy ==43 && iz ==14) cout << "the valley start point is here!!" << (int) flag_lm[idx] << endl;;

               if(flag_lm[idx] == 255 && clearFlag[idx] == 1 ) //only work on local maxima (and not cleared)
               {
                 //classify to see if it is a center               
                 prediction = classifyAVoxel(image, ch, iz, iy, ix, dimension_1d, pmodel); 
                                       
                 if(prediction == 0)
                    denied ++;
                  
                 candidateflag  = false;

                 if (prediction == 1 || candidateflag)
                 {
                   //cellcount ++;             
                   //results[idx] =  255; 
                   //
                  double ncx, ncy, ncz;
  
                  unsigned char * currentCube =getACube(image, ch, iz, iy, ix, dimension_1d, dimension_1d*dimension_1d, pagesz, channelsz); //fixed a bug 060210
                  curcoeff = coeff(currentCube, g_1d, cubesize);
 
                   //debug
                  if(ix == 65 && iy ==43 && iz ==14) 
                    std::cout << "coeff at valley:" << curcoeff << std::endl ;         
 
                  delete[] currentCube;
                   //if(curcoeff < 0.45)
                   //{
                    //  std::cout << "coeff too low for (" << ix << " " << iy << " " << iz << ") " << " coef: " << curcoeff << endl;                               
                    //  continue;
                   //}

                   //converge toward center of mass, 
                   
                   //move the center using highest score (either matching or classifier). 
                   /*
                   getMatchingCenter(image, ix, iy, iz, r, ch, ncx, ncy, ncz, flag_lm);
                   double nncx, nncy, nncz;
                   //getMassCenter(image, ncx, ncy, ncz, r, ch, nncx, nncy, nncz, flag_lm);
                   getMassCenter(filtered, sx,sy,sz, ncx, ncy, ncz, r, ch, nncx, nncy, nncz, flag_lm);
                   int newx = (int) (nncx+0.5), newy = (int) (nncy+0.5), newz = (int) (nncz+0.5); //rounding
                   */
                   
                   getMassCenter(filtered, sx,sy,sz, ix, iy, iz, r, ch, ncx, ncy, ncz, flag_lm);
                   int newx = (int) (ncx+0.5), newy = (int) (ncy+0.5), newz = (int) (ncz+0.5); //rounding
                   
                   //make a final decision if, after moving, there is a close neighbor identified already on the new spot
                   if (nearACenter(newx, newy, newz, results, r, sx, sy, sz))
                   {
                     // std::cout << "#" << cellcount << ", there's 1 nearby. Skip. " ;                   
                      continue;
                   }

                   long foundidx = newz*sx*sy + newy*sx + newx;
 
                   //check if move to a lm , possible for valley area between cells.
                   //why this made the debug image has 20 down to 9 cells!!
                   /*if ( flag_lm[foundidx] == 0)
                   {
                      std::cout << "non-lm. Skip. " ;                   
                      continue;
                   }*/
 
                   //else: a cell is found, set that to 255
                   results[foundidx] =  255; 

                   //remove foreground around that center from image: based on radius? reestimate based on std?
                   //int testt=0; for(int lll =0; lll < channelsz; lll++) if (flag_lm[lll] ==255) testt ++;
                   //cout << "postive flags: " << testt << endl;
                   //will not consider its neighbors in the future.
                   clearSurrounding(image, ch, newx, newy, newz, r, clearFlag);
                   //testt=0; for(int lll =0; lll < channelsz; lll++) if (flag_lm[lll] ==255) testt ++;
                   //cout << "postive flags after: " << testt << endl;

                   //increase cell counter by 1.
                   LocationSimple pp(newx, newy, newz);
                   detectedPos.push_back(pp);
                   LocationSimple marker(newx +1, newy +1, newz +1); //convert back to 1-base
                   marker.radius = r;
                   markerList.push_back(marker);               
                   
                   cellcount ++;
                   
                  }
                   
               }//end local maxima
          }//end ix
        }//end iy
     }//end iz
     
     std::cout << "total number of cells:" << cellcount << std::endl;
     
     
     char buf[30]; 
     itoa(cellcount, buf, 10);
     string resstring = "total cells:";
     resstring.append(buf);
     QMessageBox::information(0, "debug", QString(resstring.c_str()));
     
     std::cout << "total denied local maximum:" << denied << std::endl;
     
     svm_destroy_model(pmodel);
     
     /* //results only
     Image4DSimple p4DImage;
     p4DImage.setData(results, sx, sy, sz, 1, image->datatype);
     v3dhandle newwin = callback.newImageWindow();
     callback.setImage(newwin, &p4DImage);
     callback.setImageName(newwin,  "prediction results image");
     callback.updateImageWindow(newwin);
     */
     
     //v3d does not allow me to use the same image data in a different (new) window?
     //I need to make a copy of the data first?
     unsigned char *newimage1d = new unsigned char [channelsz]; 
     if(!newimage1d)  
     { 
        std::cout << "not enough memory to create result window";
        return results;
     } 
     unsigned char* image1d = image->getRawData();  
     for(long n = 0; n < channelsz; n++)
        newimage1d[n] = image1d[ch*channelsz + n];
     
     //show resulting cell markers  in a new window   
     Image4DSimple newImage;
     newImage.setData(newimage1d, sx, sy, sz, 1, image->datatype);
     v3dhandle newwin = callback.newImageWindow();
     callback.setImage(newwin, &newImage);
 	 callback.setImageName(newwin, "cell_counted");
	 callback.updateImageWindow(newwin);
	 callback.setLandmark(newwin, markerList); 


    //de-alloc
     //should I close svm file here???
     if(filtered)  { std::cout << "clean up memory for filtered image." << endl;  delete[] filtered; }
     if(flag_lm)   { std::cout << "clean up memory for local maximum." << endl;  delete[] flag_lm;  }   
     if(clearFlag) { std::cout << "clean up memory for flags." << endl;  delete[] clearFlag; }
     
     return results;
    
}
Exemplo n.º 16
0
bool findedgeimg(V3DPluginCallback2 &callback, const V3DPluginArgList & input, V3DPluginArgList & output)
{
    cout<<"Welcome to Label edge of a mask image"<<endl;
    if (output.size() != 1) return false;

    int method_code = 0;
    if (input.size()>=2)
    {
        vector<char*> paras = (*(vector<char*> *)(input.at(1).p));
        if(paras.size() >= 1) method_code = atoi(paras.at(0));
    }

    char * inimg_file = ((vector<char*> *)(input.at(0).p))->at(0);
    char * outimg_file = ((vector<char*> *)(output.at(0).p))->at(0);
    cout<<"method_code = "<<method_code<<endl;
    cout<<"inimg_file = "<<inimg_file<<endl;
    cout<<"outimg_file = "<<outimg_file<<endl;

    Image4DSimple *image = callback.loadImage(inimg_file);
    if (!image || !image->valid())
    {
        cerr<<"load image "<<inimg_file<<" error!"<<endl;
        return false;
    }

    V3DLONG szx=image->getXDim(),
            szy=image->getYDim(),
            szz=image->getZDim(),
            szc=image->getCDim();
    V3DLONG N = image->getTotalUnitNumber();

    //create the output buffer
    unsigned char *outputData = 0;
    try
    {
        outputData = new unsigned char [N];
        for (V3DLONG tmpi=0; tmpi<N; ++tmpi) outputData[tmpi] = 0; //preset to be all 0
    }
    catch (...)
    {
        v3d_msg("Fail to allocate memory.");
        if (outputData) {
            delete []outputData;
            outputData=0;
        }
        return false;
    }

    Image4DSimple outputImage;
    outputImage.setData((unsigned char*)outputData, szx, szy, szz, szc, V3D_UINT8);
    Image4DProxy<Image4DSimple> outputIProxy(&outputImage);

    //now do computation
    {
        bool bset255 = (method_code==0) ? false : true;

        Image4DProxy<Image4DSimple> p(image);
        Image4DProxy_foreach(p, ix, iy, iz, ic)
        {
            double v = p.value_at(ix, iy, iz, ic);
            V3DLONG cx, cy, cz;

            bool bb=false;
            for (cz = iz-1; cz<iz+2; ++cz)
            {
                for (cy = iy-1; cy<iy+2; ++cy)
                {
                    for (cx = ix-1; cx<ix+2; ++cx)
                    {
                        if (!p.is_inner(cx, cy, cz, ic))
                            continue;
                        if (v!=p.value_at(cx, cy, cz, ic))
                        {
                            *outputIProxy.at(ix, iy, iz, ic) = (bset255) ? 255 : v;
                            bb = true;
                            break;
                        }
                    }
                    if (bb)	break;
                }
                if (bb) break;
            }

            //note that all value had been preset as 0, thus no need to set as the background color in case not an edge point
        }
    }
Exemplo n.º 17
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);

}
Exemplo n.º 18
0
/**********************************************************************************
* Returns a new, interpolated image from the two given images
***********************************************************************************/
Image4DSimple* CImageUtils::interpolateLinear(
    Image4DSimple* im1,         // first image
    Image4DSimple* im2,         // second image
    int i,                      // step  index
    int N)                      // steps number
throw (tf::RuntimeException)
{
    // checks
    if(!im1 || !im1->getRawData())
        throw tf::RuntimeException("in CImageUtils::interpolate_linear(): invalid 1st image data");
    if(!im2 || !im2->getRawData())
        throw tf::RuntimeException("in CImageUtils::interpolate_linear(): invalid 2nd image data");
    if(im1->getXDim() != im2->getXDim())
        throw tf::RuntimeException("in CImageUtils::interpolate_linear(): the two images differ in X dimensions");
    if(im1->getYDim() != im2->getYDim())
        throw tf::RuntimeException("in CImageUtils::interpolate_linear(): the two images differ in Y dimensions");
    if(im1->getZDim() != im2->getZDim())
        throw tf::RuntimeException("in CImageUtils::interpolate_linear(): the two images differ in Z dimensions");
    if(im1->getCDim() != im2->getCDim())
        throw tf::RuntimeException("in CImageUtils::interpolate_linear(): the two images differ in channel dimensions");
    if(im1->getTDim() > 1)
        throw tf::RuntimeException(tf::strprintf("in CImageUtils::interpolate_linear(): 1st image has TDim = %d (5D not supported)", im1->getTDim()));
    if(im2->getTDim() > 1)
        throw tf::RuntimeException(tf::strprintf("in CImageUtils::interpolate_linear(): 2nd image has TDim = %d (5D not supported)", im2->getTDim()));
    if(im1->getDatatype() != V3D_UINT8)
        throw tf::RuntimeException("in CImageUtils::interpolate_linear(): 1st image is not UINT8 (not supported)");
    if(im2->getDatatype() != V3D_UINT8)
        throw tf::RuntimeException("in CImageUtils::interpolate_linear(): 2nd image is not UINT8 (not supported)");

    // allocate new image
    Image4DSimple* imout = new Image4DSimple();
    imout->setXDim(im1->getXDim());
    imout->setYDim(im1->getYDim());
    imout->setZDim(im1->getZDim());
    imout->setCDim(im1->getCDim());
    imout->setTDim(im1->getTDim());
    imout->setDatatype(V3D_UINT8);
    V3DLONG data_size = imout->getXDim()*imout->getYDim()*imout->getZDim()*imout->getCDim();
    unsigned char* data = new unsigned char[data_size];
    imout->setRawDataPointer(data);


    // interpolation channel-by-channel (it would be way better in the HSV space...)
    unsigned char* data1 = im1->getRawData();
    unsigned char* data2 = im2->getRawData();
    for(V3DLONG k=0; k<data_size; k++)
        data[k] = tf::linear<unsigned char>(data1[k], data2[k], i, N);

    return imout;
}