最終更新: mikk_ni3_92 2008年02月22日(金) 09:12:30履歴
現在地 >> メニュー >> サンプルコード::OpenCV >> Bresenhamのアルゴリズムでの直線 >> Bresenhamのアルゴリズムでの直線2
#include <cv.h>
#include <highgui.h>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <iostream>
using namespace std;
void Mouse( int event, int x, int y, int flags ,void *param);
void DRAW_LINE(CvPoint *p1, CvPoint *p2);
int CHECK_DIRECTION(char *str ,CvPoint *p1, CvPoint *p2);
void PUT_PIXEL_X(CvPoint *p1, CvPoint *p2,int &sx, int &sy,int &dx, int &dy);
void PUT_PIXEL_Y(CvPoint *p1, CvPoint *p2,int &sx, int &sy,int &dx, int &dy);
CvSize window={300,300};//ウィンドウサイズ
IplImage *imgA;
int main( int argc, char **argv)
{
imgA = cvCreateImage(window,IPL_DEPTH_8U,3);
cvSet (imgA, cvScalarAll (0), 0);
cvNamedWindow("window",CV_WINDOW_AUTOSIZE);
cvShowImage("window",imgA);
cvSetMouseCallback("window", Mouse);
cvWaitKey(0); // 0秒待つ => ずっと入力待ち
cvReleaseImage( &imgA );
cvDestroyWindow("window");
return 0;
}
/***************[ここから コールバック]****************/
CvPoint p1;
CvPoint p2;
int count;
void Mouse( int event, int x, int y, int flags ,void *param = NULL) // コールバック関数
{
switch(event)
{
case CV_EVENT_LBUTTONDOWN:
if(count == 0)
{
printf("p1:(%d,%d) \n",x,y);
cvSet (imgA, cvScalarAll (0), 0);
cvShowImage("window",imgA);
p1.x = x;
p1.y = y;
count++;
}else if(count == 1)
{
printf("p2:(%d,%d) \n",x,y);
puts("---------------");
p2.x = x;
p2.y = y;
count =0;
DRAW_LINE(&p1,&p2);
}
cvShowImage("window",imgA);
break;
}
}
/***[ここから各種関数]***/
void DRAW_LINE(CvPoint *p1, CvPoint *p2)
{
/*初期値代入*/
int dx = abs(p1->x - p2->x);
int dy = abs(p1->y - p2->y);
int sx = CHECK_DIRECTION("x",p1,p2); //進行方向決定(x軸)
int sy = CHECK_DIRECTION("y",p1,p2);//進行方向決定(y軸)
/*ここから描画*/
if(dx >= dy)
{
PUT_PIXEL_X(p1,p2,sx,sy,dx,dy);
}else
{
PUT_PIXEL_Y(p1,p2,sx,sy,dx,dy);
}
}
/*方向チェック*/
int CHECK_DIRECTION(char *str ,CvPoint *p1, CvPoint *p2)
{
if(strncmp(str,"x",1)== 0)
{
if(p1->x >= p2->x)
{
return -1;
}else
{
return 1;
}
}else if(strncmp(str,"y",1)== 0)
{
if(p1->y >= p2->y)
{
return -1;
}else
{
return 1;
}
}else
{
printf("CHECK_DIRECTION is fault.\n");
std::exit(0);
}
}
/*X軸方向に走査*/
void PUT_PIXEL_X(CvPoint *p1, CvPoint *p2,int &sx, int &sy ,int &dx, int &dy)
{
int a = 2*dy;
int a1= a-2*dx;
int e = a - dx;
int x = p1->x;
int y = p1->y;
for(x = p1->x; (sx >=0 ? x<= p2->x : x>=p2->x) ;x+=sx) // |傾き| <= 1
{
imgA->imageData[y*imgA->widthStep + x*3] = (signed char)255;
imgA->imageData[y*imgA->widthStep + x*3+1] = (signed char)255;
imgA->imageData[y*imgA->widthStep + x*3+2] = (signed char)255;
if (e>=0)
{
y+=sy;
e += a1;
}else
{
e+=a;
}
}
}
/*Y軸方向に走査*/
void PUT_PIXEL_Y(CvPoint *p1, CvPoint *p2,int &sx, int &sy ,int &dx, int &dy)
{
int a = 2*dx;
int a1= a-2*dy;
int e = a - dy;
int x = p1->x;
int y = p1->y;
for(y = p1->y; (sy >=0 ? y<= p2->y : y>=p2->y) ;y+=sy)// |傾き| > 1
{
imgA->imageData[y*imgA->widthStep + x*3] = (signed char)255;
imgA->imageData[y*imgA->widthStep + x*3+1] = (signed char)255;
imgA->imageData[y*imgA->widthStep + x*3+2] = (signed char)255;
if (e>=0)
{
x+=sx;
e += a1;
}else
{
e+=a;
}
}
}
#include <cv.h>
#include <highgui.h>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <iostream>
using namespace std;
void Mouse( int event, int x, int y, int flags ,void *param);
void DRAW_LINE(CvPoint *p1, CvPoint *p2);
int CHECK_DIRECTION(char *str ,CvPoint *p1, CvPoint *p2);
void PUT_PIXEL_X(CvPoint *p1, CvPoint *p2,int &sx, int &sy,int &dx, int &dy);
void PUT_PIXEL_Y(CvPoint *p1, CvPoint *p2,int &sx, int &sy,int &dx, int &dy);
CvSize window={300,300};//ウィンドウサイズ
IplImage *imgA;
int main( int argc, char **argv)
{
imgA = cvCreateImage(window,IPL_DEPTH_8U,3);
cvSet (imgA, cvScalarAll (0), 0);
cvNamedWindow("window",CV_WINDOW_AUTOSIZE);
cvShowImage("window",imgA);
cvSetMouseCallback("window", Mouse);
cvWaitKey(0); // 0秒待つ => ずっと入力待ち
cvReleaseImage( &imgA );
cvDestroyWindow("window");
return 0;
}
/***************[ここから コールバック]****************/
CvPoint p1;
CvPoint p2;
int count;
void Mouse( int event, int x, int y, int flags ,void *param = NULL) // コールバック関数
{
switch(event)
{
case CV_EVENT_LBUTTONDOWN:
if(count == 0)
{
printf("p1:(%d,%d) \n",x,y);
cvSet (imgA, cvScalarAll (0), 0);
cvShowImage("window",imgA);
p1.x = x;
p1.y = y;
count++;
}else if(count == 1)
{
printf("p2:(%d,%d) \n",x,y);
puts("---------------");
p2.x = x;
p2.y = y;
count =0;
DRAW_LINE(&p1,&p2);
}
cvShowImage("window",imgA);
break;
}
}
/***[ここから各種関数]***/
void DRAW_LINE(CvPoint *p1, CvPoint *p2)
{
/*初期値代入*/
int dx = abs(p1->x - p2->x);
int dy = abs(p1->y - p2->y);
int sx = CHECK_DIRECTION("x",p1,p2); //進行方向決定(x軸)
int sy = CHECK_DIRECTION("y",p1,p2);//進行方向決定(y軸)
/*ここから描画*/
if(dx >= dy)
{
PUT_PIXEL_X(p1,p2,sx,sy,dx,dy);
}else
{
PUT_PIXEL_Y(p1,p2,sx,sy,dx,dy);
}
}
/*方向チェック*/
int CHECK_DIRECTION(char *str ,CvPoint *p1, CvPoint *p2)
{
if(strncmp(str,"x",1)== 0)
{
if(p1->x >= p2->x)
{
return -1;
}else
{
return 1;
}
}else if(strncmp(str,"y",1)== 0)
{
if(p1->y >= p2->y)
{
return -1;
}else
{
return 1;
}
}else
{
printf("CHECK_DIRECTION is fault.\n");
std::exit(0);
}
}
/*X軸方向に走査*/
void PUT_PIXEL_X(CvPoint *p1, CvPoint *p2,int &sx, int &sy ,int &dx, int &dy)
{
int a = 2*dy;
int a1= a-2*dx;
int e = a - dx;
int x = p1->x;
int y = p1->y;
for(x = p1->x; (sx >=0 ? x<= p2->x : x>=p2->x) ;x+=sx) // |傾き| <= 1
{
imgA->imageData[y*imgA->widthStep + x*3] = (signed char)255;
imgA->imageData[y*imgA->widthStep + x*3+1] = (signed char)255;
imgA->imageData[y*imgA->widthStep + x*3+2] = (signed char)255;
if (e>=0)
{
y+=sy;
e += a1;
}else
{
e+=a;
}
}
}
/*Y軸方向に走査*/
void PUT_PIXEL_Y(CvPoint *p1, CvPoint *p2,int &sx, int &sy ,int &dx, int &dy)
{
int a = 2*dx;
int a1= a-2*dy;
int e = a - dy;
int x = p1->x;
int y = p1->y;
for(y = p1->y; (sy >=0 ? y<= p2->y : y>=p2->y) ;y+=sy)// |傾き| > 1
{
imgA->imageData[y*imgA->widthStep + x*3] = (signed char)255;
imgA->imageData[y*imgA->widthStep + x*3+1] = (signed char)255;
imgA->imageData[y*imgA->widthStep + x*3+2] = (signed char)255;
if (e>=0)
{
x+=sx;
e += a1;
}else
{
e+=a;
}
}
}