0
点赞
收藏
分享

微信扫一扫

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


导 读

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

实现步骤

    核心思路是使用距离变换来获取最大内切圆,具体步骤如下:

白色(255)。

    测试原图:

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

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

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

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

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

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

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

    【4】其他图像测试:

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

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

实现源码


  Python-OpenCV源码:

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源码:

#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 条评论