1 直线的方程
假设opencv中有一个M*N的图像,直线起点为(x0,y0),直线中点为(x1,y1)。需要从起点到终点画一条直线。直线的方程为:
f(x,y)=(x1-x0)y+(y0-y1)x+c=0=ay+bx+c,其中a=x1-x0,b=y0-y1
当某点(x,y)在直线下方时,f(x,y)<0;当某点(x,y)在直线上时,f(x,y)=0;当某点(x,y)在直线上方时,f(x,y)>0;
2 中点画线法
现在假设点P1(x,y)在直线上,并且假设该直线的斜率大于0,则P1的下一点只能在P2(x+1,y)与P3(x+1,y+1)中选取。P2和P3的中点为M(x+1,y+0.5)。若f(M)=f(x+1,y+0.5)<0,则M在直线下方,P3点离直线更近,应该选择P3;若M点在直线上方,则P2点离直线更近,应该选择P2。
将M点坐标带入f(x,y),得到判别式d:
d=a(x+1)+b(y+0.5)+c
若d<0,则选择P3(x+1,y+1)
新的判别等式为:
d’= a(x+2)+b(y+1.5)+c=d+(a+b)
若d>=0,则选择P2(x+1,y)
新的判别等式为:
d’= a(x+2)+b(y+0.5)+c=d+a
特别的,初始点的d为:
d0=a(x0+1)+b(y0+0.5)+c=a+0.5*b
按照以上算法遍历从x0到x1的坐标点,则可以画出最接近的直线。
3 opencv3中的程序实现
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
//此程序对于OpenCV3版需要额外包含头文件:
#include <opencv2/imgproc/imgproc.hpp>
#define WINDOW_NAME1 "【绘制图1】" //为窗口标题定义的宏
#define WINDOW_NAME2 "【绘制图2】" //为窗口标题定义的宏
#define WINDOW_WIDTH 600//定义窗口大小的宏
void DrawLine( Mat img, Point start, Point end );//绘制线段
void MP_Circle(Mat img,intr);
void MP_Line(Mat img,intx0,int y0,intx1,int y1);
int main( void )
{
// 创建空白的Mat图像
Mat rookImage = Mat::zeros(WINDOW_WIDTH, WINDOW_WIDTH, CV_8UC3 );
MP_Circle(rookImage,WINDOW_WIDTH/2);
MP_Line(rookImage,0,0,WINDOW_WIDTH,WINDOW_WIDTH);
//---------------------------<3>显示绘制出的图像------------------------
namedWindow(WINDOW_NAME1);
imshow( WINDOW_NAME1, rookImage );
waitKey( 0 );
return(0);
}
void drawPoint(Mat img,Point pt)
{
intthickness = 1;
intlineType = 8;
line( img,
pt,
Point(pt.x+1,pt.y),
Scalar( 255, 255, 255 ),
thickness,
lineType );
}
void MP_Circle(Mat img,intr)
{
int x, y;
double d;
x = 0;
y = r;
d = 1.25-r;
drawPoint(img,Point(x,y));
while(x< y)
{
if(d< 0)
{
d = d + 2 * x + 3;
}
else
{
d = d + 2 * ( x - y ) + 5;
y--;
}
x++;
drawPoint(img,Point(x+r , r-y));
drawPoint(img,Point(x+r,r+y));
drawPoint(img,Point(-x+r,r-y));
drawPoint(img,Point(-x+r,r+y));
drawPoint(img,Point(r-y,x+r));
drawPoint(img,Point(r+y,x+r));
drawPoint(img,Point(r-y,-x+r));
drawPoint(img,Point(r+y,-x+r));
}
}
void MP_Line(Mat img,intx0,int y0,intx1,int y1)
{
inta=y0-y1;
intb=x1-x0;
intd=a+0.5*b;
intx=x0;
inty=y0;
while(x<x1)
{
if(d>0)
{
d += a;
}
else
{
d += a+b;
y++;
}
x++;
drawPoint(img,Point(x,y));
}
}
效果图: