# 椭圆拟合
## 实验目的和要求
尝试使用 cv.fitEllipse()函数,对图像进行椭圆拟合
## 实验内容和原理
椭圆拟合
该函数使用的是最小二乘法拟合,要求输入的点至少有 6 个。
![](https://www.writebug.com/myres/static/uploads/2022/6/29/55461c3d7ad3bc1632afe486c2a31dc1.writebug)
![](https://www.writebug.com/myres/static/uploads/2022/6/29/f539e2debfb1c6d2a3245aa8805e1556.writebug)
![](https://www.writebug.com/myres/static/uploads/2022/6/29/6252385a9674fedd4961e2f673908c8f.writebug)
![](https://www.writebug.com/myres/static/uploads/2022/6/29/f7efe99c4990a7d18737c6f6565eef2d.writebug)
![](https://www.writebug.com/myres/static/uploads/2022/6/29/2f2d6e518cdda18c7f52fc2d60c4c49f.writebug)
![](https://www.writebug.com/myres/static/uploads/2022/6/29/81979a89f4bb3f5a3a52d2dffadd6c69.writebug)
函数中对应的参数如下:
![](https://www.writebug.com/myres/static/uploads/2022/6/29/0579ac4f31ad1e29970efd2448a8721c.writebug)
对输入图像的预处理
输入一张 RGB 图片,先转换为灰度图,本来打算先转换为二值图像再进行边缘检测的,但是发现二值化容易使阴影成为新的边缘,并丢失原有边缘信息,于是直接对灰度图进行了边缘检测。在边缘检测前还进行了降噪
边缘检测
用 Sobel Kernel 进行滤波,来计算 x 和 y 方向的导数。
![](https://www.writebug.com/myres/static/uploads/2022/6/29/5edce9669a931987d142378338c9c6c2.writebug)
对于每个像素,检测它是否为局部最大值,如果不是就设置为 0
![](https://www.writebug.com/myres/static/uploads/2022/6/29/fb372af7d088d09a60fcc3d2a3ebe6e1.writebug)
输入的两个参数为 min 和 max,用来限定寻找的边缘范围(大于 max 的肯定是边缘,小于 min 的肯定不是,在 min 和 max 之间的则通过判断连通性等方式来判断。
实验步骤与分析
读入图片
读入后先去掉高频的信息(降噪)。然后保存一个 RGB 图像信息,存储一个 gray 灰度图信息。边缘信息 edge 直接从 gray 中提取,min 取到 100,max 取到 200。
```python
FILENAME = "dota2items4.bmp"
img = cv.imread(FILENAME)
img = cv.GaussianBlur(img, (5, 5), 0)
rgb = cv.cvtColor(img, cv.COLOR_BGR2RGB)
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# _, thresh = cv.threshold(gray, 130, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)
edge = cv.Canny(gray, 100, 200)
```
使用 fitEllipse()函数
Ells 数组储存椭圆信息,recs 储存可以旋转的最小矩阵,recs2 储存正矩形信息。Cols 用于储存随机生成的颜色信息,方便区分不同椭圆和矩阵之间的对应关系
```c++
img = rgb
edge_ = cv.cvtColor(edge, cv.COLOR_GRAY2RGB)
ells = []
recs = []
recs2 = []
cols = []
contours, nothing = cv.findContours(edge, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
for index, contour in enumerate(contours):
if contour.shape[0] > 50:
ells.append(cv.fitEllipse(contour))
recs2.append(cv.boundingRect(contour))
recs.append(cv.minAreaRect(contour))
random.seed(10)
for i in range(len(ells)):
cols.append([random.randint(0, 256) for j in range(3)])
```
绘制椭圆与矩形
同时在 RGB 图像和边缘图像中绘制,这是椭圆
```c++
for index, ell in enumerate(ells):
cv.ellipse(img, ell, cols[index], 2)
cv.ellipse(edge_, ell, cols[index], 2)
```
这是可旋转的矩形
```c++
for index, rec in enumerate(recs):
box = cv.boxPoints(rec) # cv2.boxPoints(rect) for OpenCV 3.x
box = np.int0(box)
cv.drawContours(img,[box],0,cols[index],1)
cv.drawContours(edge_,[box],0,cols[index],1)
```
绘制正矩形
```c++
for index, rec2 in enumerate(recs2):
x,y,w,h = rec2
cv.rectangle(img,(x,y),(x+w,y+h),cols[index],1)
cv.rectangle(edge_,(x,y),(x+w,y+h),cols[index],1)
```
实验结果
输入图像
图里左上角的 Hyper stone 具有很多同心圆信息,右上的 Clarity 有不规则曲线和直线信息,右下的 Tango 有圆形信息且整体外形近似椭圆,正下方的 Force Staff 有近似的圆形信息和直线。
![](https://www.writebug.com/myres/static/uploads/2022/6/29/22aa1dfae580389a1fbb47deef8f108d.writebug)
输出:
- RGB
图像因为进行过高斯滤波而稍微模糊
![](https://www.writebug.com/myres/static/uploads/2022/6/29/690b2f7b297e0653a8288c28378defdc.writebug)
- GrayScale
![](https://www.writebug.com/myres/static/uploads/2022/6/29/1ada350feb9b6c851793ff050ad48213.writebug)
- Thresh
可以看出,二值化后的图像失去了很多细节信息,同时引入了阴影的边缘信息,这是我们不太想要的
![](https://www.writebug.com/myres/static/uploads/2022/6/29/06a633e40ec32bd34656d2e6a0e15c46.writebug)
- Edge
根据灰度图生成了图像的边缘信息
![](https://www.writebug.com/myres/static/uploads/2022/6/29/7ef1375c9d1ebf467e7627bc08744804.writebug)
Ellipse on Edge
大部分边缘信息拟合良好,但是图中红色箭头标出的浅蓝色椭圆很奇怪,通过分析,它对应的 contour 是左边浅蓝色矩形内部的信息,并不知道为什么会发生这样的事,也许是 bug?(这个现象同样在 Lena 图片中出现,根据搜索到的信息,可能是最小二乘法造成的问题)
![](https://www.writebug.com/myres/static/uploads/2022/6/29/719a6a1aa20f809da2e72fd369c6ad7e.writebug)
下图为 Lena 照片下半部分,看得出左边深蓝色矩阵和右边的椭圆对应,但并没有任何重合。
![](https://www.writebug.com/myres/static/uploads/2022/6/29/218023130f40af8b4bf8033772fa74d4.writebug)
Ellipse on RGB
看得出,那个浅蓝色椭圆与整个图片格格不入
![](https://www.writebug.com/myres/static/uploads/2022/6/29/ea2badba6f5c8206dc37b3351f6049ea.writebug)
心得体会
本来想直接用那种波点图像就算了,看见同学做了对奇怪的游戏 CG 的拟合,于是考虑到继续使用 Lena 姐姐的照片,但是羽毛帽的细节信息太多,导致效果并不十分好。于是找了 DOTA2 的物品图标(虽然效果很好,但是分辨率实在太低,于是找了二次创作的高清图像,效果还不错,各种情况下的效果都能看见)
![](https://www.writebug.com/myres/static/uploads/2022/6/29/037dd951240c5571c648ab4926eab4cd.writebug)
比如这里非常标准的椭圆
![](https://www.writebug.com/myres/static/uploads/2022/6/29/d31436457d07a36c521c3b3ef33ca0a2.writebug)
![](https://www.writebug.com/myres/static/uploads/2022/6/29/11830b66f432617c661a1f55613ca47d.writebug)
这里对形状近似的物体的拟合
![](https://www.writebug.com/myres/static/uploads/2022/6/29/07f98555dba9df270d5cd047ca0dd0f5.writebug)
这个粉色应该是在拟合瓶子的左下边缘。
通过调大拟合时使用的点的数量阈值以及画的线的粗细,可以删除一些不靠谱的结果,防止出现一大团乱七八糟的线 的效果(如下)
![](https://www.writebug.com/myres/static/uploads/2022/6/29/363ed61aa017e7b4b905daa0426a4572.writebug)
(对应的其实是)
![](https://www.writebug.com/myres/static/uploads/2022/6/29/d317c01112eaef4e8201e9c0e61cc6ec.writebug)
xziyuan
- 粉丝: 879
- 资源: 129
最新资源
- P+F绝对值编码器GSD文件 PSM58.rar PFDG5046.GSD
- 图论重庆大学图论与应用课程期末复习资料(部分个人手写资料)(私人复习资料)
- 施工人员检测41-CreateML数据集.rar
- burp24-jdk-21.0.2
- 施工人员检测38-YOLO(v5至v9)、COCO、CreateML、Darknet、Paligemma、TFRecord、VOC数据集合集.rar
- burp-proxy-tools
- 施工人员检测37-YOLOv7、COCO、CreateML、Darknet、Paligemma、VOC数据集合集.rar
- 嵌入式系统课程设计:基于51单片机的温度检测系统实现
- BurpLoaderKeygen
- 工具变量-A股上市公司企业盟浪esg评级数据(2018-2022年).xlsx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