He is researching to find meaningful scene in endoscopic video.
His one of approach is using optical flow.
refer to this page.
http://study.marearts.com/2015/01/the-method-to-check-that-camera-is.html
Dense optical flow can know how much video moving.
The source code of reference page checked camera move or not by the percentage of movement.
There are 2 threshold values.
Count number of moved pixels, this is counted when pixels moved over than threshold-1 value.
And check whether the counted pixels is over than threshold-2 percent or not in all pixels.
By the way, he ask me to separate video moving by big, middle, small using k-means clustering algorithm without threshold.
In past, I introduced the usage of k-mean algorithm using openCV.
See this page.
http://study.marearts.com/search/label/K-means
This work is separated by 3 steps.
Step 1 is to calculate movement rate in video using optical flow.
And save fame and movement rate information to txt file.
Step 2 is clustering by 3 class degree movement using k-means.
read step 1 file and write clustering information to txt file.
Step 3 is for display.
read step 3 txt file and display moving rate on the video.
refer to these source code.
Thank you.
Step 1.
Getting movement rate of frames.
moving rate is calculated.
...
#include < stdio.h> #include < opencv2\opencv.hpp> #include < opencv2/core/core.hpp> #include < opencv2/highgui/highgui.hpp> #include < opencv2\gpu\gpu.hpp> #include < opencv2\nonfree\features2d.hpp > #ifdef _DEBUG #pragma comment(lib, "opencv_core249d.lib") #pragma comment(lib, "opencv_imgproc249d.lib") //MAT processing #pragma comment(lib, "opencv_objdetect249d.lib") //HOGDescriptor #pragma comment(lib, "opencv_gpu249d.lib") #pragma comment(lib, "opencv_features2d249d.lib") #pragma comment(lib, "opencv_highgui249d.lib") #else #pragma comment(lib, "opencv_core249.lib") #pragma comment(lib, "opencv_imgproc249.lib") #pragma comment(lib, "opencv_objdetect249.lib") #pragma comment(lib, "opencv_gpu249.lib") #pragma comment(lib, "opencv_features2d249.lib") #pragma comment(lib, "opencv_highgui249.lib") #endif using namespace std; using namespace cv; #define WIDTH_DENSE (80) #define HEIGHT_DENSE (60) #define DENSE_DRAW 0 //dense optical flow arrow drawing or not #define GLOBAL_MOTION_TH1 1 #define GLOBAL_MOTION_TH2 70 float drawOptFlowMap_gpu (const Mat& flow_x, const Mat& flow_y, Mat& cflowmap, int step, float scaleX, float scaleY, int drawOnOff); int main() { //stream ///////////////////////////////////////////////// VideoCapture stream1("M:\\____videoSample____\\medical\\HUV-03-14.wmv"); //variables ///////////////////////////////////////////// Mat O_Img; //Mat gpu::GpuMat O_Img_gpu; //GPU gpu::GpuMat R_Img_gpu_dense; //gpu dense resize gpu::GpuMat R_Img_gpu_dense_gray_pre; //gpu dense resize gray gpu::GpuMat R_Img_gpu_dense_gray; //gpu dense resize gray gpu::GpuMat flow_x_gpu, flow_y_gpu; Mat flow_x, flow_y; //algorithm ************************************* //dense optical flow gpu::FarnebackOpticalFlow fbOF; //running once ////////////////////////////////////////// if(!(stream1.read(O_Img))) //get one frame form video { printf("Open Fail !!\n"); return 0; } //for rate calucation float scaleX, scaleY; scaleX = O_Img.cols/WIDTH_DENSE; scaleY = O_Img.rows/HEIGHT_DENSE; O_Img_gpu.upload(O_Img); gpu::resize(O_Img_gpu, R_Img_gpu_dense, Size(WIDTH_DENSE, HEIGHT_DENSE)); gpu::cvtColor(R_Img_gpu_dense, R_Img_gpu_dense_gray_pre, CV_BGR2GRAY); ////////////////////////////////////////////////////////// FILE *fp = fopen("DataOutput.txt","w"); //unconditional loop /////////////////////////////////// int frame=0; int untilFrame=1000; while (true) { frame++; if(frame>untilFrame) //stop point. break; //reading if( stream1.read(O_Img) == 0) //get one frame form video break; // --------------------------------------------------- //upload cou mat to gpu mat O_Img_gpu.upload(O_Img); //resize gpu::resize(O_Img_gpu, R_Img_gpu_dense, Size(WIDTH_DENSE, HEIGHT_DENSE)); //color to gray gpu::cvtColor(R_Img_gpu_dense, R_Img_gpu_dense_gray, CV_BGR2GRAY); //calculate dense optical flow using GPU version fbOF.operator()(R_Img_gpu_dense_gray_pre, R_Img_gpu_dense_gray, flow_x_gpu, flow_y_gpu); flow_x_gpu.download( flow_x ); flow_y_gpu.download( flow_y ); //calculate motion rate in whole image float motionRate = drawOptFlowMap_gpu(flow_x, flow_y, O_Img, 1, scaleX, scaleY, DENSE_DRAW); //update pre image R_Img_gpu_dense_gray_pre = R_Img_gpu_dense_gray.clone(); //display "moving rate (0~100%)" and save to txt with frame char TestStr[100]; sprintf(TestStr, "%.2lf %% moving", motionRate); putText(O_Img, TestStr, Point(30,60), CV_FONT_NORMAL, 1, Scalar(255,255,255),2,2); //OutImg is Mat class; //output "frame, motionRate" to txt fprintf(fp,"%d %.2lf\n", frame, motionRate); // show image ---------------------------------------- imshow("Origin", O_Img); // wait key if( cv::waitKey(100) > 30) break; } fclose(fp); } float drawOptFlowMap_gpu (const Mat& flow_x, const Mat& flow_y, Mat& cflowmap, int step, float scaleX, float scaleY, int drawOnOff) { double count=0; float countOverTh1 = 0; int sx,sy; for(int y = 0; y < HEIGHT_DENSE; y += step) { for(int x = 0; x < WIDTH_DENSE; x += step) { if(drawOnOff) { Point2f fxy; fxy.x = cvRound( flow_x.at< float >(y, x)*scaleX + x*scaleX ); fxy.y = cvRound( flow_y.at< float >(y, x)*scaleY + y*scaleY ); line(cflowmap, Point(x*scaleX,y*scaleY), Point(fxy.x, fxy.y), CV_RGB(0, 255, 0)); circle(cflowmap, Point(fxy.x, fxy.y), 1, CV_RGB(0, 255, 0), -1); } float xx = fabs(flow_x.at< float >(y, x) ); float yy = fabs(flow_y.at< float >(y, x) ); float xxyy = sqrt(xx*xx + yy*yy); if( xxyy > GLOBAL_MOTION_TH1 ) countOverTh1 = countOverTh1 +1; count=count+1; } } return (countOverTh1 / count) * 100; }...
step 2. clustering movement rate to 3 classes.
The movement rates are clustered by 3 values
Frames and class ID
...
#include < stdio.h> #include < iostream> #include < opencv2\opencv.hpp> #ifdef _DEBUG #pragma comment(lib, "opencv_core249d.lib") #pragma comment(lib, "opencv_imgproc249d.lib") //MAT processing #pragma comment(lib, "opencv_highgui249d.lib") #else #pragma comment(lib, "opencv_core249.lib") #pragma comment(lib, "opencv_imgproc249.lib") #pragma comment(lib, "opencv_highgui249.lib") #endif using namespace cv; using namespace std; void main() { //read data FILE* fp = fopen("DataOutput.txt","r"); vector< float > readDataV; int frames; double movingRate; while(fscanf(fp,"%d %lf", &frames, &movingRate) != EOF ) { readDataV.push_back( movingRate ); //printf("%d %lf \n", frames, movingRate); } fclose(fp); //preparing variables for kmeans Mat samples(readDataV.size(), 1, CV_32F); //copy vector to mat memcpy(samples.data, readDataV.data(), readDataV.size()*sizeof(float) ); //kmean int clusterCount = 3; Mat labels; int attempts = 10; Mat centers; kmeans(samples, clusterCount, labels, TermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, 10, 1.0), attempts, KMEANS_RANDOM_CENTERS, centers ); //result out //frames, class index for(int i=0; i< clusterCount; ++i) { printf("%d class center %lf\n", i, centers.at< float>(i,0) ); } printf("\n"); FILE* fp2 = fopen("ResultKmeans.txt", "w"); for(int i=0; i< readDataV.size(); ++i) { //printf("%d %d\n", i, labels.at< int>(i,0) ); fprintf(fp2, "%d %d\n", i+1, labels.at< int>(i,0) ); } fclose(fp2); }...
step 3. display movement labels on the video.
display 3 type of movement category(big, middle, small).
#include < time.h> #include < opencv2\opencv.hpp> #include < string> #include < stdio.h> #ifdef _DEBUG #pragma comment(lib, "opencv_core249d.lib") #pragma comment(lib, "opencv_imgproc249d.lib") //MAT processing #pragma comment(lib, "opencv_highgui249d.lib") #else #pragma comment(lib, "opencv_core249.lib") #pragma comment(lib, "opencv_imgproc249.lib") #pragma comment(lib, "opencv_highgui249.lib") #endif using namespace std; using namespace cv; int main() { ///////////////////////////////////////////////////////////////////////// //read file FILE* fp = fopen("ResultKmeans.txt","r"); vector< int > readDataV; int frames; int labels; while(fscanf(fp,"%d %d", &frames, &labels) != EOF ) { readDataV.push_back( labels ); //printf("%d %d \n", frames, labels); } fclose(fp); //Load avi file VideoCapture stream1("M:\\____videoSample____\\medical\\HUV-03-14.wmv"); ///////////////////////////////////////////////////////////////////////// //Mat and GpuMat Mat o_frame; //capture stream1 >> o_frame; if( o_frame.empty() ) return 0; ////////////////////////////////////////////////////////////////////////// int frame=0; int untilFrame=1000; while(1) { frame++; if(frame>untilFrame) //stop point. break; ///////////////////////////////////////////////////////////////////////// stream1 >> o_frame; if( o_frame.empty() ) return 0; char TestStr[100]; if(readDataV[frame-1] == 0) sprintf(TestStr, "Big moving"); else if(readDataV[frame-1] == 1) sprintf(TestStr, "middle moving"); else sprintf(TestStr, "small moving"); putText(o_frame, TestStr, Point(30,60), CV_FONT_NORMAL, 1, Scalar(255,255,255),2,2); //OutImg is Mat class; //Display imshow("origin", o_frame); ///////////////////////////////////////////////////////////////////////// if( waitKey(10) > 0) break; } return 0; }...
No comments:
Post a Comment