opencv实现中点法画线

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));
         }
}


效果图:


猜你喜欢

转载自blog.csdn.net/liuzhijun301/article/details/78321251