3/09/2015

To save mouse drag region to image file on the video frame. example source using opencv

This example source code is for saving image file that specified a rectangle region by mouse drag on the video frame.

The method is easy.
Firstly, enter the file name included file extension (ex: s.avi)
Then, video will be play.
Press p key on the video play window, if you want to save image.
Video will play after end of drag and drag region will be saved in your folder.
'ESC' key is for program finish.

Thank you.

example video is here
-> https://www.youtube.com/watch?v=ZpO1b-lZb7g



///
#include < stdio.h>
#include < iostream>

#include < opencv2\opencv.hpp>

#ifdef _DEBUG        
#pragma comment(lib, "opencv_core249d.lib")
#pragma comment(lib, "opencv_highgui249d.lib")
#else
#pragma comment(lib, "opencv_core249.lib")
#pragma comment(lib, "opencv_highgui249.lib")
#endif 

using namespace std;
using namespace cv;

bool selectObject = false;
Rect selection;
Point origin;
Mat image;
bool pause =false;
double fpss;

Rect PatchRect;
Mat PatchImg;

unsigned int frame_index=0;

static void onMouse( int event, int x, int y, int, void* )
{
 if( selectObject & pause)
 {

  selection.x = MIN(x, origin.x);
  selection.y = MIN(y, origin.y);
  selection.width = std::abs(x - origin.x);
  selection.height = std::abs(y - origin.y);
  selection &= Rect(0, 0, image.cols, image.rows);
 }

 switch( event )
 {
 case CV_EVENT_LBUTTONDOWN:
  origin = Point(x,y);
  selection = Rect(x,y,0,0);
  selectObject = true;
  break;
 case CV_EVENT_LBUTTONUP:
  if(selectObject && pause)
  {
   if(selection.width > 5 && selection.height > 5 )
   {
    PatchRect = selection;
    image( PatchRect ).copyTo( PatchImg );
    imshow("Selected Img", PatchImg );

    
    char str[100];
    sprintf_s(str,"%d.jpg", int(frame_index/fpss));
    imwrite(str, PatchImg);

   }else
    selection = Rect(0,0,0,0);
  }
  selectObject = false;
  pause = false;

  break;
 }
}


int main (void)  
{  


 printf("avi file name?");
 char nstr[255];
 scanf_s("%s", nstr);
 printf("-> %s", nstr);

 VideoCapture cap(nstr); 

 Mat frame;
 namedWindow( "Demo", 0 );
 setMouseCallback( "Demo", onMouse, 0 );
 printf("P key is pause, ESC key is exit.\n");

 for(;;)
 {
  frame_index++;

  if(!pause)
   cap >> frame;
  if( frame.empty() )
   break;
  frame.copyTo(image);


  if( pause && selection.width > 0 && selection.height > 0 )
  {
   rectangle(image, Point(selection.x-1, selection.y-1), Point(selection.x+selection.width+1, selection.y+selection.height+1), CV_RGB(255,0,0) );
  }

  imshow( "Demo", image );

  char k = waitKey(10);

  if( k == 27 )
   break;
  else if(k == 'p' || k=='P' )
   pause=!pause;
 }

 return 0;  
}  


...


4 comments:

  1. Hello,
    When running this program, my video is playing faster than usual, how can i get it to normal speed again?
    Thanks

    ReplyDelete
    Replies
    1. It is the posting for you!!! ^^
      http://study.marearts.com/2017/04/video-show-and-write-keeping-original.html

      Thank you for visiting and interesting.

      Delete
  2. μ•ˆλ…•ν•˜μ„Έμš” κ°•μ˜λ₯Ό 따라 λ“£κ³  μžˆλŠ” ν•™μƒμž…λ‹ˆλ‹€. 이 예제 μ½”λ“œλ₯Ό λ”°λΌμ„œ μ‹€ν–‰ν•΄ λ΄€λŠ”λ° 그림이 μ €μž₯λ˜λŠ” λΆ€λΆ„μ—μ„œ 였λ₯˜κ°€ μƒκ²ΌμŠ΅λ‹ˆλ‹€. 제 μƒκ°μ—λŠ” μ €μž₯λ˜λŠ” λΆ€λΆ„μ—μ„œ fpssλΌλŠ” λ³€μˆ˜κ°€ μ„ μ–Έ 후에 값이 λ³€λ™λ˜μ§ˆ μ•Šμ•„ μƒκΈ°λŠ” 문제 인것 같은데 도움을 μ£Όμ‹ λ‹€λ©΄ κ°μ‚¬ν•˜κ² μŠ΅λ‹ˆλ‹€

    ReplyDelete
    Replies
    1. 닡변이 λŠ¦μ–΄μ„œ μ£„μ†‘ν•©λ‹ˆλ‹€.
      λ„€ fpssκ°€ 아무 값도 μ•ˆλ“€μ–΄ κ°€λ„€μš”.. ^^
      μ œκ°€ 무슨 μƒκ°μœΌλ‘œ μ΄λ ‡κ²Œ μ§°λŠ”μ§€..
      μ–΄μ§Έλ“  아무 μ΄λ¦„μ΄λ‚˜ λ“€μ–΄κ°€λ©΄ λ˜λ‹ˆκΉ
      sprintf_s(str,"%d.jpg", int(frame_index/fpss));
      λ₯Ό
      sprintf_s(str,"%d.jpg", int(frame_index));
      으둜 κ³ μ³λ³΄μ„Έμš”.
      κ°μ‚¬ν•©λ‹ˆλ‹€.

      Delete