Python EAST文本检测的解码几何输出

Python EAST文本检测的解码几何输出,python,opencv,deep-learning,Python,Opencv,Deep Learning,我试图在OpenCV中使用EAST模型来检测图像中的文本。我在通过网络运行图像后成功地获得了输出,但我很难理解我使用的解码功能是如何工作的。我知道我从模型中得到5个数字作为输出,我认为这是一个点到矩形顶部、底部、左侧和右侧的距离,以及最后的旋转角度。我不确定decode函数如何获得文本区域的边界框 我知道为什么偏移量会乘以4(在模型中运行时会缩小4)。我知道为什么h和w是这样的。在那之后我什么都不确定 分数是每个区域的信心分数; 几何图形是每个区域的几何图形值(我提到的5个数字) scoreTh

我试图在OpenCV中使用EAST模型来检测图像中的文本。我在通过网络运行图像后成功地获得了输出,但我很难理解我使用的解码功能是如何工作的。我知道我从模型中得到5个数字作为输出,我认为这是一个点到矩形顶部、底部、左侧和右侧的距离,以及最后的旋转角度。我不确定decode函数如何获得文本区域的边界框

我知道为什么偏移量会乘以4(在模型中运行时会缩小4)。我知道为什么h和w是这样的。在那之后我什么都不确定

分数是每个区域的信心分数; 几何图形是每个区域的几何图形值(我提到的5个数字) scoreThresh只是非最大抑制的阈值

def decode(scores, geometry, scoreThresh):
    detections = []
    confidences = []

    ############ CHECK DIMENSIONS AND SHAPES OF geometry AND scores ############
    assert len(scores.shape) == 4, "Incorrect dimensions of scores"
    assert len(geometry.shape) == 4, "Incorrect dimensions of geometry"
    assert scores.shape[0] == 1, "Invalid dimensions of scores"
    assert geometry.shape[0] == 1, "Invalid dimensions of geometry"
    assert scores.shape[1] == 1, "Invalid dimensions of scores"
    assert geometry.shape[1] == 5, "Invalid dimensions of geometry"
    assert scores.shape[2] == geometry.shape[2], "Invalid dimensions of scores and geometry"
    assert scores.shape[3] == geometry.shape[3], "Invalid dimensions of scores and geometry"
    height = scores.shape[2]
    width = scores.shape[3]
    for y in range(0, height):

        # Extract data from scores
        scoresData = scores[0][0][y]
        x0_data = geometry[0][0][y]
        x1_data = geometry[0][1][y]
        x2_data = geometry[0][2][y]
        x3_data = geometry[0][3][y]
        anglesData = geometry[0][4][y]
        for x in range(0, width):
            score = scoresData[x]

            # If score is lower than threshold score, move to next x
            if(score < scoreThresh):
                continue

            # Calculate offset
            offsetX = x * 4.0
            offsetY = y * 4.0
            angle = anglesData[x]

            # Calculate cos and sin of angle
            cosA = math.cos(angle)
            sinA = math.sin(angle)
            h = x0_data[x] + x2_data[x]
            w = x1_data[x] + x3_data[x]

            # Calculate offset
            offset = ([offsetX + cosA * x1_data[x] + sinA * x2_data[x], offsetY - sinA * x1_data[x] + cosA * x2_data[x]])

            # Find points for rectangle
            p1 = (-sinA * h + offset[0], -cosA * h + offset[1])
            p3 = (-cosA * w + offset[0],  sinA * w + offset[1])
            center = (0.5*(p1[0]+p3[0]), 0.5*(p1[1]+p3[1]))
            detections.append((center, (w,h), -1*angle * 180.0 / math.pi))
            confidences.append(float(score))

    # Return detections and confidences
    return [detections, confidences]
def解码(分数、几何、分数阈值):
检测=[]
信任=[]
############检查几何体的尺寸和形状以及分数############
断言len(scores.shape)==4,“分数的维度不正确”
断言len(geometry.shape)==4,“几何体的尺寸不正确”
断言分数。形状[0]==1,“分数的维度无效”
断言几何体。形状[0]==1,“几何体的尺寸无效”
断言分数。形状[1]==1,“分数的维度无效”
断言几何体。形状[1]==5,“几何体的尺寸无效”
断言分数。形状[2]==几何图形。形状[2],“分数和几何图形的维度无效”
断言分数。形状[3]==几何图形。形状[3],“分数和几何图形的维度无效”
高度=分数。形状[2]
宽度=分数。形状[3]
对于范围(0,高度)内的y:
#从分数中提取数据
分数数据=分数[0][0][y]
x0_数据=几何[0][0][y]
x1_数据=几何[0][1][y]
x2_数据=几何[0][2][y]
x3_数据=几何[0][3][y]
角度数据=几何[0][4][y]
对于范围内的x(0,宽度):
分数=分数数据[x]
#如果分数低于阈值分数,则移动到下一个x
如果(分数<分数阈值):
持续
#计算偏移量
偏移量x=x*4.0
偏移量=y*4.0
角度=角度数据[x]
#计算角的cos和sin
cosA=math.cos(角度)
sinA=math.sin(角度)
h=x0_数据[x]+x2_数据[x]
w=x1_数据[x]+x3_数据[x]
#计算偏移量
偏移量=([offsetX+cosA*x1_数据[x]+sinA*x2_数据[x],offsetY-sinA*x1_数据[x]+cosA*x2_数据[x]]
#为矩形查找点
p1=(-sinA*h+偏移量[0],-cosA*h+偏移量[1])
p3=(-cosA*w+偏移量[0],sinA*w+偏移量[1])
中心=(0.5*(p1[0]+p3[0]),0.5*(p1[1]+p3[1]))
检测。附加((中心,(w,h),-1*角度*180.0/数学pi))
信任。附加(浮动(分数))
#返回检测和信任
返回[检测、信任]
包含输出格式的图表。不是以通常的方式指定框,而是将其指定为距偏移(x,y)的一组距离(上、右、下和左),除了角度a之外,金额框还逆时针旋转。

请注意,
分数
几何
y,x
索引,与
偏移
计算下面的任何逻辑相反。因此,要获得得分最高的几何组件
y,x

high_scores_yx = np.where(scores[0][0] >= np.max(scores[0][0]))
y, x = high_scores_yx[0][0], high_scores_yx[1][0]
h_upper, w_right, h_lower, w_left, A = geometry[0,:,y,x]
代码使用
offset
存储矩形右下角的偏移量。因为它是右下角,所以只需要
w_right
h_lower
,在代码中分别是
x1_数据
x2_数据

右下角相对于原始偏移量的位置取决于旋转角度。下面的虚线显示了轴的方向。从原始偏移量到下底部偏移量的组件以紫色(水平)和紫色(垂直)标记。请注意,
sin(A)*w_right
分量被减去,因为在这个坐标系中,
y
越低越大

这就解释了

offset = ([offsetX + cosA * x1_data[x] + sinA * x2_data[x], offsetY - sinA * x1_data[x] + cosA * x2_data[x]])
接下来:
p1
p3
分别是矩形的左下角和右上角,并考虑旋转
center
只是这两点的平均值

最后,
-1*angle*180.0/math.pi
将原始的逆时针弧度角转换为顺时针角度(因此逆时针旋转的对象的最终输出角度应为负值)。这是为了与CV2
boxPoints
方法兼容,用于:


那么,你的确切问题是什么?基本上,解码函数为什么会这样做?非常感谢,我自己能够解决一些问题,但对y、x索引以及一些余弦和正弦上的符号感到困惑。这太棒了!