导 读
本文主要介绍如何使用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—