Ejemplo n.º 1
0
	int getPegthresholdFromUser(IplImage *img, Gui *gui, string message, int pegThreshVal, Rect r, cv::Mat &fgMaskPeg)
	{
		cv::Mat element[1];
		int count = 0;

		element[0] = getStructuringElement(MORPH_ELLIPSE, Size(8, 8), Point(0, 0));
		
		window_name = gui->windowName();
		cvDestroyWindow(window_name.c_str());
		cvNamedWindow(window_name.c_str(), CV_WINDOW_AUTOSIZE);
		cvMoveWindow(window_name.c_str(), 100, 100);

		img0 = (IplImage *)cvClone(img);
		char TrackbarName[50];
		sprintf(TrackbarName, "thresh x %d", slider_max);

		slider_val = pegThreshVal;
		createTrackbar(TrackbarName, window_name, &slider_val, slider_max, 0);

		

		Mat src, im1, im3;
		src = Mat(img0);

		im1 = Mat::zeros(src.size(), src.type());
		cvtColor(src, im3, CV_BGR2HSV);
		vector<vector<Point> > pegsI;
		while (1)
		{
			pegsI.clear();
			Mat channel[3];
			split(im3, channel);


			//Mat fgMaskRing;
			inRange(channel[2], slider_val, 255, fgMaskPeg);
			// ROI
			for (int y = 0; y < fgMaskPeg.rows; y++)
			{
				for (int x = 0; x < fgMaskPeg.cols; x++)
				{
					if (!(x >= r.tl().x && x <= r.br().x && y >= r.tl().y && y <= r.br().y))
					{
						fgMaskPeg.at<uchar>(Point(x, y)) = 0;
					}
				}
			}
			erode(fgMaskPeg, fgMaskPeg, element[0]);
			dilate(fgMaskPeg, fgMaskPeg, element[0]);
			erode(fgMaskPeg, fgMaskPeg, element[0]);
			dilate(fgMaskPeg, fgMaskPeg, element[0]);

			//p.copyTo(p, fgMaskPeg);
			for (int y = 0; y < src.rows; y++)
			{
				for (int x = 0; x < src.cols; x++)
				{
					if (fgMaskPeg.at<uchar>(Point(x, y)))
					{
						im1.at<Vec3b>(Point(x, y)) = src.at<Vec3b>(Point(x, y));
					}
					else
					{
						im1.at<Vec3b>(Point(x, y)) = Vec3b(0,0,0);
					}
				}
			}

			Mat mask = fgMaskPeg.clone();
			vector<Vec4i> hierarchy_ring;

			//imshow("Initial mask", initial_ring_mask);
			findContours(mask, pegsI, hierarchy_ring, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
			count = pegsI.size();



			cout << "count Pegs->" << count << endl;
			cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 0.5, 0.5, 0, 1, 8);
			putText(im1, message.c_str(), cvPoint(0, 60), CV_FONT_HERSHEY_SIMPLEX, .7, Scalar(255, 255, 0), 1);

			imshow(window_name.c_str(), im1);
			char key = cvWaitKey(40);
			if ((key == '\r' || key == '\n' || key == '\r\n'))
			{
				if (count == 12)
				{
					break;
				}
			}
			count = 0;
		} 
		cvReleaseImage(&img0);
		return slider_val;
	}
