OpenCV轮廓分析

简介: OpenCV轮廓分析

1.轮廓发现

  • 基于联通组件
  • 反映图像拓扑结构
void outline_demo()
{
  QString appPath = QCoreApplication::applicationDirPath();
  QString imagePath = appPath + "/morph3.png";
  Mat img = cv::imread(imagePath.toStdString());
  if (img.empty()) {
    return;
  }
  namedWindow("input", WINDOW_AUTOSIZE);
  imshow("input", img);
  //高斯模糊:降噪
  GaussianBlur(img, img, Size(3, 3), 0);
  //To gray image
  Mat gray, binary;
  cvtColor(img, gray, COLOR_BGR2GRAY);
  imshow("gray", gray);
  //OTSU
  double m_otsu = threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
  imshow("BINARY", binary);
  vector<vector<Point>> contours;
  vector<Vec4i> hierachy;
  findContours(binary, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
  drawContours(img, contours, -1, Scalar(0, 0, 255), 2, 8);
  imshow("outline", img);
  waitKey();
  destroyAllWindows();
}

2.轮廓分析

void outline_analysis_demo()
{
  QString appPath = QCoreApplication::applicationDirPath();
  QString imagePath = appPath + "/zhifang_ball.png";
  Mat img = cv::imread(imagePath.toStdString());
  if (img.empty()) {
    return;
  }
  namedWindow("input", WINDOW_AUTOSIZE);
  imshow("input", img);
  //高斯模糊:降噪
  GaussianBlur(img, img, Size(3, 3), 0);
  //To gray image
  Mat gray, binary;
  cvtColor(img, gray, COLOR_BGR2GRAY);
  imshow("gray", gray);
  //OTSU
  double m_otsu = threshold(gray, binary, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
  imshow("BINARY", binary);
  vector<vector<Point>> contours;
  vector<Vec4i> hierachy;
  findContours(binary, contours, hierachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
  for (size_t t = 0; t < contours.size(); t++)
  {
    double area = contourArea(contours[t]);
    double size = arcLength(contours[t],true);
    qDebug() << "area:" << area << "  " << "size:" << size;
    if (area < 100 || size < 10) continue;
    //最大矩形
    Rect box = boundingRect(contours[t]);
    rectangle(img,box,Scalar(0,0,255),2,8,0);
    //最小矩形
    RotatedRect rrt = minAreaRect(contours[t]);
    ellipse(img, rrt, Scalar(255, 0, 0), 2, 8);
    Point2f pts[4];
    rrt.points(pts);
    for (int i = 0; i < 4; i++)
    {
      line(img, pts[i], pts[(i + 1) % 4], Scalar(0, 255, 0), 2, 8);
    }
    //绘制轮廓
    drawContours(img, contours, t, Scalar(0, 0, 255), 2, 8);
  }
  imshow("outline", img);
  waitKey();
  destroyAllWindows();
}

3.轮廓匹配

void outline_match_demo()
{
  QString appPath = QCoreApplication::applicationDirPath();
  Mat img1 = cv::imread(appPath.toStdString() + "/abc.png");
  Mat img2 = cv::imread(appPath.toStdString() + "/a5.png");
  if (img1.empty() || img2.empty()) {
    return;
  }
  imshow("input1", img1);
  imshow("input2", img2);
  vector<vector<Point>> contours1,contours2;
  contour_info(img1, contours1);
  contour_info(img2, contours2);
  Moments mm2 = moments(contours2[0]);
  Mat hu2;
  HuMoments(mm2, hu2);
  for (size_t t = 0; t < contours1.size(); t++)
  {
    Moments mm = moments(contours1[t]);
    double cx = mm.m10 / mm.m00;
    double cy = mm.m01 / mm.m00;
    circle(img1,Point(cx, cy), 3, Scalar(255, 0, 0), 2,8, 0);
    Mat hu;
    HuMoments(mm, hu);
    double dist = matchShapes(hu, hu2, CONTOURS_MATCH_I1,0);
    if (dist < 1.0)
    {
      drawContours(img1, contours1, t, Scalar(0, 0, 255), 2, 8);
    }
  }
  imshow("match contrours demo", img1);
  waitKey();
  destroyAllWindows();
}
void contour_info(Mat &image, vector<vector<Point>> &contours)
{
  //高斯模糊:降噪
  GaussianBlur(image, image, Size(3, 3), 0);
  //To gray image
  Mat gray, binary;
  cvtColor(image, gray, COLOR_BGR2GRAY);
  //OTSU
  double m_otsu = threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
  vector<Vec4i> hierachy;
  findContours(binary, contours, hierachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
  
}

4.多边形逼近

void outline_fit_clicked()
{
  QString appPath = QCoreApplication::applicationDirPath();
  QString imagePath = appPath + "/contours.png";
  Mat img = cv::imread(imagePath.toStdString());
  if (img.empty()) {
    return;
  }
  namedWindow("input", WINDOW_AUTOSIZE);
  imshow("input", img);
  //高斯模糊:降噪
  GaussianBlur(img, img, Size(3, 3), 0);
  //To gray image
  Mat gray, binary;
  cvtColor(img, gray, COLOR_BGR2GRAY);
  imshow("gray", gray);
  //OTSU
  double m_otsu = threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
  imshow("BINARY", binary);
  vector<vector<Point>> contours;
  vector<Vec4i> hierachy;
  findContours(binary, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
  //多边形逼近
  for (size_t t = 0; t < contours.size(); t++)
  {
    Moments mm = moments(contours[t]);
    double cx = mm.m10 / mm.m00;
    double cy = mm.m01 / mm.m00;
    circle(img, Point(cx, cy), 3, Scalar(255, 0, 0), 2, 8, 0);
    double area = contourArea(contours[t]);
    double clen = arcLength(contours[t], true);
    
    Mat result;
    approxPolyDP(contours[t], result, 4, true);
    qDebug() << result.rows << " " << result.cols;
    if (result.rows == 6)
    {
      putText(img, "poly", Point(cx,cy-10), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 0, 255), 1,8);
    }
    if (result.rows == 4)
    {
      putText(img, "rectangle", Point(cx, cy - 10), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 0, 255), 1, 8);
    }
    if (result.rows == 3)
    {
      putText(img, "trriangle", Point(cx, cy - 10), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 0, 255), 1, 8);
    }
    if (result.rows >10)
    {
      putText(img, "circle", Point(cx, cy - 10), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 0, 255), 1, 8);
    }
  }
  imshow("多边形逼近", img);
  waitKey();
  destroyAllWindows();
}

5.拟合圆和椭圆

void actual::fit_circle_demo(Mat &image)
{
  //To gray image
  Mat gray, binary;
  cvtColor(image, gray, COLOR_BGR2GRAY);
  //OTSU
  double m_otsu = threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
  vector<vector<Point>> contours;
  vector<Vec4i> hierachy;
  findContours(binary, contours, hierachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
  //多边形逼近
  for (size_t t = 0; t < contours.size(); t++)
  {
    RotatedRect rrt = fitEllipse(contours[t]);
    float w = rrt.size.width;
    float h = rrt.size.height;
    Point center = rrt.center;
    circle(image, center, 3, Scalar(255.0, 0), 2, 8, 0);
    ellipse(image, rrt, Scalar(0, 255, 0), 2, 8);
  }
  imshow("拟合圆和椭圆", image);
}


相关文章
|
6月前
|
计算机视觉 Python
OpenCV轮廓拟合与凸包的讲解与实战应用(附Python源码)
OpenCV轮廓拟合与凸包的讲解与实战应用(附Python源码)
186 0
|
计算机视觉
OpenCV-计算轮廓周长cv::arcLength
OpenCV-计算轮廓周长cv::arcLength
137 0
|
5月前
|
存储 编解码 算法
【Qt&OpenCV 检测图像中的线/圆/轮廓 HoughLinesP/HoughCircles/findContours&drawContours】
【Qt&OpenCV 检测图像中的线/圆/轮廓 HoughLinesP/HoughCircles/findContours&drawContours】
91 0
|
6月前
|
算法 计算机视觉 开发者
OpenCV图形检测中绘制图像的轮廓讲解与实战应用(附Python源码)
OpenCV图形检测中绘制图像的轮廓讲解与实战应用(附Python源码)
193 0
|
6月前
|
算法 Serverless 计算机视觉
【OpenCV】- 多边形将轮廓包围
【OpenCV】- 多边形将轮廓包围
|
计算机视觉
OpenCV-计算轮廓面积cv::contourArea
OpenCV-计算轮廓面积cv::contourArea
249 0
|
6月前
|
存储 计算机视觉 索引
【OpenCV】-查找并绘制轮廓
【OpenCV】-查找并绘制轮廓
|
存储 算法 计算机视觉
【OpenCV图像处理8】图像轮廓
【OpenCV图像处理8】图像轮廓
274 0
|
6月前
|
计算机视觉
OpenCV(三十四):轮廓外接最大、最小矩形和多边形拟合
OpenCV(三十四):轮廓外接最大、最小矩形和多边形拟合
469 0
|
6月前
|
计算机视觉
OpenCV(三十三):计算轮廓面积与轮廓长度
OpenCV(三十三):计算轮廓面积与轮廓长度
258 0