void BlobTracking::process(const cv::Mat &img_input, const cv::Mat &img_mask, cv::Mat &img_output) { if(img_input.empty() || img_mask.empty()) return; loadConfig(); if(firstTime) saveConfig(); IplImage* frame = new IplImage(img_input); cvConvertScale(frame, frame, 1, 0); IplImage* segmentated = new IplImage(img_mask); IplConvKernel* morphKernel = cvCreateStructuringElementEx(5, 5, 1, 1, CV_SHAPE_RECT, NULL); cvMorphologyEx(segmentated, segmentated, NULL, morphKernel, CV_MOP_OPEN, 1); if(showBlobMask) cvShowImage("Blob Mask", segmentated); IplImage* labelImg = cvCreateImage(cvGetSize(frame), IPL_DEPTH_LABEL, 1); cvb::CvBlobs blobs; unsigned int result = cvb::cvLabel(segmentated, labelImg, blobs); //cvb::cvFilterByArea(blobs, 500, 1000000); cvb::cvFilterByArea(blobs, minArea, maxArea); //cvb::cvRenderBlobs(labelImg, blobs, frame, frame, CV_BLOB_RENDER_BOUNDING_BOX); if(debugBlob) cvb::cvRenderBlobs(labelImg, blobs, frame, frame, CV_BLOB_RENDER_BOUNDING_BOX|CV_BLOB_RENDER_CENTROID|CV_BLOB_RENDER_ANGLE|CV_BLOB_RENDER_TO_STD); else cvb::cvRenderBlobs(labelImg, blobs, frame, frame, CV_BLOB_RENDER_BOUNDING_BOX|CV_BLOB_RENDER_CENTROID|CV_BLOB_RENDER_ANGLE); cvb::cvUpdateTracks(blobs, tracks, 200., 5); if(debugTrack) cvb::cvRenderTracks(tracks, frame, frame, CV_TRACK_RENDER_ID|CV_TRACK_RENDER_BOUNDING_BOX|CV_TRACK_RENDER_TO_STD); else cvb::cvRenderTracks(tracks, frame, frame, CV_TRACK_RENDER_ID|CV_TRACK_RENDER_BOUNDING_BOX); //std::map<CvID, CvTrack *> CvTracks if(showOutput) cvShowImage("Blob Tracking", frame); cv::Mat img_result(frame); img_result.copyTo(img_output); //cvReleaseImage(&frame); //cvReleaseImage(&segmentated); cvReleaseImage(&labelImg); delete frame; delete segmentated; cvReleaseBlobs(blobs); cvReleaseStructuringElement(&morphKernel); firstTime = false; }
void BlobTrackingNode::process(const cv::Mat &img_input, const cv::Mat &img_mask, cv::Mat &img_output) { //This is output event QList<DetectedEvent> blobEvent; cv::Mat newInput; img_input.copyTo(newInput); if(img_input.empty() || img_mask.empty()){ return; } loadConfig(); if(firstTime){ saveConfig(); } IplImage* frame = new IplImage(img_input); cvConvertScale(frame, frame, 1, 0); IplImage* segmentated = new IplImage(img_mask); IplConvKernel* morphKernel = cvCreateStructuringElementEx(5, 5, 1, 1, CV_SHAPE_RECT, NULL); cvMorphologyEx(segmentated, segmentated, NULL, morphKernel, CV_MOP_OPEN, 1); cv::Mat temp = cv::Mat(segmentated); if(showBlobMask){ //cv::imshow("test",temp); ownerPlugin->updateFrameViewer("Tracking Mask",convertToQImage(temp)); } IplImage* labelImg = cvCreateImage(cvGetSize(frame), IPL_DEPTH_LABEL, 1); cvb::CvBlobs blobs; cvb::cvLabel(segmentated, labelImg, blobs); cvb::cvFilterByArea(blobs, minArea, maxArea); if(debugBlob){ cvb::cvRenderBlobs(labelImg, blobs, frame, frame, CV_BLOB_RENDER_BOUNDING_BOX|CV_BLOB_RENDER_CENTROID|CV_BLOB_RENDER_ANGLE|CV_BLOB_RENDER_TO_STD); } else{ cvb::cvRenderBlobs(labelImg, blobs, frame, frame, CV_BLOB_RENDER_BOUNDING_BOX|CV_BLOB_RENDER_CENTROID|CV_BLOB_RENDER_ANGLE); } cvb::cvUpdateTracks(blobs, tracks,threshold_distance, threshold_inactive); //At this point, we have assigned each blob in current frame in to a track. so we can iterate through active tracks, and // find out out blobs within one of those tracks. Following loop does that. This is helpfull to have more generalized idea about // relationship between blobs with increasing time. for (cvb::CvTracks::const_iterator track = tracks.begin(); track!=tracks.end(); ++track) { if((*track).second->active != 0){ for(std::map<cvb::CvLabel,cvb::CvBlob *>::iterator it = blobs.begin() ; it != blobs.end(); it++){ cvb::CvLabel label = (*it).first; cvb::CvBlob * blob = (*it).second; if((*track).second->label == label){ //qDebug()<< blob->minx <<","<<blob->miny; //This is smoothed time tracked blob lables blobEvent.append(DetectedEvent("blob",QString("%1,%2,%3,%4,%5,%6,%7,%8").arg(frameIndex).arg((*track).first).arg(blob->centroid.x).arg(blob->centroid.y).arg(blob->minx).arg(blob->miny).arg(blob->maxx).arg(blob->maxy),1.0)); } } } } if(debugTrack){ cvb::cvRenderTracks(tracks, frame, frame, CV_TRACK_RENDER_ID|CV_TRACK_RENDER_BOUNDING_BOX|CV_TRACK_RENDER_TO_STD); } else{ cvb::cvRenderTracks(tracks, frame, frame, CV_TRACK_RENDER_ID|CV_TRACK_RENDER_BOUNDING_BOX); } if(showFrameID){ cv::Mat temp = cv::Mat(frame); cv::putText(temp,QString("%1").arg(frameIndex).toStdString(),cv::Point(40,120),cv::FONT_HERSHEY_PLAIN,2,cv::Scalar(0,255,0),2); } if(showOutput){ cv::Mat temp = cv::Mat(frame); ownerPlugin->updateFrameViewer("Tracking Output",convertToQImage(temp)); //cvShowImage("Blob Tracking", frame); } cv::Mat img_result(frame); cv::putText(img_result,QString("%1").arg(QString::number(frameIndex)).toUtf8().constData(), cv::Point(10,30), CV_FONT_HERSHEY_PLAIN,1.0, CV_RGB(255,255,255)); img_result.copyTo(img_output); cvReleaseImage(&labelImg); delete frame; delete segmentated; cvReleaseBlobs(blobs); cvReleaseStructuringElement(&morphKernel); firstTime = false; frameIndex++; QImage input((uchar*)newInput.data, newInput.cols, newInput.rows, newInput.step1(), QImage::Format_RGB888); QImage output((uchar*)img_output.data, img_output.cols, img_output.rows, img_output.step1(), QImage::Format_RGB888); QList<QImage> images; images.append(input); images.append(output); emit generateEvent(blobEvent,images); //emit generateEvent(blobEvent); }
IonDetector::result_type IonDetector::blob_detector( const image_type& img ) { Kernel logs[3]; float sigmas[3]; logs[0] = Kernel::LoG( 4, 0.6 ); sigmas[0] = 0.85; logs[1] = Kernel::LoG( 6, 1.0 ); sigmas[1] = 1.0; logs[2] = Kernel::LoG( 20, 5.0 ); sigmas[2] = 2.; image_type img_result( img.extents ); result_type results; const size_t hsize = 2000; std::vector< size_t > histogram( hsize, 0 ); size_t g = 2; logs[g].apply_kernel( img, img_result ); save_file( "log.fits", img_result ); float img_max = *std::max_element( img_result.ptr(), img_result.ptr() + img.num_elements() ); for( float* iter = img_result.ptr(); iter != img_result.ptr() + img.num_elements(); ++iter ) { int p = (size_t)( ( *iter + img_max ) / 2 / img_max * hsize ); if( p >= (int)hsize ) p = hsize-1; if( p < 0 ) p = 0; histogram[ p ] ++; } size_t nelems = 0, counter = hsize-1; while( nelems < (size_t)blob_threshold ) nelems += histogram[ counter-- ]; float thresh = (float)counter / hsize * img_max - img_max / 2.; for( image_type::index i = 12; i < img.extents.first-12; ++i ) for( image_type::index j = 12; j < img.extents.second-12; ++j ) { if( img_result( i, j ) > thresh && img_result( i, j ) > img_result( i+1, j ) && img_result( i, j ) > img_result( i-1, j ) && img_result( i, j ) > img_result( i, j+1 ) && img_result( i, j ) > img_result( i, j-1 ) && img_result( i, j ) > img_result( i+1, j+1 ) && img_result( i, j ) > img_result( i+1, j-1 ) && img_result( i, j ) > img_result( i-1, j+1 ) && img_result( i, j ) > img_result( i-1, j-1 ) ) { results.push_back( IonData( i, j, sigmas[g] ) ); } } return results; }