- 所属公司
- 新西兰恒天然集团
- 所属行业
- 乳品
- 中文名称
- 安佳
- 创立时间
- 1886年
- 创立地点
- 新西兰
- 英文名称
- Anchor
-
Anchor
2019-11-18 20:20:06Anchor(锚点) 在一个典型的GEF程序中,我们通常会在画板上放上一些图形,然后用一些线连接这些图形。这些线的两个端点就是Anchor(锚点),而锚点所在的图形叫做锚点的Owner。更细化的说,一条线的起点叫做Source ...Anchor(锚点)
在一个典型的GEF程序中,我们通常会在画板上放上一些图形,然后用一些线连接这些图形。这些线的两个端点就是Anchor(锚点),而锚点所在的图形叫做锚点的Owner。更细化的说,一条线的起点叫做Source Anchor(源锚点),终结点叫做Target Anchor(目标锚点)。如图1中的黑色小方块所示。
图1. 源锚点和目标锚点
图1. 源锚点和目标锚点不难看出,锚点的具体位置和两个图形的位置以及连线的方式有关,这两个前提确定之后,锚点可以通过一定的方法计算得出。对于图1的情况,两个图形之间的连线是由两个图形的中心点确定的,那么锚点的计算方法就是找到这条中心线和图形边界的交点。Draw2D缺省为我们提供了一些Anchor的实现,最常用的大概是ChopboxAnchor,它只是简单的取两个图形的中心线和图形边界的交点做为锚点(正是图1 的情况)。对于简单的应用来说,ChopboxAnchor可以满足我们的需要,但是它的锚点计算方法导致锚点在任何时候都是唯一的,如果这两个图形之间存在多条连线,它们会相互重叠使得看上去只有一条,于是用户不可能用鼠标选择到被覆盖的连线。
解决这个问题的办法有两个:
1. 提供一个自定义的Connection Router(连线路由器),以便能尽量避免线之间的重合,甚至也可以每条线都有不同的Router。
2. 实现一个自定义的锚点,可以让用户自己拖动锚点到不同的位置,避免线之间的重合
对于方法1,我们在以后的系列中会有介绍。这里我们考虑方法2。
Shapes ExampleGEF的Shapes示例是一个很基础的GEF程序,用户可以在其上放置椭圆和长方形的图形,然后可以用两种样式的线连接它们。由于其使用了ChopboxAnchor,它不支持在两个图形之间创建多条连线,也不能移动锚点。我们将在它的基础上实现一个可移动的锚点。
第一步,确定锚点的表示策略设计自定义Anchor的第一个问题是"我想把什么位置做为Anchor?",比如对于一个矩形,你可以选择图形的中心,或者四条边的中心,或者边界上的任何点。在我们这个例子里,我们希望是椭圆边界的任何点。因此我们可以考虑用角度来表示Anchor的位置,如图2所示:
图2. Anchor的表示方式
图2. Anchor的表示方式我们可以用一个变量表示角度,从而计算出中心射线与边界的交点,把这个交点作为图形的锚点。通过这样的方式,边界上的任一点都可以成为锚点,可以通过手工调整锚点,避免连线重叠。
第二步,修改Model为了表示锚点,我们需要一个表示角度的变量,这个变量应该放到模型中以便能够把锚点信息记录到文件中。对于一条来说,它有两个锚点,所以应该在连线对象中添加两个成员,在Shapes例子中,连线对象是org.eclipse.gef.examples.shapes.model.Connection, 我们修改它添加两个成员和相应的Getter和Setter方法:
private double sourceAngle;
private double targetAngle;public double getSourceAngle() {
return sourceAngle;
}public void setSourceAngle(double sourceAngle) {
this.sourceAngle = sourceAngle;
}public double getTargetAngle() {
return targetAngle;
}public void setTargetAngle(double targetAngle) {
this.targetAngle = targetAngle;
}sourceAngle保存了源锚点的角度,targetAngle保存了目标锚点的角度,使用弧度表示。
第三步,实现ConnectionAnchor接口锚点的接口是由org.eclipse.draw2d.ConnectionAnchor定义的,我们需要实现这个接口,但是一般来说我们不用从头开始,可以通过继承其它类来减少我们的工作。由于存在椭圆和长方形两种图形,所以我们还需要实现两个子类。最终我们定义了基础类BorderAnchor和RectangleBorderAnchor,EllipseBorderAnchor两个子类。BorderAnchor的代码如下:
package org.eclipse.gef.examples.shapes.anchor;
import org.eclipse.draw2d.ChopboxAnchor;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Point;public abstract class BorderAnchor extends ChopboxAnchor {
protected double angle;public BorderAnchor(IFigure figure) { super(figure); angle = Double.MAX_VALUE; } public abstract Point getBorderPoint(Point reference); public Point getLocation(Point reference) { // 如果angle没有被初始化,使用缺省的ChopboxAnchor,否则计算一个边界锚点 if(angle == Double.MAX_VALUE) return super.getLocation(reference); else return getBorderPoint(reference); } public double getAngle() { return angle; } public void setAngle(double angle) { this.angle = angle; }
}
重要的是getLocation()方法,它有一个参数"Point reference",即一个参考点,在计算锚点时,我们可以根据参考点来决定锚点的位置,对于ChopboxAnchor来说,参考点就是另外一个图形的中心点。BorderAnchor类有一个angle成员,保存了锚点的角度,它会被初始化为Double.MAX_VALUE,所以我们判断angle是否等于Double.MAX_VALUE,如果是则BorderAnchor相当于一个ChopboxAnchor,如果否则调用一个抽象方法getBorderPoint()来计算我们的锚点。BorderAnchor的两个子类分别实现了计算椭圆和长方形锚点的算法,EllipseBorderAnchor的代码如下所示:
package org.eclipse.gef.examples.shapes.anchor;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PrecisionPoint;
import org.eclipse.draw2d.geometry.Rectangle;public class EllipseBorderAnchor extends BorderAnchor {
public EllipseBorderAnchor(IFigure figure) {
super(figure);
}@Override public Point getBorderPoint(Point reference) { //得到owner矩形,转换为绝对坐标 Rectangle r = Rectangle.SINGLETON; r.setBounds(getOwner().getBounds()); getOwner().translateToAbsolute(r); // 椭圆方程和直线方程,解2元2次方程 double a = r.width >> 1; double b = r.height >> 1; double k = Math.tan(angle); double dx = 0.0, dy = 0.0; dx = Math.sqrt(1.0 / (1.0 / (a * a) + k * k / (b * b))); if(angle > Math.PI / 2 || angle < -Math.PI / 2) dx = -dx; dy = k * dx; // 得到椭圆中心点,加上锚点偏移,得到最终锚点坐标 PrecisionPoint pp = new PrecisionPoint(r.getCenter()); pp.translate((int)dx, (int)dy); return new Point(pp); }
}
值的注意的地方是我们可以通过getOwner().getBounds()来得到Owner的边界矩形,这是我们能够计算出锚点的重要前提。此外我们要注意的是必须把坐标转换为绝对坐标,这是通过getOwner().translateToAbsolute®来实现的。最后,我们返回了锚点的绝对坐标,中间的具体计算过程只不过是根据椭圆方程和射线方程求值而已。在我们的实现中,并没有用到参考点,如果你想有更多的变数,可以把参考点考虑进去。
同样,RectangleBorderAnchor也是如此,只不过求长方形边界点的方法稍微不一样而已,我们就不一一解释了,代码如下:
package org.eclipse.gef.examples.shapes.anchor;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PrecisionPoint;
import org.eclipse.draw2d.geometry.Rectangle;public class RectangleBorderAnchor extends BorderAnchor {
public RectangleBorderAnchor(IFigure figure) { super(figure); } @Override public Point getBorderPoint(Point reference) { // 得到owner矩形,转换为绝对坐标 Rectangle r = Rectangle.SINGLETON; r.setBounds(getOwner().getBounds()); getOwner().translateToAbsolute(r); // 根据角度,计算锚点相对于owner中心点的偏移 double dx = 0.0, dy = 0.0; double tan = Math.atan2(r.height, r.width); if(angle >= -tan && angle <= tan) { dx = r.width >> 1; dy = dx * Math.tan(angle); } else if(angle >= tan && angle <= Math.PI - tan) { dy = r.height >> 1; dx = dy / Math.tan(angle); } else if(angle <= -tan && angle >= tan - Math.PI) { dy = -(r.height >> 1); dx = dy / Math.tan(angle); } else { dx = -(r.width >> 1); dy = dx * Math.tan(angle); } // 得到长方形中心点,加上偏移,得到最终锚点坐标 PrecisionPoint pp = new PrecisionPoint(r.getCenter()); pp.translate((int)dx, (int)dy); return new Point(pp); }
}
这样我们就完成了自定义的锚点实现。在ConnectionAnchor接口中,还有其他4个方法,虽然我们没有用到,但是有必要了解一下它们:
void addAnchorListener(AnchorListener listener);
void removeAnchorListener(AnchorListener listener);
Point getReferencePoint();
IFigure getOwner();addAnchorListener()和removeAnchorListener()可以添加或删除一个锚点监听器,这样我们可以知道锚点何时发生了移动。getOwner()则是返回锚点的Onwer图形,显然我们可以指定另外一个图形为锚点的Owner,虽然这种需求可能不太多。而getReferencePoint()则是返回一个参考点,要注意的是,这个参考点不是给自己用的,而是给另外一个锚点用的。比如对于源锚点来说,它会调用目标锚点的getReferencePoint()方法,而对于目标锚点来说,它会调用源锚点的getReferencePoint()方法。我们可以看看ChopboxAnchor的getReferencePoint()实现,它返回的就是它的Owner的中心。
第四步,修改EditPart锚点实现完成后,我们需要修改ShapeEditPart使它能够使用我们定义的锚点。EditPart中的getSourceConnectionAnchor(ConnectionEditPart connection)和getTargetConnectionAnchor(ConnectionEditPart connection)是决定使用哪种锚点的关键方法。它们还有一个重载版本,用来处理Reconnect时的锚点更新。这四个方法我们都需要修改,同时为了减少对象创建的次数,我们可以在ConnectionEditPart里面添加两个成员用来保存源锚点对象和目标锚点对象,如下:
/* In ConnectionEditPart.java */
private BorderAnchor sourceAnchor;
private BorderAnchor targetAnchor;public BorderAnchor getSourceAnchor() {
return sourceAnchor;
}public void setSourceAnchor(BorderAnchor sourceAnchor) {
this.sourceAnchor = sourceAnchor;
}public BorderAnchor getTargetAnchor() {
return targetAnchor;
}public void setTargetAnchor(BorderAnchor targetAnchor) {
this.targetAnchor = targetAnchor;
}这样的话,在ShapeEditPart中应该检查一下ConnectionEditPart中的成员是否有效,如果有效则直接返回,无效则创建一个新的锚点对象。而Reconnect时的代码稍微复杂一些,我们需要根据鼠标的当前位置,重新计算angle的值,鼠标的当前位置是包含在ReconnectRequest里面的。我们给出getSourceConnectionAnchor()的代码,对于getTargetConnectionAnchor(),只要将Source换成Target即可。
/* In ShapeEditPart.java */
/*
-
(non-Javadoc)
-
@see org.eclipse.gef.NodeEditPart#getSourceConnectionAnchor
(org.eclipse.gef.ConnectionEditPart)
*/
public ConnectionAnchor getSourceConnectionAnchor
(ConnectionEditPart connection) {
org.eclipse.gef.examples.shapes.parts.ConnectionEditPart con =
(org.eclipse.gef.examples.shapes.parts.ConnectionEditPart)connection;
BorderAnchor anchor = con.getSourceAnchor();
if(anchor == null || anchor.getOwner() != getFigure()) {
if(getModel() instanceof EllipticalShape)
anchor = new EllipseBorderAnchor(getFigure());
else if(getModel() instanceof RectangularShape)
anchor = new RectangleBorderAnchor(getFigure());
else
throw new IllegalArgumentException(“unexpected model”);Connection conModel = (Connection)con.getModel(); anchor.setAngle(conModel.getSourceAngle()); con.setSourceAnchor(anchor);
}
return anchor;
}
/*
-
(non-Javadoc)
-
@see org.eclipse.gef.NodeEditPart#getSourceConnectionAnchor
(org.eclipse.gef.Request)
*/
public ConnectionAnchor getSourceConnectionAnchor(Request request) {
if(request instanceof ReconnectRequest) {
ReconnectRequest r = (ReconnectRequest)request;
org.eclipse.gef.examples.shapes.parts.ConnectionEditPart con =
(org.eclipse.gef.examples.shapes.parts.ConnectionEditPart)r.
getConnectionEditPart();
Connection conModel = (Connection)con.getModel();
BorderAnchor anchor = con.getSourceAnchor();
GraphicalEditPart part = (GraphicalEditPart)r.getTarget();
if(anchor == null || anchor.getOwner() != part.getFigure()) {
if(getModel() instanceof EllipticalShape)
anchor = new EllipseBorderAnchor(getFigure());
else if(getModel() instanceof RectangleBorderAnchor)
anchor = new RectangleBorderAnchor(getFigure());
else
throw new IllegalArgumentException(“unexpected model”);anchor.setAngle(conModel.getSourceAngle()); con.setSourceAnchor(anchor); } Point loc = r.getLocation(); Rectangle rect = Rectangle.SINGLETON; rect.setBounds(getFigure().getBounds()); getFigure().translateToAbsolute(rect); Point ref = rect.getCenter(); double dx = loc.x - ref.x; double dy = loc.y - ref.y; anchor.setAngle(Math.atan2(dy, dx)); conModel.setSourceAngle(anchor.getAngle()); return anchor;
} else {
if(getModel() instanceof EllipticalShape)
return new EllipseBorderAnchor(getFigure());
else if(getModel() instanceof RectangularShape)
return new RectangleBorderAnchor(getFigure());
else
throw new IllegalArgumentException(“unexpected model”);
}
}
到这里我们的修改就完成了,但是由于Shapes示例不允许创建多条连线,所以我们还需要把ConnectionCreateCommand和ConnectionReconnectCommand中的一些代码注释掉,这个内容就不做更多介绍了,大家可以下载本文附带的代码查看具体的修改。最终,我们修改后的Shapes可以创建多条连线,并且可以手动调整它们的锚点以避免重叠,如图3所示:
图3. 新的Shapes示例
图3. 新的Shapes示例
结束语一个灵活的锚点实现对于复杂的图形编辑程序来说是必须的,我们所要做的仅仅只是实现ConnectionAnchor接口。本文实现的BorderAnchor是一个通用的锚点实现,你可以随意应用到自己的GEF程序中。或者在此基础上实现更为灵活的锚点功能。
-
-
anchor
2019-09-18 20:56:48首先我们需要知道anchor的本质是什么,本质是SPP(spatial pyramid pooling)思想的逆向。而SPP本身是做什么的呢,就是将不同尺寸的输入resize成为相同尺寸的输出。所以SPP的逆向就是,将相同尺寸的输出,倒推得到不同...anchor是在原图上的区域,而不是在特征图上。
anchor的窗口尺寸,三个面积尺寸(128x128,256x256,512x512),然后在每个面积尺寸下,取三种不同的长宽比例(1:1,1:2,2:1).这样一来,我们得到了一共9种面积尺寸各异的anchor。示意图如下:
对于每个3x3的窗口,作者就计算这个滑动窗口的中心点所对应的原始图片的中心点。对于每个3x3窗口,作者假定它来自9种不同原始区域的池化,但是这些池化在原始图片中的中心点,都完全一样。这个中心点,就是刚才提到的,3x3窗口中心点所对应的原始图片中的中心点。
如此一来,在每个窗口位置,我们都可以根据9个不同长宽比例、不同面积的anchor,逆向推导出它所对应的原始图片中的一个区域,这个区域的尺寸以及坐标,都是已知的。而这个区域,就是我们想要的 proposal。所以我们通过滑动窗口和anchor,成功得到了 51x39x9 个原始图片的proposal。接下来,每个proposal我们只输出6个参数:每个 proposal 和 ground truth 进行比较得到的前景概率和背景概率(2个参数)(对应图上的 cls_score);由于每个 proposal 和 ground truth 位置及尺寸上的差异,从 proposal 通过平移放缩得到 ground truth 需要的4个平移放缩参数(对应图上的 bbox_pred)。 -
anchor links
2020-12-30 09:02:19<p><a name="anchor1" id="anchor1">Anchor text</a></p> <p>How to tell polymer to evaluate the path at runtime properly ???</p><p>该提问来源于开源项目:erikringsmuth/app-router</p></div> -
Anchor Based和Anchor Free
2021-01-21 13:43:54Anchor Based和Anchor Free之间区别主要有以下两点:1.分类差异(关键正负样本定义)2.回归差异 1.分类差异: 现阶段的算法多尺度预测,即GT是由哪一个特征层和位置Anchor预测。 Anchor Based是由IoU来确定哪层和...Anchor Based和Anchor Free之间区别主要有以下两点:1.分类差异(关键正负样本定义)2.回归差异
1.分类差异:
现阶段的算法多尺度预测,即GT是由哪一个特征层和位置Anchor预测。
Anchor Based是由IoU来确定哪层和哪个位置的Anchor来预测,这个的选择是根据图像中目标物体的大小来决定。有个很牛逼名字叫启发式引导。
Anchor Free是Scale Ratio确定GT在哪层,利用Center Sampling确定那些位置是正样本。
现阶段的Anchor Free的检测方式的精度已经超过了Anchor Based。在Anchor based的算法中存在的问题:第一个是Anchor数量太多,第二个是超参数的引入【每层的Anchor数量、尺度、高宽比】
为什么Anchor数量会多呢?目标位置、以及形状的可能性,导致需要大量的框。框不够就会出现漏检的情况。因为正样本的选择有完全依赖IoU,而与真实物体达到一定置信度的Anchor相对于负样本来说少得可怜,就会导致正负样本不均衡的问题,也就会导致为什么准确率低的原因。
超参数的选择更是玄学中的玄学,技术不高就别玩绝招哦!!!!
基于Anchor Based中:在L1层中由于感受野太大,Anchor太小IoU无法达到所要求的置信度,所以在L1特征层不能确定是否包含目标。在L2中真实物体的中心在中间像素点上,正样本数量则为1.
基于Anchor Free中:L1同上,在L2中有两个Anchor中心点在GT中,因此可以理解为正样本数量为2.因此从这个方面我们也可以理解为什么Anchor Free会好于Anchor Based。总结一下:
Anchor Based的正负样本的选项方法:计算FPN每层的IoU来确定特征层,然后计算指定特征层位置的IoU确定具体位置。将IoU大于置信度的设置为正样本,小于某个置信值的为负样本,其他删除。
Anchor Free选择依据:空间和比例约束将anchor points分为不同的金字塔等级。首先将groundtruth框内的anchor point视为候选正样本,然后根据为每个金字塔等级定义的比例范围从候选样本中选择最终的正样本,最后那些未选择的锚点为负样本。2.回归差异:
对于一个正样本而言,Anchor Based回归起始状态是一个Anchor Box如图(b)所示;而Anchor Free起始状态是一个Anchor Point 如图©所示。
大神制作总而言之,还是归结于正负样本的选择。
关于Anchor Free的最新论文与代码如下所示:
论文地址:https://arxiv.org/pdf/1912.02424.pdf
代码地址:https://github.com/sfzhang15/ATSS -
anchor scale
2021-01-11 02:44:33<div><p>The code use the following equation to set the base anchor size, the size of the anchor with 1 and 1 the scale and ratio. <p>base_anchor_size = self.anchor_scale * stride * scale where ... -
Localise Anchor
2021-01-09 01:03:48<div><p>Ar hyn o bryd, os nad ydych yn siarad Saesneg, gallai fod yn anhygyrch Anchor. (At the moment, if you do not speak English, Anchor might be inaccessible.)</p><p>该提问来源于开源项目:... -
anchor_scale anchor_ration
2021-01-11 02:35:32<div><p>Hello,I want to konw how to produce anchor_scale and anchor_ration</p><p>该提问来源于开源项目:zylo117/Yet-Another-EfficientDet-Pytorch</p></div> -
Anchor links
2020-12-29 17:43:42anchor" links to a website and it triggers the routing process on click which it shouldn't do because "anchor" links are not supposed to navigate to any other location: they're ... -
Dimensional Anchor
2021-01-12 02:35:54Adds dimensional anchor item and some related fluff content."</code></pre> <h4>Purpose of change <p>These are quest items for Hub 01 fourth quest. Both the anchor and the suit will be armor to ... -
hashRouter anchor
2020-12-07 03:04:43t mean an anchor link. so in search result, the anchor will not append in url <p><strong>Result exclude the string like '#/*'. if url has '#/', it will be recognized as a route, not ... -
Anchor points
2021-01-10 18:09:43<div><p>It should be possible to build compound objects, relative to the anchor point. As it is now, attaching a child or a piece of physics to a node, will force its placement in lower left corner. ... -
[anchor] pluggable anchor commitments
2021-01-12 00:08:58- [x] Negotiating anchor type during funding flow <p>TODO: - [ ] Unit tests for anchor specific changes - [x] One itest case using anchors: #4001 <p>Long term: - [ ] Automatically sweep anchors - [ ]... -
YOLO-v3模型参数anchor设置
2018-10-02 14:29:43但是在训练自己数据的时候还是用模型中原有的anchor设置显然是有点不合适的,那么就涉及到根据自己的训练数据来设置anchor。 那么,首先我们需要知道anchor的本质是什么,本质是SPP(spatial pyramid pooling)思想的...1. 背景知识
在YOLO-v2版本中就引入了anchor box的概念,极大增加了目标检测的性能。但是在训练自己数据的时候还是用模型中原有的anchor设置显然是有点不合适的,那么就涉及到根据自己的训练数据来设置anchor。
那么,首先我们需要知道anchor的本质是什么,本质是SPP(spatial pyramid pooling)思想的逆向。而SPP本身是做什么的呢,就是将不同尺寸的输入resize成为相同尺寸的输出。所以SPP的逆向就是,将相同尺寸的输出,倒推得到不同尺寸的输入。
接下来是anchor的窗口尺寸,这个不难理解,三个面积尺寸(),然后在每个面积尺寸下,取三种不同的长宽比例.这样一来,我们得到了一共9种面积尺寸各异的anchor。示意图如下:
那么anchor在目标检测中是怎么使用的呢?那就先来看Faster R-CNN中的运用,下面是整个网络的结构图:
利用anchor是从第二列这个位置开始进行处理,这个时候,原始图片已经经过一系列卷积层和池化层以及relu,得到了这里的 feature:51x39x256(256是层数:H,W,C)在这个特征参数的基础上,通过一个3x3的滑动窗口,在这个51x39的区域上进行滑动,stride=1,padding=1,这样一来,滑动得到的就是51x39个3x3的窗口。对于每个3x3的窗口,作者就计算这个滑动窗口的中心点所对应的原始图片的中心点。然后作者假定,这个3x3窗口,是从原始图片上通过SPP池化得到的,而这个池化的区域的面积以及长宽比例,就是一个个的anchor。换句话说,对于每个3x3窗口,作者假定它来自9种不同原始区域的池化,但是这些池化在原始图片中的中心点,都完全一样。这个中心点,就是刚才提到的,3x3窗口中心点所对应的原始图片中的中心点。如此一来,在每个窗口位置,我们都可以根据9个不同长宽比例、不同面积的anchor,逆向推导出它所对应的原始图片中的一个区域,这个区域的尺寸以及坐标,都是已知的。而这个区域,就是我们想要的 proposal。所以我们通过滑动窗口和anchor,成功得到了 51x39x9 个原始图片的proposal。接下来,每个proposal我们只输出6个参数:每个 proposal 和 ground truth 进行比较得到的前景概率和背景概率(2个参数)(对应图上的 cls_score);由于每个 proposal 和 ground truth 位置及尺寸上的差异,从 proposal 通过平移放缩得到 ground truth 需要的4个平移放缩参数(对应图上的 bbox_pred)。2. Anchor先验参数计算
这里计算训练数据的anchor先验直接使用的是转好的数据,即是已经转好的可直接训练的数据。这里使用的代码参考的是这个仓库kmeans-anchor-boxes。各位可以到仓库里面下载里面的KMeans文件就可以了,这里给出我使用的部分代码:
# -*- coding=utf-8 -*- import glob import os import sys import xml.etree.ElementTree as ET import numpy as np from kmeans import kmeans, avg_iou # 根文件夹 ROOT_PATH = '/data/DataBase/YOLO_Data/V3_DATA/' # 聚类的数目 CLUSTERS = 6 # 模型中图像的输入尺寸,默认是一样的 SIZE = 640 # 加载YOLO格式的标注数据 def load_dataset(path): jpegimages = os.path.join(path, 'JPEGImages') if not os.path.exists(jpegimages): print('no JPEGImages folders, program abort') sys.exit(0) labels_txt = os.path.join(path, 'labels') if not os.path.exists(labels_txt): print('no labels folders, program abort') sys.exit(0) label_file = os.listdir(labels_txt) print('label count: {}'.format(len(label_file))) dataset = [] for label in label_file: with open(os.path.join(labels_txt, label), 'r') as f: txt_content = f.readlines() for line in txt_content: line_split = line.split(' ') roi_with = float(line_split[len(line_split)-2]) roi_height = float(line_split[len(line_split)-1]) if roi_with == 0 or roi_height == 0: continue dataset.append([roi_with, roi_height]) # print([roi_with, roi_height]) return np.array(dataset) data = load_dataset(ROOT_PATH) out = kmeans(data, k=CLUSTERS) print(out) print("Accuracy: {:.2f}%".format(avg_iou(data, out) * 100)) print("Boxes:\n {}-{}".format(out[:, 0] * SIZE, out[:, 1] * SIZE)) ratios = np.around(out[:, 0] / out[:, 1], decimals=2).tolist() print("Ratios:\n {}".format(sorted(ratios)))
经过运行之后得到一组如下数据:
[[0.21203704 0.02708333] [0.34351852 0.09375 ] [0.35185185 0.06388889] [0.29513889 0.06597222] [0.24652778 0.06597222] [0.24861111 0.05347222]] Accuracy: 89.58% Boxes: [135.7037037 219.85185185 225.18518519 188.88888889 157.77777778 159.11111111]-[17.33333333 60. 40.88888889 42.22222222 42.22222222 34.22222222]
其中的Boxes就是得到的anchor参数,以上面给出的计算结果为例,最后的anchor参数设置为
anchors = 135,17, 219,60, 225,40, 188,42, 157,42, 159,34
由于KMeans算法的结果对于初始点的选取敏感,因而每次运行的结果并不相同,只有Accuracy结果比较稳定点。至于那个anchor参数好,只有自己去尝试了。但是在使用的时候,没改过anchor经过一段时间的训练之后网络也能够适应,至于会不会对检测的精度有影响,暂时还没验证,-_-||。。。
为什么YOLOv2和YOLOv3的anchor大小有明显区别?
在YOLOv2中,作者用最后一层feature map的相对大小来定义anchor大小。也就是说,在YOLOv2中,最后一层feature map大小为13X13(不同输入尺寸的图像最后的feature map也不一样的),相对的anchor大小范围就在(0x0,13x13],如果一个anchor大小是9x9,那么其在原图上的实际大小是288x288。而在YOLOv3中,作者又改用相对于原图的大小来定义anchor,anchor的大小为(0x0,input_w x input_h]。所以,在两份cfg文件中,anchor的大小有明显的区别。如下是作者自己的解释:
So YOLOv2 I made some design choice errors, I made the anchor box size be relative to the feature size in the last layer. Since the network was down-sampling by 32. This means it was relative to 32 pixels so an anchor of 9x9 was actually 288px x 288px. In YOLOv3 anchor sizes are actual pixel values. this simplifies a lot of stuff and was only a little bit harder to implement https://github.com/pjreddie/darknet/issues/555#issuecomment-376190325
3. 参考
-
FreeAnchor
2020-10-28 15:00:17FreeAnchor2.1 Detector Training as Maximum Likelihood Estimation2.2 Detection Customized Likelihood 论文:FreeAnchor: Learning to Match Anchors for Visual Object Detection 来源:NIPS 2019 1. ... -
深入理解anchor
2019-11-10 20:53:49主要研究了anchor大小的设置以及提出了MTCNN中的anchor机制 -
anchor free 目标检测_目标检测中的anchor-based 和anchor free
2021-01-05 11:47:37目标检测中的anchor-based 和anchor free1. anchor-free 和 anchor-based 区别深度学习目标检测通常都被建模成对一些候选区域进行分类和回归的问题。在单阶段检测器中,这些候选区域就是通过滑窗方式产生的 anchor;... -
anchor free和anchor based的区别
2020-10-10 14:21:47anchor-free 和 anchor-based 区别几何 这个问题首先需要回答为什么要有 anchor。在深度学习时代,物体检测问题通常都被建模成对一些候选区域进行分类和回归的问题。在单阶段检测器中,这些候选区域就是通过滑窗方式... -
Does HL Portal display anchor from World Anchor Store
2021-01-10 08:42:58But wanted to know if HL portal shows anchor from world anchor store or just attaching to game object in scene is enough. I am not able to get anchor even after attaching and saving using world ... -
anchor box
2020-01-09 21:10:05anchor box 是目标检测中十分重要的概念,虽然最近很多论文都提出anchor free,但是深入理解anchor box对我们理解目前主流的faster rcnn,ssd,yolov2v3等算法很有帮助。 传统方法: 1.滑动窗口:顾名思义,采用一个... -
anchor实践
2020-03-27 18:08:15自己敲了一遍才彻底明白anchor是咋操作的,一直想趁假期的时间把faster复现一下… import torch import numpy as np ratios=[0.5,1,2]#长与宽之比 原图对应16*16 将其缩放的比例 有 11*23,16*16,23*11 scales=[8,16,... -
Horizontal Anchor Links
2020-11-28 21:54:26<p>I am able to of course get the horizontal anchor to work in a page not included in the book.json list, since this forces the book app to open this page in a UIWebView, which obeys horizontal anchor... -
anchor free 目标检测_目标检测——anchor-based 与anchor-free
2021-01-05 11:47:35在自然图像中,基于深度学习的目标检测技术包括anchor-based和anchor-free两大类。1、基于anchor-based的技术包括一个阶段和两个阶段的检测。其中一阶段的检测技术包括SSD,DSSD,RetinaNet,RefineDet,YOLOV3等,... -
Custom anchor links
2021-01-11 20:31:53<div><p>While it is very useful to get automatic anchor links from the title, in some cases it is nice to choose anchor links that give nice URLs. <p>Given suitable configuraton in Hugo, a header can ... -
Adding anchor line
2020-11-26 17:07:43<div><p>This adds the possibility of drawing an anchor line at the begining of the print on the X axis <p>It introduces following parameters: - <code>anchorThickness</code> and <code>anchorLinewidth, ...
-
Samba 服务配置与管理
-
2017年上半年 信息系统监理师 上午试卷 综合知识 软考真题【含答案和答案解析】
-
基于python的dango框架购物商城毕业设计毕设源代码使用教程
-
2014年上半年 信息系统监理师 上午试卷 综合知识 软考真题【含答案和答案解析】
-
NFS 实现高可用(DRBD + heartbeat)
-
二叉树搜索树(无左旋右旋)C 迭代寻找插入
-
使用Jenkins搭建iOS/Android持续集成打包平台
-
深入剖析 ConcurrentHashMap
-
kafka中kafkaConsumer的poll拉取方法
-
两种新的具有最优修复的2位奇偶校验MDS阵列代码
-
【Python-随到随学】 FLask第一周
-
UL 153:2020 Portable Electric Luminaires(便携灯具)- 最新完整英文版(204页)
-
2019年上半年 信息系统监理师 上午试卷 综合知识 软考真题【含答案和答案解析】
-
JMETER 性能测试基础课程
-
2012年下半年 信息系统监理师 上午试卷 综合知识 软考真题【含答案和答案解析】
-
MHA 高可用 MySQL 架构与 Altas 读写分离
-
保真度与量子绝热演化之间的广义关系
-
辅助驾驶的哈密顿量对绝热演化是否总是有用?
-
歌声合成从入门到精通
-
CentOS 7.8安装Java8