OpenCv获取图像中椭圆长短轴的点的位置

   OpenCv获取图像中椭圆长短轴的点的位置_第1张图片

 目的是得到长短轴上的灰度变化曲线

1 首先使用Opencv的  FindContour   fitEllipse  可以得到旋转矩形

2 然后获取矩形长轴和短轴的位置,然后根据位置得到灰度值,最后得到曲线

关键在于如何获取长短轴的位置

   1 .先得到两个点的方程,并获取线段方程上的点的位置

         p0 线段起点  p1 线段终点 points 线段上所有点

void GetLocation(cv::Point p0,cv::Point p1,std::vector &points){
  int a1 = p1.y - p0.y;
  int b1 = p0.x - p1.x;
  int c1 = p0.x * p1.y - p1.x * p0.y;

  int  xDis = p1.x - p0.x;  //x的增量
  int	 yDis = p1.y - p0.y;  //y的增量

  int x0 =(std:: min(p0.x, p1.x));
  int y0 = (std::min(p0.y, p1.y));
  if (abs(xDis) > abs(yDis)) {
    for (int i = 0; i < abs(xDis); i++) {
      x0 = x0 + 1;
      y0 = std::round((double)(c1 - a1 * x0) / b1);
      points.push_back(cv::Point(x0,y0));
    }
  }
  else {
    for (int i = 0; i < abs(yDis); i++) {
      y0 = y0 + 1;
      x0 = std::round((double)(c1 - b1 * y0) / a1);
      points.push_back(cv::Point(x0,y0));
    }
  }
}

思路很简单,先得到直线方程一般式的参数 a b c (初中数学知识)

然后朝着x 方向或者 y 方向遍历,为了使点的数量尽可能多,这里判断一下if (abs(xDis) > abs(yDis)) 

2. 只需要把 p0  p1 换成矩形上两个长边中点或者短边中点,下面是中点求解方法

 

    //cv::RotatedRect box; //椭圆拟合得到的box
  
    double x = box.center.x;
    double y = box.center.y;
    double th = (box.angle);
    double h = box.size.height/2;
    double w = box.size.width/2;
    double cos  = std::cos(th * pi / 180);
    double sin = std::sin(th * pi / 180);
      //短边的 p0 p1 得到长轴
      cv::Point  Long_axis0 = (cv::Point(round(x + cos * w), round(y + w * sin)));
      cv::Point  Long_axis1 = (cv::Point(round(x - cos * w), round(y - w * sin)));
      //长边的 p0 p1 得到短轴
      cv::Point  short_axis0 = cv::Point(round(x - sin * h), round(y + h * cos));
      cv::Point  short_axis1 = cv::Point(round(x + sin * h), round(y  - h * cos));


// 初中几何知识

3. 遍历 各个Point  就可得到灰度值,绘制曲线用QT charts

你可能感兴趣的:(opencv,qt,c++,opencv)