干货 | OpenCV获取不规则区域的最大内切圆(附Python / C++ 源码)

2022-09-26 10:14:08 浏览数 (1)

导 读

本文主要介绍如何使用OpenCV获取不规则区域的最大内切圆。(公众号:OpenCV与AI深度学习)

实现步骤 核心思路是使用距离变换来获取最大内切圆,具体步骤如下: 【1】将目标轮廓/区域提取出来,处理成二值图:目标区域白色(255),背景黑色(0),并将目标区域填充为白色(255)。 测试原图:

二值化 轮廓提取 填充绘制:

【2】距离变换:获取距离变换结果最大值及其坐标。

【3】绘制结果:距离变换结果最大值为半径,对应位置为内切圆圆心。

【4】其他图像测试:

实现源码 Python-OpenCV源码:

代码语言:javascript复制

import cv2
import numpy as np

src = cv2.imread('2.png')
cv2.imshow('src',src)

gray = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)
gray[gray > 127] = 255
cv2.imshow('thres',gray)

contours,hierarchy = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

mask = np.zeros(gray.shape,np.uint8)
cv2.drawContours(mask,contours,0,(255,255,255),-1)
cv2.imshow('mask',mask) 

dt = cv2.distanceTransform(mask,cv2.DIST_L2,5,cv2.DIST_LABEL_PIXEL)
transImg = cv2.convertScaleAbs(dt)
cv2.normalize(transImg, transImg, 0, 255, cv2.NORM_MINMAX)
cv2.imshow("distanceTransform", transImg)

_, max_val, _, max_loc = cv2.minMaxLoc(dt)
cv2.circle(src,max_loc, int(max_val),(0,0,255), 2)
cv2.imshow('result',src)

cv2.waitKey(0)
cv2.destroyAllWindows()

C OpenCV源码:

代码语言:javascript复制

#include "pch.h"
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
  Mat src = imread("1.png");
  Mat gray;
  cvtColor(src, gray, COLOR_BGR2GRAY);

  // threshold
  Mat1b thres = gray > 127;
  imshow("thres", thres);

  vector<vector<Point>>contours;
  findContours(thres, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

  // 填充轮廓
  Mat1b mask(thres.rows, thres.cols, uchar(0));
  drawContours(mask, contours, 0, Scalar(255), -1);

  // 距离变换
  Mat1f dt;
  distanceTransform(mask, dt, DIST_L2, 5, DIST_LABEL_PIXEL);
   
  Mat1b transImg;
  normalize(dt, transImg, 0, 255, NORM_MINMAX);
  imshow("distanceTransform", transImg);

  //查找最大值
  double max_val;
  Point max_loc;
  minMaxLoc(dt, nullptr, &max_val, nullptr, &max_loc);
  cout << max_loc << endl;
  cout << max_val << endl;
  cv::circle(src, max_loc, max_val, cv::Scalar(0, 0, 255), 2);
  imshow("result", src);
  waitKey();
  return 0;
}

—THE END—

0 人点赞