• 怎么求不规则图像的最小外接圆
2021-04-18 16:54:33

I=imread('matlab2.png');

BW=im2bw(I);

BW=BW(20:270,20:218);

figure,imshow(BW),hold on

se=[0 1 0;1 1 1;0 1 0];

BW=imdilate(BW,se);

figure,imshow(BW),hold on

L=bwlabel(BW);

stats=regionprops(L,'BoundingBox');

temp=stats.BoundingBox;

rectangle('position',temp,'edgecolor','r');

BW=BW(floor(temp(2))-1:floor(temp(2)+temp(4))+1,floor(temp(1))-1:floor(temp(1)...

+temp(3))+1);

BW=edge(BW,'canny');

figure,imshow(BW),hold on

[y,x]=find(BW==1);

[m,index]=max(y);

y_max=m;

x_max=x(index);

text(x_max, y_max,'A','color','red')

distance_max=0;

for k=1:size(x)

distance=norm(([x(k),y(k)]-[x_max,y_max]),2);

if(distance>distance_max) distance_max=distance;

index_dis_max=k;

end

end

text(x(index_dis_max), y(index_dis_max),'B','color','red'),hold on

text(71.5, 86.5,'M','color','red'),hold on

P1=[x_max,x(index_dis_max)];

P2=[y_max,y(index_dis_max)];

P_Mind=[(x_max+x(index_dis_max))/2,(y_max+y(index_dis_max))/2];

%A到B画线

a=polyfit(P1,P2,1);

if(x_max>x(index_dis_max)) x_line=x(index_dis_max):0.5:x_max;

else x_line=x_max:0.5:x(index_dis_max);

end

y_line=a(1).*x_line+a(2);

for k=1:size(x_line)

text(x_line, y_line,'-','color','yellow'),hold on

end

distance_PtoLmax=0;

for k1=1:size(x)

distance_PtoL=abs((a(1).*x(k1)-y(k1)+a(2))./(sqrt(a(1).^2+a(2).^2)));

if(distance_PtoL>distance_PtoLmax) distance_PtoLmax=distance_PtoL;

distance_PtoLmax=k1;

end

end

text(x(distance_PtoLmax), y(distance_PtoLmax),'C','color','red'),hold on

%A到C画线

P3=[x_max,x(distance_PtoLmax)];

P4=[y_max, y(distance_PtoLmax)];

a1=polyfit(P3,P4,1);

if(x_max>x(distance_PtoLmax)) x_line1=x(distance_PtoLmax):0.5:x_max;

else x_line1=x_max:0.5:x(distance_PtoLmax);

end

y_line1=a1(1).*x_line1+a1(2);

for k=1:size(x_line1)

text(x_line1, y_line1,'-','color','yellow'),hold on

end

%B到C画线

P5=[x(index_dis_max),x(distance_PtoLmax)];

P6=[y(index_dis_max), y(distance_PtoLmax)];

a2=polyfit(P5,P6,1);

if(x(index_dis_max)>x(distance_PtoLmax)) x_line2=x(distance_PtoLmax):...

0.5:x(index_dis_max);

else x_line2=x(index_dis_max):0.5:x(distance_PtoLmax);

end

y_line2=a2(1).*x_line2+a2(2);

for k=1:size(x_line1)

text(x_line2, y_line2,'-','color','yellow'),hold on

end

%海伦公式求圆心 A B  C 三点上面已经 求出  分别是  A(x_max，y_max)，

% B(x(index_dis_max),y(index_dis_max)),

%C(x(distance_PtoLmax), y(distance_PtoLmax)).

%求 AB,AC,BC的长度 L_AB,L_AC,L_BC

A=[x_max,y_max];

B=[x(index_dis_max),y(index_dis_max)];

C=[x(distance_PtoLmax),y(distance_PtoLmax)];

L_AB=norm((A-B),2);

L_AC=norm((A-C),2);

L_BC=norm((B-C),2);

R=(L_AB.*L_AC.*L_BC)./sqrt((L_AB+L_AC+L_BC).*(L_AB+L_AC-L_BC)...

.*(L_AB-L_AC+L_BC).*(-L_AB+L_AC+L_BC));

%求圆心

syms m n;

s1=sqrt((A(1)-m)^2+(A(2)-n)^2);

s2=sqrt((B(1)-m)^2+(B(2)-n)^2);

s3=sqrt((C(1)-m)^2+(C(2)-n)^2);

eq1=s1-s2;

eq2=s2-s3;

[m,n]=solve(eq1,eq2,'m','n');

m=double(m);

n=double(n);

% 圆心 m,n  半径 R rectangle 画圆

