• 【OpenCV学习】Bresenham算法


    作者:gnuhpc
    出处:http://www.cnblogs.com/gnuhpc/

    /*
     * =====================================================================================
     *
     *       Filename:  linebresenham2.c
     *
     *    Description:  A program for bresenham ,any point you want
     *
     *        Version:  1.0
     *        Created:  01/08/2009 10:36:37 AM
     *       Revision:  none
     *       Compiler:  gcc
     *
     *         Author:  Futuredaemon (BUPT), gnuhpc@gmail.com
     *        Company:  BUPT_UNITED
     *
     * =====================================================================================
     */
    #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};//窗口大小 
    
    CvPoint p1;
    CvPoint p2;
    int number;
    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); 
    
      cvReleaseImage( &imgA );
      cvDestroyWindow("window");
    
      return 0;
    }
    
    void Mouse( int event, int x, int y, int flags ,void *param = NULL) //记录点
    {
    
      switch (event)
        {
    
        case CV_EVENT_LBUTTONDOWN:
    
          if (number == 0)
            {
              printf("p1:(%d,%d) /n",x,y);
              cvSet (imgA, cvScalarAll (0), 0);
              cvShowImage("window",imgA);
    
              p1.x = x;
              p1.y = y;
              number++;
    
            }
          else if (number == 1)
            {
              printf("p2:(%d,%d) /n",x,y);
              puts("---------------");
              p2.x = x;
              p2.y = y;
              number =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) 
        {
          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)
        {
    
          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;
            }
    
        }
    }
    
    

    作者:gnuhpc
    出处:http://www.cnblogs.com/gnuhpc/


                   作者:gnuhpc
                   出处:http://www.cnblogs.com/gnuhpc/
                   除非另有声明,本网站采用知识共享“署名 2.5 中国大陆”许可协议授权。


    分享到:

  • 相关阅读:
    Android滑动菜单框架完全解析,教你如何一分钟实现滑动菜单特效
    Android滑动菜单特效实现,仿人人客户端侧滑效果,史上最简单的侧滑实现
    Android桌面悬浮窗效果实现,仿360手机卫士悬浮窗效果
    各产品编译及串口烧录
    C 语言代码规范
    烧录
    共享目录
    openwrt Makefile
    netfilter 参考pywj的《netfilter + nf_conntrack + iptables》
    iptables问题
  • 原文地址:https://www.cnblogs.com/gnuhpc/p/2806670.html
Copyright © 2020-2023  润新知