Ejemplo n.º 2
0
void close(int h,int w,int win){
	dilate(h,w,win);
	erode(h,w,win);
}
Ejemplo n.º 3
0
void open(int h,int w,int win){
	erode(h,w,win);
	dilate(h,w,win);

}
Ejemplo n.º 4
0
void OpenniFilter::cloud_cb_ (const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr &cloud)
{
    if (!viewer.wasStopped())
    {
        if (cloud->isOrganized())
        {
            // initialize all the Mats to store intermediate steps
            int cloudHeight = cloud->height;
            int cloudWidth = cloud->width;
            rgbFrame = Mat(cloudHeight, cloudWidth, CV_8UC3);
            drawing = Mat(cloudHeight, cloudWidth, CV_8UC3, NULL);
            grayFrame = Mat(cloudHeight, cloudWidth, CV_8UC1, NULL);
            hsvFrame = Mat(cloudHeight, cloudWidth, CV_8UC3, NULL);
            contourMask = Mat(cloudHeight, cloudWidth, CV_8UC1, NULL);

            if (!cloud->empty())
            {
                for (int h = 0; h < rgbFrame.rows; h ++)
                {
                    for (int w = 0; w < rgbFrame.cols; w++)
                    {
                        pcl::PointXYZRGBA point = cloud->at(w, cloudHeight-h-1);
                        Eigen::Vector3i rgb = point.getRGBVector3i();
                        rgbFrame.at<Vec3b>(h,w)[0] = rgb[2];
                        rgbFrame.at<Vec3b>(h,w)[1] = rgb[1];
                        rgbFrame.at<Vec3b>(h,w)[2] = rgb[0];
                    }
                }

                // do the filtering 
                int xPos = 0;
                int yPos = 0;
                mtx.lock();
                xPos = mouse_x;
                yPos = mouse_y;
                mtx.unlock();

                // color filtering based on what is chosen by users
                cvtColor(rgbFrame, hsvFrame, CV_RGB2HSV);
                Vec3b pixel = hsvFrame.at<Vec3b>(xPos,yPos);

                int hueLow = pixel[0] < iHueDev ? pixel[0] : pixel[0] - iHueDev;
                int hueHigh = pixel[0] > 255 - iHueDev ? pixel[0] : pixel[0] + iHueDev;
                // inRange(hsvFrame, Scalar(hueLow, pixel[1]-20, pixel[2]-20), Scalar(hueHigh, pixel[1]+20, pixel[2]+20), grayFrame);
                inRange(hsvFrame, Scalar(hueLow, iLowS, iLowV), Scalar(hueHigh, iHighS, iHighV), grayFrame);

                // removes small objects from the foreground by morphological opening
                erode(grayFrame, grayFrame, getStructuringElement(MORPH_ELLIPSE, Size(5,5)));
                dilate(grayFrame, grayFrame, getStructuringElement(MORPH_ELLIPSE, Size(5,5)));

                // morphological closing (removes small holes from the foreground)
                dilate(grayFrame, grayFrame, getStructuringElement(MORPH_ELLIPSE, Size(5,5)));
                erode(grayFrame, grayFrame, getStructuringElement(MORPH_ELLIPSE, Size(5,5)));

                // gets contour from the grayFrame and keeps the largest contour
                Mat cannyOutput;
                vector<vector<Point> > contours;
                vector<Vec4i> hierarchy;
                int thresh = 100;
                Canny(grayFrame, cannyOutput, thresh, thresh * 2, 3);
                findContours(cannyOutput, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
                int largestContourArea, largestContourIndex = 0;
                int defaultContourArea = 1000; // 1000 seems to work find in most cases... cannot prove this
                vector<vector<Point> > newContours;
                for (int i = 0; i < contours.size(); i++)
                {
                    double area = contourArea(contours[i], false);
                    if (area > defaultContourArea)
                        newContours.push_back(contours[i]);
                }

                // draws the largest contour: 
                drawing = Mat::zeros(cannyOutput.size(), CV_8UC3);
                for (int i = 0; i < newContours.size(); i++)
                    drawContours(drawing, newContours, i, Scalar(255, 255, 255), CV_FILLED, 8, hierarchy, 0, Point());

                // gets the filter by setting everything within the contour to be 1. 
                inRange(drawing, Scalar(1, 1, 1), Scalar(255, 255, 255), contourMask);

                // filters the point cloud based on contourMask
                // again go through the point cloud and filter out unnecessary points
                pcl::PointCloud<pcl::PointXYZRGBA>::Ptr resultCloud (new pcl::PointCloud<pcl::PointXYZRGBA>);
                pcl::PointXYZRGBA newPoint;
                for (int h = 0; h < contourMask.rows; h ++)
                {
                    for (int w = 0; w < contourMask.cols; w++)
                    {
                        if (contourMask.at<uchar>(h,w) > 0)
                        {
                            newPoint = cloud->at(w,h);
                            resultCloud->push_back(newPoint);
                        }
                    }
                }

                if (xPos == 0 && yPos == 0)
                    viewer.showCloud(cloud);
                else
                    viewer.showCloud(resultCloud);
                
                imshow("tracker", rgbFrame);
                imshow("filtered result", contourMask);
                char key = waitKey(1);
                if (key == 27) 
                {
                    interface->stop();
                    return;
                }
            }
            else
                cout << "Warning: Point Cloud is empty" << endl;
        }
        else
            cout << "Warning: Point Cloud is not organized" << endl;
    }
}
Ejemplo n.º 5
0
// display function should be good enough
void OpenRadar::DrawRadarData()
{
	int usualColor[15] = {16777215,255,128,65280,32768,
		      16711680,16711935,8421376,65535,32896 }; /*<usual color*/
	CvPoint pt1, pt2;

	cvZero(RadarImage);
	cvCircle(RadarImage, cvPoint(DisplayDx,DisplayDy),3, CV_RGB(0,255,255), -1, 8,0);
	int x,y;
	unsigned char * pPixel = 0;
	int colorIndex = 0, colorRGB;
	int R = 255, G = 0, B = 0;
    
	for (int i = 0; i < RadarDataCnt;i++)
	{  
		if (RadarRho[i] < 0)
		{
			
			//change color
			colorRGB = usualColor[colorIndex];
			R = colorRGB/65536;
			G = (colorRGB%65536)/256;
			B = colorRGB%256;
			colorIndex = (colorIndex + 1)%10;
			
		}
		else 
		{
			x = (int)(RadarRho[i]*cos(RadarTheta[i])/DisplayRatio) + DisplayDx;
			y = (int)(-RadarRho[i]*sin(RadarTheta[i])/DisplayRatio)+ DisplayDy;
	
			if (x >= 0 && x < RadarImageWdith && y >= 0 && y < RadarImageHeight)
			{
				pPixel = (unsigned char*)RadarImage->imageData + y*RadarImage->widthStep + 3*x;
				pPixel[0] = B;
				pPixel[1] = G;
				pPixel[2] = R;
			}
		}     
	}
	
	pt1.x = DisplayDx; pt1.y = DisplayDy;
	pt2.x = DisplayDx+line_length*v_scale*sin(v_angle + 0.5*M_PI); 
	pt2.y = DisplayDy+line_length*v_scale*cos(v_angle + 0.5*M_PI);
	cvLine(RadarImage, pt1, pt2, CV_RGB(255,255,255),2,8,0);

	pt2.x = DisplayDx+line_length*cos(-(-120 + skip_bin_idx * polarH_resolution)* M_PI/180 ); 	
	pt2.y = DisplayDy+line_length*sin(-(-120 + skip_bin_idx * polarH_resolution)* M_PI/180 ); 
	cvLine(RadarImage, pt1, pt2, CV_RGB(0,255,0),1,8,0);

	pt2.x = DisplayDx+line_length*cos(-(-120 + (polarH_length-skip_bin_idx) * polarH_resolution)* M_PI/180 ); 
	pt2.y = DisplayDy+line_length*sin(-(-120 + (polarH_length-skip_bin_idx) * polarH_resolution)* M_PI/180 ); 
	//pt2.x = DisplayDx+line_length*cos(0.25*M_PI); 
	//pt2.y = DisplayDy+line_length*sin(0.25*M_PI);
	//cout<< line_length <<endl; 
	//cout<< pt1.x <<" , " << pt1.y <<endl;
	//cout<< pt2.x <<" , " << pt2.y <<endl;
	cvLine(RadarImage, pt1, pt2, CV_RGB(0,255,0),1,8,0);

	float angle;
	int line_length2;
	for (int i=0; i<polarH_length;i++)
	{
		angle = (-30+i*polarH_resolution)*M_PI/180;
		line_length2 = H[i]/10;
		pt2.x = DisplayDx+line_length2*sin(angle); 
		pt2.y = DisplayDy+line_length2*cos(angle);
		cvCircle(RadarImage, pt2, 2, CV_RGB(255,255,255),1,8,0);
	}

	////////////////////////////////////////////////////////////////////////////////////
	// mine
	////////////////////////////////////////////////////////////////////////////////////
	Mat binImg = Mat::zeros(RadarImageHeight,RadarImageWdith,CV_8UC1);
	vector< Point> centerRaw;
	centerRaw.clear();
	for (int i = 0; i < RadarDataCnt;i++)
	{  
		if (RadarRho[i] > 200)
		{
			x = (int)(RadarRho[i]*cos(RadarTheta[i])/DisplayRatio) + DisplayDx;
			y = (int)(-RadarRho[i]*sin(RadarTheta[i])/DisplayRatio)+ DisplayDy;
			//centerRaw.push_back(Point(x,y));
			//cout<<"P:" <<centerRaw[i].x<<","<<centerRaw[i].y<<endl;
			if (x >= 0 && x < RadarImageWdith && y >= 0 && y < RadarImageHeight)
			{
				 circle( binImg,Point(x,y),1,Scalar(255),-1);
			}
		}     
	}
	imshow("binImg",binImg);
	Mat element = getStructuringElement(MORPH_RECT, Size(1,2));
	Mat element2 = getStructuringElement(MORPH_RECT, Size(10,10));
	erode(binImg, binImg, element);
	morphologyEx(binImg, binImg, MORPH_OPEN, element);
	dilate(binImg, binImg, element2);
	morphologyEx(binImg, binImg, MORPH_CLOSE, element2);
	imshow("dilate",binImg);

	vector< vector<Point> > contours;	
	vector< vector<Point> > filterContours;	
	vector< Vec4i > hierarchy;	
	vector< Point2f> center;
	vector< float > radius;
	vector<Point2f> realPoint;
	

	findContours(binImg, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
	center.resize(contours.size());
	radius.resize(contours.size());
	//realPoint.resize(contours.size());
	for(int i = 0; i< contours.size(); i++)
	{
		minEnclosingCircle(Mat(contours[i]),center[i],radius[i]);//对轮廓进行多变形逼近
		circle(binImg,center[i],650/DisplayRatio,Scalar(255),1); 
		//cout<<"No."<<i<<" | P: "<< center[i].x<<","<<center[i].y<<endl;
		float realX = (center[i].x - DisplayDx) * DisplayRatio;
		float realY = (center[i].y - DisplayDy) * DisplayRatio;

		realPoint.push_back(Point2f(realX,realY));
		//cout<<"No."<<i<<" | P: "<< realPoint[i].x<<","<<realPoint[i].y<<endl;
	}
	imshow("findContours",binImg);
	// colar map
	Mat mapImg = Mat::zeros(RadarImageHeight,RadarImageWdith,CV_8UC3);
	circle(mapImg, Point(DisplayDx,DisplayDy),3, CV_RGB(255,255,255),-1);
	line(mapImg, Point(DisplayDx,DisplayDy), Point(DisplayDx+40,DisplayDy), Scalar(0,0,255),1);
	line(mapImg, Point(DisplayDx,DisplayDy), Point(DisplayDx,DisplayDy+40), Scalar(0,255,0),1);
	for(int i = 0; i< center.size(); i++)
	{
		circle(mapImg,center[i],650/DisplayRatio,Scalar(255,255,0),1,CV_AA); 
		circle(mapImg,center[i],100/DisplayRatio,Scalar(0,255,255),-1); 
	}
	imshow("Map",mapImg);
	////////////////////////////////////
	ukftest::laserPoint msg;
	vector <float> xvec;
	vector <float> yvec;
	for(int i = 0 ; i < realPoint.size(); i++)
	{
		// cm
		xvec.push_back(realPoint[i].x/10.0f);
		yvec.push_back(realPoint[i].y/10.0f);
	}

	// msg
	msg.header.stamp = ros::Time::now();
	msg.header.frame_id = "hokuyo_laser";
	msg.x =xvec;
	msg.y =yvec;
	if(realPoint.size() >0) msg.isBlocking = 1;
	else msg.isBlocking = 0;
	pub_xy. publish(msg);
	
}
Ejemplo n.º 6
0
/* ------------------------------------------------------------------------------------------------------
   Creates a byte from the waveform

   0..255  new byte
   -1      continue
   -2      error
   -3      no more bytes
--------------------------------------------------------------------------------------------------------- */
int byte_decode(int restart, int new_file)
{
	static int t,t_active,t_byte;
	static int byte,n_bytes,c[6];
	int i,j,k,d[7],sampleval;
	double x;

	// t = number of samples read
	// t_byte = sample where byte starts
	// t_active is > 0 when a signal has been detected

	if(restart) {
		t = t_active = 0;
		update_progress(0.0);
		update_status("Attente du signal...");
	}

	// process next sample
	t++;
	sampleval = next_sample(new_file);
	
	if (sampleval == 40000) {
		return -3;
	}
	x = (double)sampleval / 32768.0;
	x = filter(x);
	x = dilate(x);
	x = median(x);
	x = make_decision(x,d);
	b_median(d);
	update_level(x);

	// print_deep_debug("t: %d, d6 %d, d5 %d, x %0.5f\n", t, d[6], d[5], x);
	// activation test
	if(d[6] && t_active == 0) {
		print_deep_debug(" - act - ");
		t_active = t;
		t_byte = 0;
		n_bytes = 0;
		update_status("Analyse du signal...");
	}
	if(t_active == 0) return -1;

	// deactivation test after a long period of inactivity
	if(t > t_active + 10000) {
		update_status("Désactivation pour cause d'inactivité");
		return -2;
	}

	// new byte?
	if(t_byte == 0 && d[5]) { // new byte
		print_deep_debug(" -- new byte -- ");
		t_active = t_byte = t;
		n_bytes++;
		byte = 0;
		for(i = 0;i < 6;i++)
			c[i] = 0;
	}

	// processing a byte?
	if(t_byte > 0) {
		j = (t - t_byte) / 88;  // bit number; the duration of a bit is very close to 2ms=88.2 samples
		if(j >= 10) { // end of the byte
			print_deep_debug(" [b = %d ] ", byte);
			if((byte & 1) == 0) { // first bit (lsb) must be a one
				print_debug("Bad byte start");
				return -2;
			}
			if(byte >= 512) { // last bit (msb) must be a zero
				print_debug("Bad byte finish");
				return -2;
			}
			byte >>= 1;
			t_byte = 0;
			if(n_bytes > 5) {
				return byte;
			}
			if(byte != 0xAA) { // bad synchronization byte
				print_debug("Bad synchronization byte.");
				return -2;
			}
			print_debug("Found good synchronization byte.");
			return -1; // discard synchronization byte
		}
Ejemplo n.º 7
0
Stitcher::Status Stitcher::composePanorama(InputArrayOfArrays images, OutputArray pano)
{
    CV_INSTRUMENT_REGION();

    LOGLN("Warping images (auxiliary)... ");

    std::vector<UMat> imgs;
    images.getUMatVector(imgs);
    if (!imgs.empty())
    {
        CV_Assert(imgs.size() == imgs_.size());

        UMat img;
        seam_est_imgs_.resize(imgs.size());

        for (size_t i = 0; i < imgs.size(); ++i)
        {
            imgs_[i] = imgs[i];
            resize(imgs[i], img, Size(), seam_scale_, seam_scale_, INTER_LINEAR_EXACT);
            seam_est_imgs_[i] = img.clone();
        }

        std::vector<UMat> seam_est_imgs_subset;
        std::vector<UMat> imgs_subset;

        for (size_t i = 0; i < indices_.size(); ++i)
        {
            imgs_subset.push_back(imgs_[indices_[i]]);
            seam_est_imgs_subset.push_back(seam_est_imgs_[indices_[i]]);
        }

        seam_est_imgs_ = seam_est_imgs_subset;
        imgs_ = imgs_subset;
    }

    UMat pano_;

#if ENABLE_LOG
    int64 t = getTickCount();
#endif

    std::vector<Point> corners(imgs_.size());
    std::vector<UMat> masks_warped(imgs_.size());
    std::vector<UMat> images_warped(imgs_.size());
    std::vector<Size> sizes(imgs_.size());
    std::vector<UMat> masks(imgs_.size());

    // Prepare image masks
    for (size_t i = 0; i < imgs_.size(); ++i)
    {
        masks[i].create(seam_est_imgs_[i].size(), CV_8U);
        masks[i].setTo(Scalar::all(255));
    }

    // Warp images and their masks
    Ptr<detail::RotationWarper> w = warper_->create(float(warped_image_scale_ * seam_work_aspect_));
    for (size_t i = 0; i < imgs_.size(); ++i)
    {
        Mat_<float> K;
        cameras_[i].K().convertTo(K, CV_32F);
        K(0,0) *= (float)seam_work_aspect_;
        K(0,2) *= (float)seam_work_aspect_;
        K(1,1) *= (float)seam_work_aspect_;
        K(1,2) *= (float)seam_work_aspect_;

        corners[i] = w->warp(seam_est_imgs_[i], K, cameras_[i].R, INTER_LINEAR, BORDER_REFLECT, images_warped[i]);
        sizes[i] = images_warped[i].size();

        w->warp(masks[i], K, cameras_[i].R, INTER_NEAREST, BORDER_CONSTANT, masks_warped[i]);
    }


    LOGLN("Warping images, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec");

    // Compensate exposure before finding seams
    exposure_comp_->feed(corners, images_warped, masks_warped);
    for (size_t i = 0; i < imgs_.size(); ++i)
        exposure_comp_->apply(int(i), corners[i], images_warped[i], masks_warped[i]);

    // Find seams
    std::vector<UMat> images_warped_f(imgs_.size());
    for (size_t i = 0; i < imgs_.size(); ++i)
        images_warped[i].convertTo(images_warped_f[i], CV_32F);
    seam_finder_->find(images_warped_f, corners, masks_warped);

    // Release unused memory
    seam_est_imgs_.clear();
    images_warped.clear();
    images_warped_f.clear();
    masks.clear();

    LOGLN("Compositing...");
#if ENABLE_LOG
    t = getTickCount();
#endif

    UMat img_warped, img_warped_s;
    UMat dilated_mask, seam_mask, mask, mask_warped;

    //double compose_seam_aspect = 1;
    double compose_work_aspect = 1;
    bool is_blender_prepared = false;

    double compose_scale = 1;
    bool is_compose_scale_set = false;

    std::vector<detail::CameraParams> cameras_scaled(cameras_);

    UMat full_img, img;
    for (size_t img_idx = 0; img_idx < imgs_.size(); ++img_idx)
    {
        LOGLN("Compositing image #" << indices_[img_idx] + 1);
#if ENABLE_LOG
        int64 compositing_t = getTickCount();
#endif

        // Read image and resize it if necessary
        full_img = imgs_[img_idx];
        if (!is_compose_scale_set)
        {
            if (compose_resol_ > 0)
                compose_scale = std::min(1.0, std::sqrt(compose_resol_ * 1e6 / full_img.size().area()));
            is_compose_scale_set = true;

            // Compute relative scales
            //compose_seam_aspect = compose_scale / seam_scale_;
            compose_work_aspect = compose_scale / work_scale_;

            // Update warped image scale
            float warp_scale = static_cast<float>(warped_image_scale_ * compose_work_aspect);
            w = warper_->create(warp_scale);

            // Update corners and sizes
            for (size_t i = 0; i < imgs_.size(); ++i)
            {
                // Update intrinsics
                cameras_scaled[i].ppx *= compose_work_aspect;
                cameras_scaled[i].ppy *= compose_work_aspect;
                cameras_scaled[i].focal *= compose_work_aspect;

                // Update corner and size
                Size sz = full_img_sizes_[i];
                if (std::abs(compose_scale - 1) > 1e-1)
                {
                    sz.width = cvRound(full_img_sizes_[i].width * compose_scale);
                    sz.height = cvRound(full_img_sizes_[i].height * compose_scale);
                }

                Mat K;
                cameras_scaled[i].K().convertTo(K, CV_32F);
                Rect roi = w->warpRoi(sz, K, cameras_scaled[i].R);
                corners[i] = roi.tl();
                sizes[i] = roi.size();
            }
        }
        if (std::abs(compose_scale - 1) > 1e-1)
        {
#if ENABLE_LOG
            int64 resize_t = getTickCount();
#endif
            resize(full_img, img, Size(), compose_scale, compose_scale, INTER_LINEAR_EXACT);
            LOGLN("  resize time: " << ((getTickCount() - resize_t) / getTickFrequency()) << " sec");
        }
        else
            img = full_img;
        full_img.release();
        Size img_size = img.size();

        LOGLN(" after resize time: " << ((getTickCount() - compositing_t) / getTickFrequency()) << " sec");

        Mat K;
        cameras_scaled[img_idx].K().convertTo(K, CV_32F);

#if ENABLE_LOG
        int64 pt = getTickCount();
#endif
        // Warp the current image
        w->warp(img, K, cameras_[img_idx].R, INTER_LINEAR, BORDER_REFLECT, img_warped);
        LOGLN(" warp the current image: " << ((getTickCount() - pt) / getTickFrequency()) << " sec");
#if ENABLE_LOG
        pt = getTickCount();
#endif

        // Warp the current image mask
        mask.create(img_size, CV_8U);
        mask.setTo(Scalar::all(255));
        w->warp(mask, K, cameras_[img_idx].R, INTER_NEAREST, BORDER_CONSTANT, mask_warped);
        LOGLN(" warp the current image mask: " << ((getTickCount() - pt) / getTickFrequency()) << " sec");
#if ENABLE_LOG
        pt = getTickCount();
#endif

        // Compensate exposure
        exposure_comp_->apply((int)img_idx, corners[img_idx], img_warped, mask_warped);
        LOGLN(" compensate exposure: " << ((getTickCount() - pt) / getTickFrequency()) << " sec");
#if ENABLE_LOG
        pt = getTickCount();
#endif

        img_warped.convertTo(img_warped_s, CV_16S);
        img_warped.release();
        img.release();
        mask.release();

        // Make sure seam mask has proper size
        dilate(masks_warped[img_idx], dilated_mask, Mat());
        resize(dilated_mask, seam_mask, mask_warped.size(), 0, 0, INTER_LINEAR_EXACT);

        bitwise_and(seam_mask, mask_warped, mask_warped);

        LOGLN(" other: " << ((getTickCount() - pt) / getTickFrequency()) << " sec");
#if ENABLE_LOG
        pt = getTickCount();
#endif

        if (!is_blender_prepared)
        {
            blender_->prepare(corners, sizes);
            is_blender_prepared = true;
        }

        LOGLN(" other2: " << ((getTickCount() - pt) / getTickFrequency()) << " sec");

        LOGLN(" feed...");
#if ENABLE_LOG
        int64 feed_t = getTickCount();
#endif
        // Blend the current image
        blender_->feed(img_warped_s, mask_warped, corners[img_idx]);
        LOGLN(" feed time: " << ((getTickCount() - feed_t) / getTickFrequency()) << " sec");
        LOGLN("Compositing ## time: " << ((getTickCount() - compositing_t) / getTickFrequency()) << " sec");
    }

#if ENABLE_LOG
        int64 blend_t = getTickCount();
#endif
    UMat result, result_mask;
    blender_->blend(result, result_mask);
    LOGLN("blend time: " << ((getTickCount() - blend_t) / getTickFrequency()) << " sec");

    LOGLN("Compositing, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec");

    // Preliminary result is in CV_16SC3 format, but all values are in [0,255] range,
    // so convert it to avoid user confusing
    result.convertTo(pano, CV_8U);

    return OK;
}
Ejemplo n.º 8
0
Result CalSpermCount::calNum(Mat img)
{
	Mat tmp, tmp_back;
//	int col = 800, row = 600;
	Size dsize = Size(nshowcol, nshowrow);
	Mat image2show = Mat(dsize,CV_8U);

	GaussianBlur(img,img,cv::Size(5,5), 1.5);

	if(nShowMidRst)
	    ShowImage("after filtering", img);
	//cvSmooth(img, img, CV_MEDIAN, 3, 0, 0, 0); //中值滤波,消除小的噪声;

	//Mat element(9,9,CV_8U,Scalar(1));
	Mat element = getStructuringElement(MORPH_RECT,Size(10,10));
	erode(img, tmp,element);
    //ShowImage("erode",tmp);

	dilate(tmp,tmp_back,element);
	::resize(tmp_back, image2show,dsize);
	//cvNamedWindow("dilate");
	//imshow("dilate", image2show);
	//ShowImage("dilate",tmp_back);

	morphologyEx(img,dst_gray,MORPH_TOPHAT,element);
	//morphologyEx(img,dst_gray,MORPH_BLACKHAT,cv::Mat());
	//dst_gray = img;

	//绘制直方图
	Histgram1D hist;
	hist.stretch(dst_gray,0.01f);
	if(nShowMidRst)
	    ShowImage("Histogram", hist.getHistogramImage(dst_gray, 1));
	Mat tmpImage;

	//::equalizeHist(dst_gray,tmpImage);
	//ShowImage("拉伸后", tmpImage);
	//ShowImage("拉伸后Histogram",  hist.getHistogramImage(tmpImage, 1));

    if(nShowMidRst)
   {
		ShowImage("Picture EQ", hist.stretch(dst_gray, 50));
	    ShowImage("after draw, Histogram",  hist.getHistogramImage(hist.stretch(dst_gray,50), 1));
	}

	dst_gray =  hist.stretch(dst_gray, 50);
	//dst_gray =  ::equalizeHist(dst_gray,dst_gray);


	//dst_gray = tmp_back  - img  ;
	//dst_gray = img  ;
	::resize(dst_gray, image2show,dsize);
#if 0 // No GUI
	if(nShowMidRst)
	    cvNamedWindow(WINDOWNAME);

	::createTrackbar("filter pattern",WINDOWNAME,&g_nThresholdType,4,on_Theshold);
	createTrackbar("theshold value",WINDOWNAME,&g_nThresholdValue,255,on_Theshold);
#endif
	//初始化自定义回调函数
	on_Theshold(0,0);

	//adaptiveThreshold(dst_gray,dstimgbw,255,adaptive_method,CV_THRESH_BINARY,blocksize,0);
    //cvAdaptiveThreshold(img, dst_bw,255,adaptive_method,//自适应阀值,blocksize为奇数
    // CV_THRESH_BINARY,blocksize,offset);


//	::resize(dstimgbw, image2show,dsize);
//	cvNamedWindow("src2");
//	imshow("src2", image2show);
//		waitKey(0);

	vector<vector<Point> > contours;

	findContours(dstimgbw,contours,CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);

	Mat rst(img.size(),CV_8U,Scalar(0));
	drawContours(rst,contours,-1,255,1);

	int cmin = minArea;
	int cmax = maxArea;
	vector<vector<Point> >::iterator itc = contours.begin();
	int i = 0;
	result.LittleNum = 0;
	result.AimNum = 0;
	result.LargeNum = 0;
	fallcount = contours.size();
	while(itc!=contours.end())
	{

		if(itc->size() < cmin )
		{
			result.LittleNum ++;
			itc = contours.erase(itc);
			//i++;
		}
		else if(itc->size() > cmax)
		{
			itc = contours.erase(itc);
			result.LargeNum ++;
		}
		else
		{
			result.AimNum ++;
		    cout <<i<<" = "<< itc->size()<<endl;
			i++;
			++itc;
		}
	}

	Mat rst2(img.size(),CV_8UC3,Scalar(0,0,0));
	drawContours(rst2,contours,-1,cv::Scalar(255,255,255),1);

	char sz1[MAX_PATH],sz2[MAX_PATH],sz3[MAX_PATH];
	char sz4[MAX_PATH];
	char szError[MAX_PATH] = " ";

	fcount = fratio * result.AimNum;


	if(result.LittleNum/fallcount > fminRatio  || result.LargeNum/fallcount > fmaxRatio)
			sprintf(szError,"Sample is dirty");

	sprintf(sz1,"Aim Num = %d",   result.AimNum);
	sprintf(sz2,"Little Num=%d",  result.LittleNum);
	sprintf(sz3,"Large Num=%d",   result.LargeNum);
	sprintf(sz4,"Count =%3.3f",   fcount);

	putText(rst2,sz1,cv::Point(10,10),cv::FONT_HERSHEY_PLAIN, 1.0,   cv::Scalar(255,0,0),     2);
	putText(rst2,sz2,cv::Point(10,30),cv::FONT_HERSHEY_PLAIN, 1.0,   cv::Scalar(255,0,0),     2);
	putText(rst2,sz3,cv::Point(10,50),cv::FONT_HERSHEY_PLAIN, 1.0,   cv::Scalar(255,0,0),     2);
	putText(rst2,sz4,cv::Point(10,70),cv::FONT_HERSHEY_PLAIN, 1.0,   cv::Scalar(255,0,255),     2);
	putText(rst2,szError,cv::Point(10,90),cv::FONT_HERSHEY_PLAIN, 1.0,   cv::Scalar(0,0,255),     2);

	cout << "Aim Num = "<<result.AimNum<<endl;
	cout << "Little Num = "<<result.LittleNum<<endl;
	cout << "Large Num = "<<result.LargeNum<<endl;
	cout << "Count = "<<fcount<<endl;
	cout << "all = "<<contours.size()<<endl;

	ShowImage("result",rst2);

	//waitKey(0);
	return result;
}
Ejemplo n.º 9
0
void KinectController::updateAnalisys(ofxKinect & kinect, float bbX, float bbY, float bbZ, float bbW, float bbH, float bbD){

	if(kinect.isFrameNew()){
		static int counter = 0;
		int w = 640;
		int h = 480;

#if ANGLE_FROM_ACCEL
		//ofVec3f worldOffset(worldX,worldY,worldZ);
		ofMatrix4x4 m = camTransform.getModelViewMatrix();
		int i = 0;
		for(int y = 0; y < h; y +=step) {
			for(int x = 0; x < w; x +=step) {
				const short & distance = kinect.getRawDepthPixelsRef()[x+y*w];
				//if(distance > 0) {
					const ofVec3f  & v = kinect.getWorldCoordinateAt(x, y, distance);
					/*if(correctAngle){
						v = v*m;
					}
					if(!applyBB || insideBB3D(v,ofVec3f(bbX,bbY,bbZ), ofVec3f(bbW, bbH, bbD))){*/
						mesh.getVertices()[i] = v;
					/*}else{
						mesh.getVertices()[i].set(0,0,0);
					}*/
				//}
				i++;
			}
		}
#elif ANGLE_FROM_PCL_GROUND_PLANE
		pcl::PointCloud<pcl::PointXYZ>::Ptr pcPtr = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
		for(int y = 0; y < h; y += step) {
			for(int x = 0; x < w; x += step) {
				//if(kinect.getDistanceAt(x, y) > 0) {
					float z = kinect.getDistanceAt(x, y);
					pcPtr->push_back(pcl::PointXYZ(x,y,z));
				//}
			}
		}
		pcPtr->width=640;
		pcPtr->height=480;

		pcl::ModelCoefficients::Ptr planeCoeffs = fitPlane<pcl::PointXYZ>(pcPtr,10,5);
		plane.set(planeCoeffs->values[0],planeCoeffs->values[1],planeCoeffs->values[2],planeCoeffs->values[3]);

		for(int i=0;i<pcPtr->points.size();i++){
			ofVec3f v(pcPtr->points[i].x,pcPtr->points[i].y,pcPtr->points[i].z);
			if(plane.distanceToPoint(v)>60)
				mesh.addVertex( kinect.getWorldCoordinateAt(v.x, v.y, v.z) );
		}

		//pcPtr = findAndSubtractPlane<pcl::PointXYZ>(pcPtr,60,5);
		//ofxPCL::toOf(pcPtr,mesh,1,1,1);
#elif CV_ANALISYS
		cv::Mat backgroundMat = toCv(background);
		if(captureBg>0){
			backgroundMat += toCv(kinect.getDistancePixelsRef());
			captureBg--;
		}else if(captureBg==0){
			backgroundMat /= 10;
			cv::GaussianBlur(backgroundMat,backgroundMat,Size(11,11),10);
			captureBg=-1;
		}else{
			// difference threshold
			cv::Mat diffMat = toCv(diff);
			cv::Mat currentMat = toCv(kinect.getDistancePixelsRef());
			cv::Mat gaussCurrentMat = toCv(gaussCurrent);
			cv::GaussianBlur(currentMat,gaussCurrentMat,Size(11,11),10);
			cv::absdiff(backgroundMat, gaussCurrentMat, diffMat);
			//diffMat = toCv(background) - toCv(kinect.getDistancePixelsRef());
			threshold(diff,thresPix,.001);
			thres8Bit = thresPix;

			cv::Mat kernel;
			cv::Mat thresMat = toCv(thres8Bit);
			cv::Point anchor(-1,-1);
			erode(toCv(thres8Bit),thresMat,kernel,anchor,10);

			dilate(toCv(thres8Bit),thresMat,kernel,anchor,5);


			cv::Mat fgMat = toCv(fg);
			bgSubstractor(toCv(thres8Bit),fgMat);
			contourFinder.findContours(fg);

			for(int i=0;i<oscContours.size();i++){
				oscContours[i]->newFrame(frame);
			}


			polylines = contourFinder.getPolylines();
			for(int i=0;i<(int)polylines.size();i++){
				ofPoint centroid = polylines[i].getCentroid2D();
				polylines[i] = polylines[i].getResampledByCount(16);
				float z = kinect.getDistanceAt(centroid);
				for(int j=0;j<oscContours.size();j++){
					oscContours[j]->sendBlob(polylines[i],z);
				}
			}
			frame++;

			if(recording){

				//convertColor(kinect.getDepthPixelsRef(),rgbDepth,CV_GRAY2RGB);
				recorder.addFrame(kinect.getRawDepthPixelsRef());
			}
		}
#endif
	}
}
Ejemplo n.º 10
0
void camera_contours_display(int num, Straightener & straight) {
	int c;
		IplImage* color_img;
		CvCapture* cv_cap = cvCaptureFromCAM(num);
		cvNamedWindow("Video", 0); // create window
		resizeWindow("Video", 700,700);
		for(;;) {
			color_img = cvQueryFrame(cv_cap); // get frame
			if(color_img != 0) {
				Mat cam_mat(color_img);
				Mat result;
				cam_mat.copyTo(result);

				if(straight.doAll(cam_mat, result)) {
					///Apply blur
					blur(result, result, Size(3,3));
					///Apply Canny to destination Matrix
					Canny(result, result, 50, 50, 3);
					/// Vectors for storing contours
					vector<vector<Point> > contours; //contours of the paper sheet
					vector<vector<Point> > approx_contours; //approx contours of the paper sheet
					vector<Vec4i> hierarchy;
					int erosion_type = 2;
					int erosion_size = 3;
					Mat element = getStructuringElement(erosion_type,
														Size( 2*erosion_size + 1, 2*erosion_size+1),
														Point( erosion_size, erosion_size));
					dilate(result, result, element);
					/// Cut 20 px from each side to avoid paper borders detection
					result = result(Rect(10, 10, result.cols-20, result.rows-20));
					findContours(result, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, Point(0, 0));
					/// Draw contours
					Mat drawing = Mat::zeros( result.size(), CV_8UC3 );
					/// https://github.com/Itseez/opencv/blob/master/samples/cpp/contours2.cpp
//					approx_contours.resize(contours.size());
					for(unsigned int i = 0; i < contours.size(); i++) {
						/// Area of more than 20 and no parent
						if(contourArea(contours[i]) > 20 && hierarchy[i][3] == -1) {
							vector<Point> tmp_contour;
							approxPolyDP(Mat(contours[i]), tmp_contour, 3, true);
							approx_contours.push_back(tmp_contour);
						}
					}
					for(unsigned int i=0; i < approx_contours.size(); i++) {
						Scalar color;
						if(approx_contours[i].size() == 4) {
							color = Scalar( 255, 255, 255);
							drawContours( drawing, approx_contours, i, color, 1, 8, NULL, 0, Point() );
						}
						else {
							color = Scalar( 0, 255, 0);
							drawContours( drawing, approx_contours, i, color, 1, 8, NULL, 0, Point() );
						}
					}
					imshow("Video", drawing);
				}
			}
			c = cvWaitKey(10); // wait 10 ms or for key stroke
			if(c == 27)

				break; // if ESC, break and quit
		}
		/* clean up */
		cvReleaseCapture( &cv_cap );
		cvDestroyWindow("Video");
}
Ejemplo n.º 11
0
void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners,
                              int maxCorners, double qualityLevel, double minDistance,
                              InputArray _mask, int blockSize,
                              bool useHarrisDetector, double harrisK )
{
    Mat image = _image.getMat(), mask = _mask.getMat();
    
    CV_Assert( qualityLevel > 0 && minDistance >= 0 && maxCorners >= 0 );
    CV_Assert( mask.empty() || (mask.type() == CV_8UC1 && mask.size() == image.size()) );

    Mat eig, tmp;
    if( useHarrisDetector )
        cornerHarris( image, eig, blockSize, 3, harrisK );
    else
        cornerMinEigenVal( image, eig, blockSize, 3 );

    double maxVal = 0;
    minMaxLoc( eig, 0, &maxVal, 0, 0, mask );
    threshold( eig, eig, maxVal*qualityLevel, 0, THRESH_TOZERO );
    dilate( eig, tmp, Mat());

    Size imgsize = image.size();

    vector<const float*> tmpCorners;

    // collect list of pointers to features - put them into temporary image
    for( int y = 1; y < imgsize.height - 1; y++ )
    {
        const float* eig_data = (const float*)eig.ptr(y);
        const float* tmp_data = (const float*)tmp.ptr(y);
        const uchar* mask_data = mask.data ? mask.ptr(y) : 0;

        for( int x = 1; x < imgsize.width - 1; x++ )
        {
            float val = eig_data[x];
            if( val != 0 && val == tmp_data[x] && (!mask_data || mask_data[x]) )
                tmpCorners.push_back(eig_data + x);
        }
    }

    sort( tmpCorners, greaterThanPtr<float>() );
    vector<Point2f> corners;
    size_t i, j, total = tmpCorners.size(), ncorners = 0;

    if(minDistance >= 1)
    {
         // Partition the image into larger grids
        int w = image.cols;
        int h = image.rows;

        const int cell_size = cvRound(minDistance);
        const int grid_width = (w + cell_size - 1) / cell_size;
        const int grid_height = (h + cell_size - 1) / cell_size;

        std::vector<std::vector<Point2f> > grid(grid_width*grid_height);

        minDistance *= minDistance;

        for( i = 0; i < total; i++ )
        {
            int ofs = (int)((const uchar*)tmpCorners[i] - eig.data);
            int y = (int)(ofs / eig.step);
            int x = (int)((ofs - y*eig.step)/sizeof(float));

	        bool good = true;

            int x_cell = x / cell_size;
            int y_cell = y / cell_size;

            int x1 = x_cell - 1;
            int y1 = y_cell - 1;
            int x2 = x_cell + 1;
            int y2 = y_cell + 1;

            // boundary check
            x1 = std::max(0, x1);
            y1 = std::max(0, y1);
            x2 = std::min(grid_width-1, x2);
            y2 = std::min(grid_height-1, y2);

            for( int yy = y1; yy <= y2; yy++ )
            {
                for( int xx = x1; xx <= x2; xx++ )
                {   
                    vector <Point2f> &m = grid[yy*grid_width + xx];

                    if( m.size() )
                    {
                        for(j = 0; j < m.size(); j++)
                        {
                            float dx = x - m[j].x;
                            float dy = y - m[j].y;

                            if( dx*dx + dy*dy < minDistance )
                            {
                                good = false;
                                goto break_out;
                            }
                        }
                    }                
                }
            }

            break_out:

            if(good)
            {
                // printf("%d: %d %d -> %d %d, %d, %d -- %d %d %d %d, %d %d, c=%d\n",
                //    i,x, y, x_cell, y_cell, (int)minDistance, cell_size,x1,y1,x2,y2, grid_width,grid_height,c);
                grid[y_cell*grid_width + x_cell].push_back(Point2f((float)x, (float)y));

                corners.push_back(Point2f((float)x, (float)y));
                ++ncorners;

                if( maxCorners > 0 && (int)ncorners == maxCorners )
                    break;
            }
        }
    }
    else
    {
        for( i = 0; i < total; i++ )
        {
            int ofs = (int)((const uchar*)tmpCorners[i] - eig.data);
            int y = (int)(ofs / eig.step);
            int x = (int)((ofs - y*eig.step)/sizeof(float));

            corners.push_back(Point2f((float)x, (float)y));
            ++ncorners;
            if( maxCorners > 0 && (int)ncorners == maxCorners )
                break;
        }
    }
    
    Mat(corners).convertTo(_corners, _corners.fixedType() ? _corners.type() : CV_32F);

    /*
    for( i = 0; i < total; i++ )
    {
        int ofs = (int)((const uchar*)tmpCorners[i] - eig.data);
        int y = (int)(ofs / eig.step);
        int x = (int)((ofs - y*eig.step)/sizeof(float));

        if( minDistance > 0 )
        {
            for( j = 0; j < ncorners; j++ )
            {
                float dx = x - corners[j].x;
                float dy = y - corners[j].y;
                if( dx*dx + dy*dy < minDistance )
                    break;
            }
            if( j < ncorners )
                continue;
        }

        corners.push_back(Point2f((float)x, (float)y));
        ++ncorners;
        if( maxCorners > 0 && (int)ncorners == maxCorners )
            break;
    }
*/
}
Ejemplo n.º 12
0
vector<Point2f> find_corners(Mat &src, unsigned int rows, unsigned int cols) {
	vector<cv::Vec4i> slines;
	vector<par_line> par_lines;
	vector<par_line> borders;
	bool new_corners = false;
	vector<Point2f> corners;
	vector<Point2f> quad_pts;

	Mat temp;
	blur(src, temp, Size(5,5));
	Canny(temp, temp, 100, 100, 3);
	int erosion_type = 1;
	int erosion_size = 1;
	Mat element = getStructuringElement( erosion_type,
										   Size( 2*erosion_size + 1, 2*erosion_size+1 ),
										   Point( erosion_size, erosion_size ) );
	dilate(temp, temp, element);
	HoughLinesP(temp, slines, 1, CV_PI/360, 120,100, 10);

	if ( slines.size() < 4 ) {
		///cout << "Hough: Znaleziono mniej niż 4 linie.";
		new_corners = false;
	}
	else {
		for( unsigned int i = 0; i < slines.size(); i++ ) {
			Vec4i l = slines[i];
			par_line tmp_line;
			/// Pionowa linia - b na dużą wartość
			if( abs(l[2]-l[0]) == 0 ){
				// znak (chyba) OK
				tmp_line.b = -(l[3]-l[1])/abs(l[3]-l[1])*1.e15;
			}
			else {
				tmp_line.b = l[1] - (double)(l[3]-l[1])/((double)(l[2]-l[0]))*l[0];
			}
			tmp_line.atana = atan2((double)(l[3]-l[1]),((double)(l[2]-l[0])));
			tmp_line.len = sqrt(pow( (double)(l[0]-l[2]), 2.0 ) + pow( (double)(l[1]-l[3]), 2.0 ));
			par_lines.push_back(tmp_line);
		}

		/// Uśrednione linie będące krawędziami kartki
		/// Dla każdej linii znajdź taką, która mieści się w zakresie +- 10 stopni
		/// Pierwsza linia trafia od razu
		borders.push_back(par_lines[0]);
		for( unsigned int i = 1; i < par_lines.size(); i++ ) {
			bool found_similiar = false;
			for ( unsigned int j = 0; j < borders.size(); j++ ) {
				/// Nowy odcinek podobny do któregoś z istniejących
				if ( abs(abs(par_lines[i].atana) - abs(borders[j].atana)) < 10.0*3.14159/180.0
					&& abs(par_lines[i].b - borders[j].b) < 150.0 ) {
					/// Nowa wartość jako średnia ważona
					borders[j].atana = (borders[j].atana*borders[j].len
										   + par_lines[i].atana*par_lines[i].len)
										   / (borders[j].len + par_lines[i].len);
					borders[j].b = (borders[j].b*borders[j].len
														   + par_lines[i].b*par_lines[i].len)
														   / (borders[j].len + par_lines[i].len);
					/// Zapisz nową długość uśrednionej prostej
					borders[j].len = borders[j].len + par_lines[i].len;
					found_similiar = true;
				}
			}
			/// Jeżeli żaden element nie był podobny, dodaj nową krawędź
			if ( !found_similiar ) {
				borders.push_back(par_lines[i]);
			}
		}
		if ( borders.size() < 4 ) {
			///cout << "Zbudowano mniej niż 3 boki obwiedni.";
			new_corners = false;
		}
		else {
			// usuwanie najkrótszych linii
			while(borders.size() > 4) {
				unsigned char i = 0;
				double minlen = 1.e30; // nieskończoność
				for(unsigned char j = 0; j < borders.size(); j++) {
					if(borders[i].len > borders[j].len) {
						i = j;
						minlen = borders[j].len;
					}
				}
				borders.erase(borders.begin()+i);
			}
			/// Znajdź narożniki
			for (unsigned int i = 0; i < borders.size(); i++){
				for (unsigned int j = i+1; j < borders.size(); j++){
					/// Znajdź przecięcie między nierównoległymi do siebie brzegami kartki
					if( abs(abs(borders[i].atana)-abs(borders[j].atana)) > 45.0*3.14159/180.0 ) {
						Point2f p;
						p.x = (borders[i].b - borders[j].b) /
								((tan(borders[j].atana) - tan(borders[i].atana)));
						p.y = p.x * tan(borders[i].atana) + borders[i].b;
						corners.push_back(p);
					}
				}
			}
			if ( corners.size() < 4 ) {
				new_corners = false;
			}
			else {
				/// Oblicz środek masy
				Point2f center(0,0);
				for ( unsigned int i = 0; i < corners.size(); i++ ) {
					center += corners[i];
				}
				center *= (1. / corners.size());
				/// Posortuj narożniki
				sortCorners(corners, center);
				new_corners = true;
			}
		}
	}
	/// Jeżeli to pierwszy przebieg, skopiuj narożniki
	if( corners_old.size() == 0 ) {
		corners_old = corners;
	}
	/// Jeżeli są nowe narożniki
	if( new_corners ) {
		/// Co 20 klatkę odświeżaj narożniki, aby uniknąć przekrzywienia po obrocie i powrocie
		if( refresh_corners > 20 ){
			corners_old = corners;
			refresh_corners = 0;
		}
		else {
			refresh_corners += 1;
			bool close_corner_found [4];
			for( int i = 0; i < 4; i++ ) {
				close_corner_found[i] = false;
				Point2f c = corners_old[i];
				for( int j = 0; j < 4; j++ ) {
					Point2f k = corners[j];
					if( abs(k.y - c.y) < 100 && abs(k.x - c.x) < 100 ) {
						close_corner_found[i] = true;
					}
				}
			}
			if ( close_corner_found[0] && close_corner_found[1] && close_corner_found[2] && close_corner_found[3] ) {
				corners_old = corners;
			}
		}
	}
	if( corners_old.size() == 4 ) {
		return corners_old;
	}
	else {
		vector<Point2f> empty;
		empty.clear();
		return empty;
	}
}
Ejemplo n.º 13
0
int main(int argc, char ** argv) {

    acc_init(acc_device_cuda);
    acc_set_device_num(0, acc_device_cuda);
	// Keep track of the start time of the program
  	long long program_start_time = get_time();
	
	// Let the user specify the number of frames to process
	int num_frames = 1;
	
	if (argc != 3){
		fprintf(stderr, "usage: %s <input file> <num of frames>", argv[0]);
		exit(1);
	}
	
	num_frames = atoi(argv[2]);
	// Open video file
	char *video_file_name;
	video_file_name = argv[1];
	
	avi_t *cell_file = AVI_open_input_file(video_file_name, 1);
	if (cell_file == NULL)	{
		AVI_print_error("Error with AVI_open_input_file");
		return -1;
	}
	
	int i, j, *crow, *ccol, pair_counter = 0, x_result_len = 0, Iter = 20, ns = 4, k_count = 0, n;
	MAT *cellx, *celly, *A;
	double *GICOV_spots, *t, *G, *x_result, *y_result, *V, *QAX_CENTERS, *QAY_CENTERS;
	double threshold = 1.8, radius = 10.0, delta = 3.0, dt = 0.01, b = 5.0;
	
	// Extract a cropped version of the first frame from the video file
	MAT *image_chopped = get_frame(cell_file, 0, 1, 0);
	printf("Detecting cells in frame 0\n");
	
	// Get gradient matrices in x and y directions
	MAT *grad_x = gradient_x(image_chopped);
	MAT *grad_y = gradient_y(image_chopped);
	
	m_free(image_chopped);
	
	// Get GICOV matrix corresponding to image gradients

	long long GICOV_start_time = get_time();
	
	/*
	MAT *gicov = ellipsematching(grad_x, grad_y);
	
	// Square GICOV values
	MAT *max_gicov = m_get(gicov->m, gicov->n);
	for (i = 0; i < gicov->m; i++) {
		for (j = 0; j < gicov->n; j++) {
			double val = m_get_val(gicov, i, j);
			m_set_val(max_gicov, i, j, val * val);
		}
	}
	*/
	MAT *gicov = GICOV(grad_x, grad_y);		

	long long GICOV_end_time = get_time();
	
	// Dilate the GICOV matrix
	long long dilate_start_time = get_time();
	//MAT *strel = structuring_element_f(12);
	//MAT *img_dilated = dilate_f(gicov, strel);
	MAT *img_dilated = dilate(gicov);

	long long dilate_end_time = get_time();
	
	// Find possible matches for cell centers based on GICOV and record the rows/columns in which they are found
	pair_counter = 0;
	crow = (int *) malloc(gicov->m * gicov->n * sizeof(int));
	ccol = (int *) malloc(gicov->m * gicov->n * sizeof(int));
	for (i = 0; i < gicov->m; i++) {
		for (j = 0; j < gicov->n; j++) {
			if (!(m_get_val(gicov,i,j) == 0.0) && (m_get_val(img_dilated,i,j) == m_get_val(gicov,i,j))) {
				crow[pair_counter] = i;
				ccol[pair_counter] = j;
				pair_counter++;
			}
		}
	}

	
	GICOV_spots = (double *) malloc(sizeof(double)*pair_counter);
	for (i = 0; i < pair_counter; i++)
		GICOV_spots[i] = sqrt(m_get_val(gicov, crow[i], ccol[i]));
	
	G = (double *) calloc(pair_counter, sizeof(double));
	x_result = (double *) calloc(pair_counter, sizeof(double));
	y_result = (double *) calloc(pair_counter, sizeof(double));
	
	x_result_len = 0;
	for (i = 0; i < pair_counter; i++) {
		if ((crow[i] > 29) && (crow[i] < BOTTOM - TOP + 39)) {
			x_result[x_result_len] = ccol[i];
			y_result[x_result_len] = crow[i] - 40;
			G[x_result_len] = GICOV_spots[i];
			x_result_len++;
		}
	}
	
	// Make an array t which holds each "time step" for the possible cells
	t = (double *) malloc(sizeof(double) * 36);
	for (i = 0; i < 36; i++) {
		t[i] = (double)i * 2.0 * PI / 36.0;
	}
	
	// Store cell boundaries (as simple circles) for all cells
	cellx = m_get(x_result_len, 36);
	celly = m_get(x_result_len, 36);
	for(i = 0; i < x_result_len; i++) {
		for(j = 0; j < 36; j++) {
			m_set_val(cellx, i, j, x_result[i] + radius * cos(t[j]));
			m_set_val(celly, i, j, y_result[i] + radius * sin(t[j]));
		}
	}
	
	A = TMatrix(9,4);

	
	V = (double *) malloc(sizeof(double) * pair_counter);
	QAX_CENTERS = (double * )malloc(sizeof(double) * pair_counter);
	QAY_CENTERS = (double *) malloc(sizeof(double) * pair_counter);
	memset(V, 0, sizeof(double) * pair_counter);
	memset(QAX_CENTERS, 0, sizeof(double) * pair_counter);
	memset(QAY_CENTERS, 0, sizeof(double) * pair_counter);

	// For all possible results, find the ones that are feasibly leukocytes and store their centers
	k_count = 0;
	for (n = 0; n < x_result_len; n++) {
		if ((G[n] < -1 * threshold) || G[n] > threshold) {
			MAT * x, *y;
			VEC * x_row, * y_row;
			x = m_get(1, 36);
			y = m_get(1, 36);

			x_row = v_get(36);
			y_row = v_get(36);

			// Get current values of possible cells from cellx/celly matrices
			x_row = get_row(cellx, n, x_row);
			y_row = get_row(celly, n, y_row);
			uniformseg(x_row, y_row, x, y);

			// Make sure that the possible leukocytes are not too close to the edge of the frame
			if ((m_min(x) > b) && (m_min(y) > b) && (m_max(x) < cell_file->width - b) && (m_max(y) < cell_file->height - b)) {
				MAT * Cx, * Cy, *Cy_temp, * Ix1, * Iy1;
				VEC  *Xs, *Ys, *W, *Nx, *Ny, *X, *Y;
				Cx = m_get(1, 36);
				Cy = m_get(1, 36);
				Cx = mmtr_mlt(A, x, Cx);
				Cy = mmtr_mlt(A, y, Cy);
				
				Cy_temp = m_get(Cy->m, Cy->n);
				
				for (i = 0; i < 9; i++)
					m_set_val(Cy, i, 0, m_get_val(Cy, i, 0) + 40.0);
					
				// Iteratively refine the snake/spline
				for (i = 0; i < Iter; i++) {
					int typeofcell;
					
					if(G[n] > 0.0) typeofcell = 0;
					else typeofcell = 1;
					
					splineenergyform01(Cx, Cy, grad_x, grad_y, ns, delta, 2.0 * dt, typeofcell);
				}
				
				X = getsampling(Cx, ns);
				for (i = 0; i < Cy->m; i++)
					m_set_val(Cy_temp, i, 0, m_get_val(Cy, i, 0) - 40.0);
				Y = getsampling(Cy_temp, ns);
				
				Ix1 = linear_interp2(grad_x, X, Y);
				Iy1 = linear_interp2(grad_x, X, Y);
				Xs = getfdriv(Cx, ns);
				Ys = getfdriv(Cy, ns);
				
				Nx = v_get(Ys->dim);
				for (i = 0; i < Ys->dim; i++)
					v_set_val(Nx, i, v_get_val(Ys, i) / sqrt(v_get_val(Xs, i)*v_get_val(Xs, i) + v_get_val(Ys, i)*v_get_val(Ys, i)));
					
				Ny = v_get(Xs->dim);
				for (i = 0; i < Xs->dim; i++)
					v_set_val(Ny, i, -1.0 * v_get_val(Xs, i) / sqrt(v_get_val(Xs, i)*v_get_val(Xs, i) + v_get_val(Ys, i)*v_get_val(Ys, i)));
					
				W = v_get(Nx->dim);
				for (i = 0; i < Nx->dim; i++)
					v_set_val(W, i, m_get_val(Ix1, 0, i) * v_get_val(Nx, i) + m_get_val(Iy1, 0, i) * v_get_val(Ny, i));
					
				V[n] = mean(W) / std_dev(W);
				
				//get means of X and Y values for all "snaxels" of the spline contour, thus finding the cell centers
				QAX_CENTERS[k_count] = mean(X);
				QAY_CENTERS[k_count] = mean(Y) + TOP;
				
				k_count++;
				
				// Free memory
				v_free(W);
				v_free(Ny);
				v_free(Nx);
				v_free(Ys);
				v_free(Xs);
				m_free(Iy1);
				m_free(Ix1);
				v_free(Y);
				v_free(X);
				m_free(Cy_temp);
				m_free(Cy);
				m_free(Cx);				
			}
			
			// Free memory
			v_free(y_row);
			v_free(x_row);
			m_free(y);
			m_free(x);
		}
	}

	// Free memory
	free(V);
	free(ccol);
	free(crow);
	free(GICOV_spots);
	free(t);
	free(G);
	free(x_result);
	free(y_result);
	m_free(A);
	m_free(celly);
	m_free(cellx);
	m_free(img_dilated);
	m_free(gicov);
	m_free(grad_y);
	m_free(grad_x);
	
	// Report the total number of cells detected
	printf("Cells detected: %d\n\n", k_count);
	
	// Report the breakdown of the detection runtime
	printf("Detection runtime\n");
	printf("-----------------\n");
	printf("GICOV computation: %.5f seconds\n", ((float) (GICOV_end_time - GICOV_start_time)) / (1000*1000));
	printf("   GICOV dilation: %.5f seconds\n", ((float) (dilate_end_time - dilate_start_time)) / (1000*1000));
	printf("            Total: %.5f seconds\n", ((float) (get_time() - program_start_time)) / (1000*1000));
	
	// Now that the cells have been detected in the first frame,
	//  track the ellipses through subsequent frames
	if (num_frames > 1) printf("\nTracking cells across %d frames\n", num_frames);
	else                printf("\nTracking cells across 1 frame\n");
	long long tracking_start_time = get_time();
	int num_snaxels = 20;
	ellipsetrack(cell_file, QAX_CENTERS, QAY_CENTERS, k_count, radius, num_snaxels, num_frames);
	printf("           Total: %.5f seconds\n", ((float) (get_time() - tracking_start_time)) / (float) (1000*1000*num_frames));
	
	// Report total program execution time
    printf("\nTotal application run time: %.5f seconds\n", ((float) (get_time() - program_start_time)) / (1000*1000));

	return 0;
}
Ejemplo n.º 14
0
void GrabCutMF::Demo(CStr &wkDir, float w1, float w2, float w3, float alpha, float beta, float gama, float mu)
{	
	CStr imgDir = wkDir + "Imgs/", salDir = wkDir + "Sal4N/", iluDir = wkDir + "Ilu4N/";
	vecS namesNE;
	int imgNum = CmFile::GetNamesNE(imgDir + "*.jpg", namesNE);
	CmFile::MkDir(salDir);
	CmFile::MkDir(iluDir);
	printf("w1 = %g, w2 = %g, w3 = %g, alpha = %g, beta = %g, gama = %g, mu = %g\n", w1, w2, w3, alpha, beta, gama, mu);

	// Number of labels
	//const int M = 2;
	CmTimer tm("Time"), tmIni("TimeIni"), tmRef("TimeRef");
	double maxWeight = 2; // 2: 0.958119, 1: 0.953818, 
	tm.Start();
#pragma omp parallel for
	for (int i = 0; i < imgNum; i++){
		printf("Processing %d/%d: %s%s.jpg%20s\r\n", i, imgNum, _S(imgDir), _S(namesNE[i]), "");
		CmFile::Copy(imgDir + namesNE[i] + ".jpg", salDir + namesNE[i] + ".jpg");
		//CmFile::Copy(imgDir + namesNE[i] + ".png", salDir + namesNE[i] + "_GT.png");
		Mat _imMat3u = imread(imgDir + namesNE[i] + ".jpg"), imMat3f, imMat3u, gt1u;
		Mat _gt1u = imread(imgDir + namesNE[i] + ".png", CV_LOAD_IMAGE_GRAYSCALE);
		if(_gt1u.rows == 0 && _gt1u.cols == 0) {
            cout<<"Error: unable to open "<<(imgDir + namesNE[i] + ".png")<<endl;
            continue;
		}
		blur(_gt1u, _gt1u, Size(3,3));
		Mat _res1u = Mat::zeros(_imMat3u.size(), CV_8U);
		Rect wkRect = CmCv::GetMaskRange(_gt1u, 30, 200);
		_imMat3u(wkRect).copyTo(imMat3u);
		_gt1u(wkRect).copyTo(gt1u);
		imMat3u.convertTo(imMat3f, CV_32FC3, 1/255.0);
		Rect rect = CmCv::GetMaskRange(gt1u, 5, 128);


		Mat edge1u; // Use an edge map to expand the background mask in flat (no edge) region
		CmCv::CannySimpleRGB(imMat3u, edge1u, 120, 1200, 5);
		dilate(edge1u, edge1u, Mat(), Point(-1, -1), 3);
		Mat borderMask1u(imMat3u.size(), CV_8U), tmpMask;
		memset(borderMask1u.data, 255, borderMask1u.step.p[0] * borderMask1u.rows);
		borderMask1u(rect) = Scalar(0);
		getGrabMask(edge1u, borderMask1u);


		//* The Mean field based GrabCut
		//tmIni.Start();
		GrabCutMF cutMF(imMat3f, imMat3u, salDir + namesNE[i], w1, w2, w3, alpha, beta, gama, mu);
		//Mat borderMask1u = CmCv::getGrabMask(imMat3u, rect), tmpMask;
		imwrite(salDir + namesNE[i] + "_BM.png", borderMask1u);
		imwrite(salDir + namesNE[i] + ".jpg", imMat3u);
		//imwrite(salDir + namesNE[i] + "_GT.png", gt1u);
		cutMF.initialize(rect, borderMask1u, (float)maxWeight, true);
		//cutMF.setGrabReg(rect, CmCv::getGrabMask(imMat3u, rect));
		//tmIni.Stop();
		//tmRef.Start();
		cutMF.refine();
		//tmRef.Stop();
		
		Mat res1u = cutMF.drawResult(), invRes1u;

		res1u.copyTo(_res1u(wkRect));
		imwrite(salDir + namesNE[i] + "_GCMF1.png", _res1u);

		//if (sum(res1u).val[0] < EPS){
		//	printf("%s.jpg don't contains a salient object\n", _S(namesNE[i]));
		//	continue;
		//}

		dilate(res1u(rect), tmpMask, Mat(), Point(-1, -1), 10);	
		bitwise_not(tmpMask, borderMask1u(rect));
		getGrabMask(edge1u, borderMask1u);

		//blur(res1u, invRes1u, Size(3, 3));
		//
		//PointSeti hullPnts;
		//convexHullOfMask(invRes1u, hullPnts);
		//fillConvexPoly(invRes1u, hullPnts, 255);
		//bitwise_not(invRes1u, invRes1u);
		//bitwise_or(invRes1u, borderMask1u, borderMask1u);
		imwrite(salDir + namesNE[i] + "_MB2.png", borderMask1u);

		
		//double w =  maxWeight - (maxWeight-1)*sum(res1u).val[0]/(borderMask1u.rows*borderMask1u.cols*255 - sum(borderMask1u).val[0]);
		cutMF.initialize(rect, borderMask1u, 2);
		cutMF.refine();

		//printf("weight = %g\n", w);
		//imshow("Result", res1u);
		//imshow("Possible", borderMask1u);
		//imshow("Image", imMat3f);
		//waitKey(0);

		res1u = cutMF.drawResult();

		Rect rectRes = CmCv::GetMaskRange(res1u, 5, 128);
		if (rectRes.width * 1.1 < rect.width || rectRes.height * 1.1 < rect.height){ // Too short result
			printf("%s.jpg contains a small object\n", _S(namesNE[i]));
			memset(borderMask1u.data, 255, borderMask1u.step.p[0] * borderMask1u.rows);
			borderMask1u(rect) = Scalar(0);
			cutMF.initialize(rect, borderMask1u, 2);
			cutMF.refine();
			res1u = cutMF.drawResult();
			imwrite(salDir + namesNE[i] + "_MB2.png", borderMask1u);
			CmFile::Copy2Dir(salDir + namesNE[i] + "*.*", iluDir);
			imwrite(iluDir + namesNE[i] + "_GCMF.png", _res1u);
		}

		res1u.copyTo(_res1u(wkRect));
		imwrite(salDir + namesNE[i] + "_GCMF.png", _res1u);
		
	}
	tm.Stop();
	double avgTime = tm.TimeInSeconds()/imgNum;
	printf("Speed: %gs, %gfps\t\t\n", avgTime, 1/avgTime);
	//tmIni.Report();
	//tmRef.Report();
	//CmEvaluation::EvalueMask(imgDir + "*.png", salDir, ".png", "_GC.png");

	
	char* pDes[] = { "GCMF1", "GCMF"}; //, "CudaG4", "Onecut", "GC", "CudaH", 
	vecS des  = charPointers2StrVec (pDes);
	CStr rootDir = CmFile::GetFatherFolder(wkDir), dbName = CmFile::GetNameNE(wkDir.substr(0, wkDir.size() - 1));
	CmEvaluation::EvalueMask(imgDir + "*.png", salDir, des, wkDir.substr(0, wkDir.size() - 1) + "Res.m", 0.3, false, "", dbName);
}
Ejemplo n.º 15
0
///////////////////////////////////////////////////////////////////
// Panel::CannyDetection() 
// Description: This function is called by DetectEdges() and it
//  is the Canny edge detection function which does not contain
//  debugging statements. We run the image through several different 
//  image processing functions to prepare the image before edge
//  detection. After detection the edges we run Hough lines which 
//  approximates lines of minimum length as specified in 
//  Settings.xml. We find all intersections of the Hough lines 
//  then make a minimum area rectangle around the intersections to 
//  approximate the edges of the panel which we are trying to
//  measure. From there we use the unit conversion calculated 
//  in DetectFeatures() to find a length and width of the current
//  panel. We report the length and width with a message box. 
///////////////////////////////////////////////////////////////////
Mat Panel::CannyDetection(Mat image, bool showImg)
{
	Mat greyImage;
	cvtColor(image, greyImage, CV_BGR2GRAY);

	Mat eroded, dilated, thresh, blurredThresh, edges, edgesGray;
	vector<Vec2f> lines;

		threshold(greyImage, thresh, m_lowCannyThreshold, 255, THRESH_BINARY);
		erode(thresh, eroded, Mat());
		dilate(eroded, dilated, Mat());
		GaussianBlur(thresh, blurredThresh, Size(7, 7), m_sigmaX, m_sigmaY);
		Canny(blurredThresh, edges, m_cannyLow, m_cannyLow*m_ratio, 3);
		HoughLines(edges, lines, 1, CV_PI / 180, m_houghLength, 0, 0);

		cvtColor(edges, edgesGray, CV_GRAY2BGR);
		for (size_t i = 0; i < lines.size(); i++)
		{
			float rho = lines[i][0], theta = lines[i][1];
			Point pt1, pt2;
			double a = cos(theta), b = sin(theta);
			double x0 = a*rho, y0 = b*rho;
			pt1.x = cvRound(x0 + 1000 * (-b));
			pt1.y = cvRound(y0 + 1000 * (a));
			pt2.x = cvRound(x0 - 1000 * (-b));
			pt2.y = cvRound(y0 - 1000 * (a));
			line(edgesGray, pt1, pt2, Scalar(0, 0, 255), 3, CV_AA);
		}

		////////////////////////////////////////////////////////
		// Compute the intersection from the lines detected
		////////////////////////////////////////////////////////
		vector<Point2f> intersections;
		for (size_t i = 0; i < lines.size(); i++)
		{
			for (size_t j = 0; j < lines.size(); j++)
			{
				Vec2f line1 = lines[i];
				Vec2f line2 = lines[j];
				if (acceptLinePair(line1, line2, (float)CV_PI / 32))
				{
					Point2f intersection = computeIntersect(line1, line2);
					if (intersection.x >= 0 && intersection.y >= 0)
						intersections.push_back(intersection);
				}
			}
		}

		if (intersections.size() > 0)
		{
			vector<Point2f>::iterator i;
			for (i = intersections.begin(); i != intersections.end(); ++i)
			{
				cout << "Intersection is " << i->x << ", " << i->y << endl;
				circle(image, *i, 2, Scalar(0, 255, 0), 3);
			}
			// Find the minimum bounding rectangle
			RotatedRect rect;
			Point2f rectPoints[4];
			Scalar color = Scalar(255, 0, 0);
			if (intersections.size() == 4)
			{
				// TODO
			}
			rect = minAreaRect(intersections);
			rect.points(rectPoints);
			int j = 0;
			for (j; j < 4; j++)
				line(image, rectPoints[j], rectPoints[(j + 1) % 4], color, 5, 8);

			float topLength = (float)norm(rectPoints[1] - rectPoints[0]);
			float botLength = (float)norm(rectPoints[3] - rectPoints[2]);
			float panelWidthPixels = topLength < botLength ? topLength : botLength;

			float leftHeight = (float)norm(rectPoints[3] - rectPoints[0]);
			float rightHeight = (float)norm(rectPoints[2] - rectPoints[1]);
			float panelHeightPixels = leftHeight < rightHeight ? leftHeight : rightHeight;

			string dimensionDisplayPixels = "Pixels:\nWidth: " + to_string(panelWidthPixels) + " pixels\nHeight: " + to_string(panelHeightPixels) + " pixels";
			// ShowMessage(dimensionDisplayPixels);
			if (m_conversionRate)
			{
				float panelWidthReal = panelWidthPixels / m_conversionRate;
				float panelHeightReal = panelHeightPixels / m_conversionRate;
				string dimensionDisplayActual = "Actual:\nWidth: " + to_string(panelWidthReal) + " cm\nHeight: " + to_string(panelHeightReal) + " cm";
				ShowMessage(dimensionDisplayActual);
			}

		}

		if (showImg){
			namedWindow("Intersections", CV_WINDOW_KEEPRATIO);
			imshow("Intersections", image);
		}
		/////////////////////////////////////////////////////////////
		// End of Computing the intersection from the lines detected
		/////////////////////////////////////////////////////////////
	return edges;
}
Ejemplo n.º 16
0
//--------------------------------------------------------------
void ofApp::update(){
    
    kinect.update();
    
    deltaTime = ofGetElapsedTimef() - lastTime;
    lastTime = ofGetElapsedTimef();
    
    if (kinect.isFrameNew()) {

        // Load grayscale depth image from the kinect source
        grayImage.setFromPixels(kinect.getDepthPixels(), kinect.width, kinect.height, OF_IMAGE_GRAYSCALE);
        
        // Threshold image
        threshold(grayImage, grayThreshNear, nearThreshold, true);
        threshold(grayImage, grayThreshFar, farThreshold);
        
        // Convert to CV to perform AND operation
        Mat grayThreshNearMat = toCv(grayThreshNear);
        Mat grayThreshFarMat = toCv(grayThreshFar);
        Mat grayImageMat = toCv(grayImage);
        
        // cvAnd to get the pixels which are a union of the two thresholds
        bitwise_and(grayThreshNearMat, grayThreshFarMat, grayImageMat);
        
        // Save pre-processed image for drawing it
        grayPreprocImage = grayImage;
        
        // Process image
        dilate(grayImage);
        dilate(grayImage);
        //erode(grayImage);
        
        // Mark image as changed
        grayImage.update();
        
        // Find contours
        //contourFinder.setThreshold(ofMap(mouseX, 0, ofGetWidth(), 0, 255));
        contourFinder.findContours(grayImage);
        
        ofPushStyle();
        ofEnableBlendMode(OF_BLENDMODE_DISABLED);
        cameraFbo.begin();
        ofSetColor(ofColor::white);
        if (doFlipCamera)
            kinect.drawDepth(cameraFbo.getWidth(), 0, -cameraFbo.getWidth(), cameraFbo.getHeight());  // Flip Horizontal
        else
            kinect.drawDepth(0, 0, cameraFbo.getWidth(), cameraFbo.getHeight());
        cameraFbo.end();
        ofDisableBlendMode();
        ofPopStyle();
        
        opticalFlow.setSource(cameraFbo.getTexture());
        opticalFlow.update(deltaTime);
        
        velocityMask.setDensity(cameraFbo.getTexture());
        velocityMask.setVelocity(opticalFlow.getOpticalFlow());
        velocityMask.update();
    }
    
    
    fluidSimulation.addVelocity(opticalFlow.getOpticalFlowDecay());
    fluidSimulation.addDensity(velocityMask.getColorMask());
    fluidSimulation.addTemperature(velocityMask.getLuminanceMask());
    
    mouseForces.update(deltaTime);
    
    for (int i=0; i<mouseForces.getNumForces(); i++) {
        if (mouseForces.didChange(i)) {
            switch (mouseForces.getType(i)) {
                case FT_DENSITY:
                    fluidSimulation.addDensity(mouseForces.getTextureReference(i), mouseForces.getStrength(i));
                    break;
                case FT_VELOCITY:
                    fluidSimulation.addVelocity(mouseForces.getTextureReference(i), mouseForces.getStrength(i));
                    particleFlow.addFlowVelocity(mouseForces.getTextureReference(i), mouseForces.getStrength(i));
                    break;
                case FT_TEMPERATURE:
                    fluidSimulation.addTemperature(mouseForces.getTextureReference(i), mouseForces.getStrength(i));
                    break;
                case FT_PRESSURE:
                    fluidSimulation.addPressure(mouseForces.getTextureReference(i), mouseForces.getStrength(i));
                    break;
                case FT_OBSTACLE:
                    fluidSimulation.addTempObstacle(mouseForces.getTextureReference(i));
                default:
                    break;
            }
        }
    }
    
    fluidSimulation.update();
    
    if (particleFlow.isActive()) {
        particleFlow.setSpeed(fluidSimulation.getSpeed());
        particleFlow.setCellSize(fluidSimulation.getCellSize());
        particleFlow.addFlowVelocity(opticalFlow.getOpticalFlow());
        particleFlow.addFluidVelocity(fluidSimulation.getVelocity());
        //		particleFlow.addDensity(fluidSimulation.getDensity());
        particleFlow.setObstacle(fluidSimulation.getObstacle());
    }
    particleFlow.update();
    
}