theta=0:pi/100:2*pi;

m1=R.*cos(theta)+m;

n1=R.*sin(theta)+n;

for k=1:size(m1)

text(m1, n1,'。','color','red'),hold on

end

% [row,col]=find(BW==1);

% plot(mean(row),mean(col));

% text(mean(row),mean(col),'C','color','white');

%

%

% text(0,0,'C','color','white');

%

% text(238,299,'C','color','white');

更多相关内容
• 主要为大家详细介绍了Opencv绘制最小外接矩形、最小外接圆的方法，具有一定的参考价值，感兴趣的小伙伴们可以参考一下
• 在介绍了利用最小外接圆判别准则快速精确求解圆度误差的基本思想和用最小外接圆法评定圆度误差的程序设计技术的基础上，根据最小外接圆法快速精确求解圆度误差的基本思想，利用本文所述的程序设计技术，能够设计出圆...
• 给定点集组成任意多边形，使用matlab求出包含所有点的最小外接圆
• cv2.drawContours(image, [box], 0, (0, 0, 255), 2) # 绘制最小外接圆 (x, y), radius = cv2.minEnclosingCircle(c) center = (int(x), int(y)) radius = int(radius) cv2.circle(image, center, radius, (0, 255, ...

import cv2
import numpy as np

if __name__ == "__main__":
orig = cv2.imread('mask.jpg', flags=cv2.IMREAD_COLOR)
mask = cv2.cvtColor(orig, cv2.COLOR_BGR2GRAY)
_, mask = cv2.threshold(mask, 200, 255, 0)
image = orig.copy()
contours, hierarchy = cv2.findContours(mask, mode=cv2.RETR_LIST, method=cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
# 绘制轮廓
image = cv2.drawContours(image, [c], 0, (255, 0, 0), 2)
# 外接矩形框，没有方向角
x, y, w, h = cv2.boundingRect(c)
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 最小外接矩形框，有方向角
rect = cv2.minAreaRect(c)
print(rect)
box = np.int0(cv2.boxPoints(rect))
cv2.drawContours(image, [box], 0, (0, 0, 255), 2)
# 绘制最小外接圆
(x, y), radius = cv2.minEnclosingCircle(c)
center = (int(x), int(y))
radius = int(radius)
cv2.circle(image, center, radius, (0, 255, 255), 2)
# 用轮廓数据来拟合椭圆
ellipse = cv2.fitEllipse(c)
cv2.ellipse(image, ellipse, (255, 0, 255), 2)
# 直线拟合
rows, cols = image.shape[:2]
[vx, vy, x, y] = cv2.fitLine(c, cv2.DIST_L2, 0, 0.01, 0.01)
lefty = int((-x * vy / vx) + y)
righty = int(((cols - x) * vy / vx) + y)
image = cv2.line(image, (cols - 1, righty), (0, lefty), (0, 0, 255), 2)
cv2.imshow("image", image)
cv2.waitKey(0)


原图

展开全文
• 阐述了最小外接圆法求解圆度误差的基本思想,给出直线准则和三角形准则下圆度误差评定的代数判别方法.依据该方法可以设计圆度误差评定软件,从而实现三坐标测量数据的圆度误差评定.
• 使用opencv画出图形的最小外接矩形与最小外接圆，首先求出图形的轮廓，设有滚动条可以选择最佳阈值，然后画出图形的最小外接圆与最小外接矩形，算法的效果很好！
• 在matlab中有自带的最小外接矩形的函数——regionprops,并没有最小外接圆的计算函数。我今天给大家说一下我的关于绘制目标最小外接圆的思路和方法。 1.首先将任意多边形变成凸多边形。这样做的目的是可以使得最小...

我们在进行数字图像处理时，通常需要获取目标的一些参数，例如，形状，大小，位置等信息。而获取这些信息的常用方法是计算该区域的最小外接矩形，除此之外，我还想到了另一种方法——求目标的最小外接圆。但matlab中并没有计算多边形最小外接圆的函数，所以今天我给大家分享一下关于绘制二值图像中目标区域最小外接圆的思路和方法。

1.首先将任意多边形变成凸多边形。这样做的目的是使该多边形的最小外接圆的圆心落在多边形内部。可以利用regionprops中的convexhull函数实现将任意多边形变成凸多边形。

2.一个多边形最少有两个顶点与外接圆的圆弧接触，而且这两个点应该是距离最远的两个点。所以下一步就是要找到凸多边形的距离最远的两个顶点。

3.用直线连接圆上的任取两点，然后做这条线段的垂直平分线L。可以确定圆心的位置就在L上。这正是做多边形的最小外接圆的理论依据。（如下图所示，绿线为L，红点为圆心O）

4.最后一步就是确定圆心。确定圆心位置的依据是：以该点为圆心，以该点到距离它最远的多边形顶点的距离为半径画圆，此圆若能刚好包围所有的多边形顶点。那么此点便是圆心，所画圆即是多边形最小外接圆。

以上就是全部思路，下面是完整的代码，以及实际测试结果 。

函数代码

function [circle_x,circle_y,R] = FindCircle( bw )
%   此函数用于计算二值区域的最小外接圆，并画在图上
%   输入为一个二值图像，输出为圆心坐标和圆的半径

stats = regionprops(bw,'ConvexImage');%将原始多边形补成一个凸多边形

%%%确定凸多边形的顶点
A=ones(3);  %卷积核
vertex=conv2(stats.ConvexImage,A,'same');%用卷积的方法查找多边形顶点
image_point=vertex<=5;%二值图像image_point用来显示多边形顶点
image_point=image_point.*stats.ConvexImage;%去除伪顶点
[x0,y0]=find(image_point==1);%查找并返回顶点坐标
F1=[];%设置空数组，用来存储顶点坐标
F1(:,1)=x0;
F1(:,2)=y0;

%%%确定距离最远的两个顶点
G=pdist(F1);%计算点与点之间的欧里几德距离
H=squareform(G);%将距离转换为矩阵形式
H=tril(H);%生成下三角矩阵，减少计算量
mx=max(max(H));%进行比较，选出最大的数值，即最大的距离
[h,L]=find(H==mx);%找到最大距离的点在H矩阵中的位置。注：此处可能产生不止一对点
point_1=F1(h(1),:);
point_2=F1(L(1),:);

%%%计算两个点的连线的垂直平分线,多边形外接圆的圆心就在此线上
x1=point_1(1);y1=point_1(2);
x2=point_2(1);y2=point_2(2);
k=(y1-y2)/(x1-x2);
b=((y1+y2)/2)+(x1+x2)/(2*k);%垂直平分线表达式：y=kx+b
X1=round(b*k);  Y1=0;
X2=0;           Y2=round(b);%确定垂直平分线经过的点的坐标
image_line=zeros(size(stats.ConvexImage));%生成一个空白图用作画垂直平分线
[image_line] = BresenhamDrawLine( image_line ,Y1,X1,Y2,X2);%调用直线插补函数，画垂直平分线
[x,y]=find(image_line==1);%查找并返回垂直平分线的坐标
F2=[];%设置空数组，用来存储垂直平分线坐标点
F2(:,1)=x;
F2(:,2)=y;

%%%确定圆心及半径
F=cat(1,F2,F1);%将垂直平分线的坐标数组与多边形顶点坐标数组合并
DIS=pdist(F);%计算垂直平分线坐标点与各个顶点之间的欧里几德距离
matrix_R=squareform(DIS);
matrix_R=tril(matrix_R);
matrix_R=matrix_R(:,1:length(x));
[R,num]=min(max(matrix_R));%进行比较，返回最小外接圆半径和圆心坐标的索引
%以上计算所得的圆心坐标是基于stats.ConvexImage的，
%但是由于stats.ConvexImage与原二值图像大小不一致，所以实际圆心坐标需要做出修改。
[bwx,bwy]=find(bw==1);
startpoint=min(bwx,bwy);%找到原始多边形上的点的坐标值中最小的x和y
circle_x=x(num)+startpoint(1)-1;
circle_y=y(num)+startpoint(2)-1;
end

这其中有关BresenhamDrawLine函数是一个直线插补函数。

原文链接——https://blog.csdn.net/u012526003/article/details/51510633?utm_source=app&app_version=4.17.2&code=app_1562916241&uLinkId=usr1mkqgl919blen

测试程序

clc

img=zeros(20,20);%首先生成一个20×20像素的二值图像
for i=8:15
for j=8:i
img(i,j)=1;
end
end
img(16,9)=1;
img(17,9)=1;
img(18,9)=1;
img(18,10)=1;%在二值图像中随意设计一个多边形区域

figure(1)
subplot(131)
imshow(img)

stats = regionprops(img,'conveximage');%将该区域补成一个凸多边形
subplot(132)
imshow(stats.ConvexImage)

[point_x,point_y,r]=FindCircle(img);%调用findcircle函数，计算区域最小外接圆的半径和圆心坐标
subplot(133)
imshow(img)
hold on
viscircles([point_y,point_x],r,'color','b');%画出该圆
text(point_y,point_x,'o');%标记圆心
hold off  

测试结果如图所示：

初次创作，或有不足之处，欢迎批评指正，欢迎转发、交流。

展开全文
• 最大内接圆，最小外接圆的开源库,内涵参考论文，以及使用例程（带数据）
• 本章内容: 1. 轮廓查找 2. 绘制轮廓 1.搜索轮廓 2.绘制轮廓 输出结果 代码 #include <ostream> #include <opencv.hpp>... 1.... cv::String fileName = "/home/wang/de...

本章内容:

1. 轮廓查找
2. 绘制轮廓

3. 凸包

4.最小外接矩形

5.最小外接圆

6.最小外接椭圆

输出结果

输出结果

输出结果

输出结果：

6. 最小外接椭圆

输出结果

代码

#include <ostream>
#include <opencv.hpp>
#include <math.h>

int main(int argc, char *argv[])
{
/*
本章内容:
1. 轮廓查找
2. 绘制轮廓
3. 凸包
4.最小外接矩形
5.最小外接圆
6.最小外接椭圆
*/
cv::String fileName = "/home/wang/dev/Image/QT.jpg";
cv::String fileName1 = "/home/wang/dev/Image/hei.png";
cv::Mat src = cv::imread(fileName);
cv::Mat src1 = cv::imread(fileName1);
if(src.data == NULL){
printf("图像读入失败\n");
return -1;
}
/* 轮廓查找
* api接口: CV_EXPORTS_W void findContours( InputArray image, OutputArrayOfArrays contours,
OutputArray hierarchy, int mode,
int method, Point offset = Point());
参数分析:
@param contours. std::vector<std::vector<cv::Point> >
@param hierarchy Optional output vector
@param mode Contour retrieval mode, see #RetrievalModes
@param method Contour approximation method, see #ContourApproximationModes
enum RetrievalModes{
RETR_EXTERNAL  = 0,
RETR_LIST      = 1,
RETR_CCOMP     = 2,
RETR_TREE      = 3,
RETR_FLOODFILL = 4
}
enum ContourApproximationModes{
enum ContourApproximationModes {
CHAIN_APPROX_NONE      = 1,
CHAIN_APPROX_SIMPLE    = 2,
CHAIN_APPROX_TC89_L1   = 3,
CHAIN_APPROX_TC89_KCOS = 4
}
*/
cv::imshow("src",src);
cv::Mat dstCany;
cv::Mat gray;
cv::cvtColor(src,gray,cv::COLOR_BGR2GRAY);
cv::Canny(gray,dstCany,50,150);
std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> hierarchy;
cv::findContours(dstCany,contours,hierarchy,cv::RETR_TREE,cv::CHAIN_APPROX_SIMPLE,cv::Point(0,0));
cv::RNG rng(1234);
cv::Mat dst(src.size(),src.type());
/* 绘制轮廓
api接口: CV_EXPORTS_W void drawContours( InputOutputArray image, InputArrayOfArrays contours,
int contourIdx, const Scalar& color,
int thickness = 1, int lineType = LINE_8,
InputArray hierarchy = noArray(),
int maxLevel = INT_MAX, Point offset = Point() );
参数分析:
@param contourIdx Parameter indicating a contour to draw. If it is negative, all the contours are drawn.
@param color Color of the contours.
*/
for(int i=0; i <contours.size();i++){
cv::Scalar color = cv::Scalar(rng.uniform(0,255),rng.uniform(0,255),rng.uniform(0,255));
cv::drawContours(dst,contours,i,color,4);
}

/* 3.凸包
* api接口:CV_EXPORTS_W void convexHull( InputArray points, OutputArray hull,
bool clockwise = false, bool returnPoints = true );
@param points 二维点集，vector
@param hull Output convex hull. vector<Point>
*/
std::vector<cv::Point> hull;
cv::convexHull(contours[0],hull);
for(int i=0;i<hull.size();i++){
cv::line(dst,hull[i],hull[(i+1)%hull.size()],cv::Scalar(0,255,0),4);
}

/* 4.最小外接矩形
apie接口: CV_EXPORTS_W RotatedRect minAreaRect( InputArray points );
*/
cv::RotatedRect rect = cv::minAreaRect(contours[1]);
cv::Point2f Ps[4];
rect.points(Ps);
for(int i=0;i<4;i++) cv::line(dst,Ps[i],Ps[(i+1)%4],cv::Scalar(0,0,255),4);

/* 5.最小外接圆
* api接口: CV_EXPORTS_W void minEnclosingCircle( InputArray points,
CV_OUT Point2f& center, CV_OUT float& radius );
*/
cv::Point2f pc;
float radius;
cv::minEnclosingCircle(contours[2],pc,radius);
cv::circle(dst,pc,radius,cv::Scalar(255,0,0),4);

/*6.最小外接椭圆
* api接口:CV_EXPORTS_W RotatedRect fitEllipse( InputArray points );
*/
cv::RotatedRect ell = cv::fitEllipse(contours[1]);
cv::ellipse(dst,ell,cv::Scalar(0,255,255),4);

cv::imshow("dst",dst);
cv::waitKey(0);
return 1;
}

展开全文
• 2. 作一个包含A,B,C三点的最小圆,圆周可能通过这3点，也可能只通过 其中两点,但包含第3点.后一种情况圆周上的两点一定是位于的一条直 径的两端。 3. 在点集中找出距离第2步所建圆心最远的D点，若D点已在内或...
• 本功能实现任意多边形的最小外接圆，先实现任意多边形的绘制，在通过一个菜单实现绘制这个多边形的最小外接圆
• import cv2 import numpy as np import matplotlib.pyplot as plt img=np.load("E:/prostate3Dmask/0/0.npy") ...(x,y),radius=cv2.minEnclosingCircle(cnt)#利用轮廓计算最小外接圆 print(radius)
• 1.使用材料 制作三角形顶点图层数据，并将每个三角形的三个顶点赋值为唯一属性值,属性字段命名为FID_1. 2.使用工具 ...3.2 计算最小外接圆 打开工具显示如下，并进行参数设置： 主要参数设置如..
• 该代码提供一个用于从背景单一、物体相对简单且相互分离的图片中获得图片中的物体最小外接圆的圆心与半径的matlab函数：[PIC,center,radius]=m_minCircumferentialCircle(pic,background)；进而在其原图上通过所得...
• i++) //依次遍历每个轮廓 { //寻找最小外接圆，输出中心点和半径 Cv2.MinEnclosingCircle(contours[i], out center, out radius); //绘制轮廓 Cv2.DrawContours(src, contours, i, new Scalar(0, 0, 255), 2, ...
• # 最小外接圆 (x, y), radius = cv2.minEnclosingCircle(cnt) center = (int(x), int(y)) radius = int(radius) cv2.circle(im, center, radius, (255, 0, 0), 2) # 椭圆拟合 ellipse = cv2.fitEllipse(cnt)...
• 轮廓的最小外接椭圆 轮廓的多边形逼近 轮廓的最小外接圆 一、效果 轮廓几何矩的质心 轮廓的最大外接矩形 轮廓的凸包 轮廓的最小外接矩形 轮廓的最小外接三角形 轮廓的最小外接椭圆 轮廓的多边形逼近 轮廓的最小外接...
• 1、轮廓可以绘制：正外接矩形、最小外接矩形、最小外接圆、最小椭圆：其中最小外接矩形与最小椭圆在绘制时，如果轮廓点少于5个，会导致异常；！！ 2、轮廓多边形逼近函数ApproxPolyDp()：输出结果为Point数组，可以...
• float&类型, 表示的输出半径 ''' center, radius = cv2.minEnclosingCircle(cnt) ''' cv2.circle(img, center, radius, color, thickness, lineType,shift) # 画圆 # img,被画圆的图像 center,圆心坐标 radius,...
• Opencv绘制最小外接矩形、最小外接圆 Opencv中求点集的最小外结矩使用方法minAreaRect，求点集的最小外接圆使用方法minEnclosingCircle。 minAreaRect方法原型： RotatedRectminAreaRect(InputArraypoints); ...
• OpenCV python 轮廓(连通域)最小外接圆形 原图:[cc.jpg] import cv2 import numpy as np def main(): # 1.导入图片 img_src = cv2.imread("cc.jpg") # 2.灰度化,二值化 img_gray = cv2.cvtColor(img_src, ...
• 最小外接矩形（up-right boundidng：正的，没有旋转的矩形） Rect cv::boundingRect ( InputArray array ) 输入灰度图 或者2D 一组点, 存在std::vector 或者 Mat. 找到 包含一组点 的...
• OpenCV4查找绘制点集的最小外接矩形、最小外接圆、最小外接三角形 C++代码： #include "opencv2/highgui.hpp" #include "opencv2/imgproc.hpp" #include <iostream> using namespace cv; using namespace ...
• 一、求最大内切圆 ...现在能够找到所有半径和圆心，但是再图像中画不出来，不知道是否是连通域太多（442个），接下来研究如何把每一个连通域分别拿出来，求它的内切圆，外接圆，内切正方形和外接正方

...