通过Google Cloud Vision API(TEXT_DETECTION)获取正确的图像方向

Jac*_*Fan 11 ocr google-cloud-platform google-cloud-vision

我在90度旋转图像上尝试了Google Cloud Vision api(TEXT_DETECTION).它仍然可以正确返回识别的文本.(见下图)

这意味着即使图像旋转90度,180度,270度,引擎也可以识别文本.

但是,响应结果不包括正确图像方向的信息.(document:EntityAnnotation)

无论如何,不​​仅要获得认可的文字,还要获得方向
谷歌可以支持它类似于(FaceAnnotation:getRollAngle)

在此输入图像描述

faa*_*aez 8

您可以利用我们知道单词中的字符序列这一事实来推断单词的方向,如下所示(对于非 LTR 语言显然逻辑略有不同):

for page in annotation:
    for block in page.blocks:
        for paragraph in block.paragraphs:
            for word in paragraph.words:
                if len(word.symbols) < MIN_WORD_LENGTH_FOR_ROTATION_INFERENCE:
                    continue
                first_char = word.symbols[0]
                last_char = word.symbols[-1]
                first_char_center = (np.mean([v.x for v in first_char.bounding_box.vertices]),np.mean([v.y for v in first_char.bounding_box.vertices]))
                last_char_center = (np.mean([v.x for v in last_char.bounding_box.vertices]),np.mean([v.y for v in last_char.bounding_box.vertices]))

                #upright or upside down
                if np.abs(first_char_center[1] - last_char_center[1]) < np.abs(top_right.y - bottom_right.y): 
                    if first_char_center[0] <= last_char_center[0]: #upright
                        print 0
                    else: #updside down
                        print 180
                else: #sideways
                    if first_char_center[1] <= last_char_center[1]:
                        print 90
                    else:
                        print 270
Run Code Online (Sandbox Code Playgroud)

然后您可以使用单个单词的方向来推断文档整体的方向。

  • 您为 MIN_WORD_LENGTH_FOR_ROTATION_INFERENCE 使用什么值? (2认同)

Jor*_*dan 5

正如公共问题跟踪器 中所述,我们的工程团队现在知道此功能请求,并且目前没有实现它的 ETA。

请注意,您的图像元数据中可能已经提供了方向信息。可以在此第三方库中看到如何提取元数据的示例。

一个广泛的解决方法是检查返回的“ boundingPoly ”“顶点”以获取返回的“textAnnotations”。通过计算每个检测到的单词的矩形的宽度和高度,如果矩形“高度”>“宽度”(也就是图像横向),您可以确定图像是否不是正面朝上的。

  • 很想知道即使图像没有水平对齐并且需要旋转,谷歌云视觉如何从图像中获取正确的文本。API如何知道旋转图像的程度?如果此信息不在图像的元数据中,云 API 如何找到它? (3认同)

Jac*_*Fan 5

我发布了我的解决方法,它确实适用于旋转 90、180、270 度的图像。请参阅下面的代码。

GetExifOrientation(annotateImageResponse.getTextAnnotations().get(1));
/**
 *
 * @param ea  The input EntityAnnotation must be NOT from the first EntityAnnotation of
 *            annotateImageResponse.getTextAnnotations(), because it is not affected by
 *            image orientation.
 * @return Exif orientation (1 or 3 or 6 or 8)
 */
public static int GetExifOrientation(EntityAnnotation ea) {
    List<Vertex> vertexList = ea.getBoundingPoly().getVertices();
    // Calculate the center
    float centerX = 0, centerY = 0;
    for (int i = 0; i < 4; i++) {
        centerX += vertexList.get(i).getX();
        centerY += vertexList.get(i).getY();
    }
    centerX /= 4;
    centerY /= 4;

    int x0 = vertexList.get(0).getX();
    int y0 = vertexList.get(0).getY();

    if (x0 < centerX) {
        if (y0 < centerY) {
            //       0 -------- 1
            //       |          |
            //       3 -------- 2
            return EXIF_ORIENTATION_NORMAL; // 1
        } else {
            //       1 -------- 2
            //       |          |
            //       0 -------- 3
            return EXIF_ORIENTATION_270_DEGREE; // 6
        }
    } else {
        if (y0 < centerY) {
            //       3 -------- 0
            //       |          |
            //       2 -------- 1
            return EXIF_ORIENTATION_90_DEGREE; // 8
        } else {
            //       2 -------- 3
            //       |          |
            //       1 -------- 0
            return EXIF_ORIENTATION_180_DEGREE; // 3
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

更多信息
我发现我必须添加语言提示才能annotateImageResponse.getTextAnnotations().get(1)始终遵循规则。

添加语言提示的示例代码

ImageContext imageContext = new ImageContext();
String [] languages = { "zh-TW" };
imageContext.setLanguageHints(Arrays.asList(languages));
annotateImageRequest.setImageContext(imageContext);
Run Code Online (Sandbox Code Playgroud)


小智 5

杰克范的回答对我有用。这是我的 VanillaJS 版本。

/**
 *
 * @param gOCR  The Google Vision response
 * @return orientation (0, 90, 180 or 270)
 */
function getOrientation(gOCR) {
    var vertexList = gOCR.responses[0].textAnnotations[1].boundingPoly.vertices;

    const ORIENTATION_NORMAL = 0;
    const ORIENTATION_270_DEGREE = 270;
    const ORIENTATION_90_DEGREE = 90;
    const ORIENTATION_180_DEGREE = 180;

    var centerX = 0, centerY = 0;
    for (var i = 0; i < 4; i++) {
        centerX += vertexList[i].x;
        centerY += vertexList[i].y;
    }
    centerX /= 4;
    centerY /= 4;

    var x0 = vertexList[0].x;
    var y0 = vertexList[0].y;

    if (x0 < centerX) {
        if (y0 < centerY) {

            return ORIENTATION_NORMAL;
        } else {
            return ORIENTATION_270_DEGREE;
        }
    } else {
        if (y0 < centerY) {
            return ORIENTATION_90_DEGREE;
        } else {
            return ORIENTATION_180_DEGREE;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)