問題
OpenCV::ドラッグ処理を利用して、ドラッグすることで絵が描けるようにせよ。
その他条件:
はやく動かした時などの補間はしなくてよい。
OpenGL版 →
ドラッグ処理2
答え
#include <cv.h>
#include <highgui.h>
#include <cstdio>
#include <iostream>
using namespace std;
void Mouse( int event, int x, int y, int flags ,void *param);
CvSize window={300,300};//ウィンドウサイズ
IplImage *imgA;
int main( int argc, char **argv)
{
imgA = cvCreateImage(window,IPL_DEPTH_8U,3);
cvSet (imgA, cvScalarAll (255), 0);
cvNamedWindow("window",CV_WINDOW_AUTOSIZE);
cvShowImage("window",imgA);
cvSetMouseCallback("window", Mouse);
cvWaitKey(0); // 0秒待つ => ずっと入力待ち
cvReleaseImage( &imgA );
cvDestroyWindow("window");
return 0;
}
/**[ここから コールバック]***/
void Mouse( int event, int x, int y, int flags ,void *param = NULL) // コールバック関数
{
static bool MOUSE_FLAG=false;
switch(event)
{
case CV_EVENT_LBUTTONDOWN:
MOUSE_FLAG = true;
break;
case CV_EVENT_LBUTTONUP:
MOUSE_FLAG=false;
break;
}
if(event == CV_EVENT_MOUSEMOVE && MOUSE_FLAG == true)
{
cvRectangle(imgA,cvPoint(x,y),cvPoint(x+1,y+1),cvScalar(255,0,0));
cvShowImage("window",imgA);
}
}
画像を読み込んで、その上に落書きする
#include <iostream>
#include <cv.h>
#include <highgui.h>
using namespace std;
/****** [ プロトタイプ宣言 ] ******/
void Mouse( int event, int x, int y, int flags ,void *imgA);
int main( int argc, char **argv)
{
IplImage *imgA = cvLoadImage( "test.jpg", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
if(imgA ==NULL)
{
cout<<"Can't Load Image .\n";
std::exit(0);
}
cvNamedWindow("window",CV_WINDOW_AUTOSIZE);
cvShowImage("window",imgA);
cvSetMouseCallback("window", Mouse, imgA);
cvWaitKey(0); // 0秒待つ => ずっと入力待ち
cvReleaseImage( &imgA );
cvDestroyWindow("window");
return 0;
}
/********** [ここから コールバック] ****************/
void Mouse( int event, int x, int y, int flags ,void *imgA) // コールバック関数
{
static bool MOUSE_FLAG=false;
switch(event)
{
case CV_EVENT_LBUTTONDOWN:
MOUSE_FLAG = true;
cvRectangle((IplImage*)imgA,cvPoint(x,y),cvPoint(x,y),cvScalar(255,0,0),5);
cvShowImage("window",(IplImage*)imgA);
break;
case CV_EVENT_LBUTTONUP:
MOUSE_FLAG=false;
break;
}
if(event == CV_EVENT_MOUSEMOVE && MOUSE_FLAG == true)
{
cvRectangle((IplImage*)imgA,cvPoint(x,y),cvPoint(x,y),cvScalar(255,0,0),5);
cvShowImage("window",(IplImage*)imgA);
}
}
メモ
以下のように書き換えると、早く動かしても途切れない。
/******** [ここから コールバック]*********/
int Xstart,Ystart;
int xdis,ydis;
void Mouse( int event, int x, int y, int flags ,void *imgA) // コールバック関数
{
static bool MOUSE_FLAG=false;
switch(event)
{
case CV_EVENT_LBUTTONDOWN:
MOUSE_FLAG = true;
Xstart = x;
Ystart = y;
cvRectangle((IplImage*)imgA,cvPoint(x,y),cvPoint(x,y),cvScalar(255,0,0),5);
cvShowImage("window",(IplImage*)imgA);
break;
case CV_EVENT_LBUTTONUP:
MOUSE_FLAG=false;
break;
}
if(event == CV_EVENT_MOUSEMOVE && MOUSE_FLAG == true)
{
xdis = abs(x - Xstart);
ydis = abs(y - Ystart);
if(xdis > 1 || ydis > 1)
{
cvLine((IplImage*)imgA,cvPoint(x,y),cvPoint(Xstart,Ystart),cvScalar(255,0,0),5);
}else
{
cvRectangle((IplImage*)imgA,cvPoint(x,y),cvPoint(x,y),cvScalar(255,0,0),5);
}
cvShowImage("window",(IplImage*)imgA);
Xstart = x;
Ystart = y;
}
}