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)); } }
效果图: