Python &Platly를 사용하여 이미지에 OCR 결과를 상호 표시

개요


OCR로 텍스트 읽기 개발을 진행하면 읽은 텍스트와 이미지를 비교해 결과를 확인하는 경우가 많다.읽은 이 문자가 그림의 어디에서 나왔는지, 단어의 단락이 부자연스러울 때 왜 이렇게 변했는지 확인할 때 문자와 그 좌표에서 그림의 상응하는 부분을 찾아야 하기 때문에 눈대중으로 조작하는 것은 매우 어렵다.물체 식별 등 작업에서는 이미지에 물체 이름의 라벨과 함께 사각형의 포위함을 그려 시각화하지만, OCR이 읽는 상황에서 문자가 이미지에 밀접하게 배치돼 이미지에 직접 묘사되면 정보량이 너무 많다.가능한 한 상호작용이 가능한 형식으로 정보를 표시하고 대부분의 경우 필요한 부분만 확인하고 싶어 한다.
이 글은 OCR이 읽은 결과를 이미지에 묘사하고 상호작용으로 결과를 확인하는 방법을 소개한다.

데모


먼저 실제 동작 화면을 소개한다.

OCR에는 Google Vision API를 사용하여 영역Word을 시각적으로 표시합니다.팝업은 OCR에서 읽은 텍스트를 표시합니다.또 이미지 사용receiptline으로 만든 영수증코드 생성.

메서드


이번에는 Plotly라는 도표 묘사 라이브러리를 이용했다.Plaotly는 그래프 배경에 이미지를 묘사하고 상호 분석하는 시각화 도구다.이 기능을 사용하면 OCR 대상의 이미지를 배경에 그리고 전체 구역에 대상의 구역과 메타정보를 그려서 이미지의 대상에 대한 정보를 표시할 수 있다.
이 방법은 Plattly 공식 창고 중 하나plotly/dash-detr에서 실시한 방법을 참고했다.대시라는 웹 앱 구축 소프트웨어 패키지를 사용해 물체 식별을 위한 시각화 도구를 제작한 데모아 프리.
https://github.com/plotly/dash-detr
기존 사용법과 달리 조금 해커 같은 방법이긴 하지만 스스로 GUI의 인터랙티브 도구를 만드는 것은 매우 어렵고, 특정 영역을 부각해 마우스로 정보를 과도하게 표시하려면 이 방법으로 충분하다.

코드


이어 위에서 소개한 dash-detr 창고의 코드를 인용하면서 해설을 진행한다.코드에 정의되지 않은 변수 등이 나타날 수 있으니 직접 테스트한 경우 적당히 교체해 주십시오.
  • https://github.com/plotly/dash-detr/blob/master/app.py
  • 묘사 영역 설정


    plotlyFigure를 제작하는 대상, 응용add_trace()update_xaxes() 등 방법으로 도표 정보를 업데이트한다.
    글의 첫머리의gif 애니메이션처럼 XY 축에 눈금을 표시하려면 각 축의 설정에 따라 visible=True로 변경합니다.
    import plotly.graph_objects as go
    fig = go.Figure()
    
    fig.add_trace(go.Scatter(
        x=[img_width * 0.05, img_width * 0.95],
        y=[img_height * 0.95, img_height * 0.05],
        showlegend=False, mode="markers", marker_opacity=0, 
        hoverinfo="none", legendgroup='Image'))
    fig.update_xaxes(
        showgrid=False, visible=False, constrain="domain", range=[0, img_width])
    fig.update_yaxes(
        showgrid=False, visible=False,
        scaleanchor="x", scaleratio=1,
        range=[img_height, 0])    
    

    그림 불러오기


    그림을 불러와서 뒷면에 놓으세요.여기서 이미지는 PIL 형식에서 기본 64 형식으로 source의 매개 변수로 변환됩니다.이미지의 URL을 직접 지정할 수도 있습니다.
    fig.add_layout_image(dict(
        source=pil_to_b64(im), sizing="stretch", opacity=1, layer="below",
        x=0, y=0, xref="x", yref="y", sizex=img_width, sizey=img_height,))
    

    OCR 결과 설명


    마지막으로 OCR 결과를 그립니다.add_bbox 함수는 각종 매개 변수를 지정하였으나 기본적으로 직사각형 좌표와 원 정보만 전달하였다.팝업에 표시할 내용을 go.Scatter()로 지정하려는 매개변수text입니다.
    def add_bbox(fig, x0, y0, x1, y1, 
                 showlegend=True, name=None, color=None, 
                 opacity=0.5, group=None, text=None):
        fig.add_trace(go.Scatter(
            x=[x0, x1, x1, x0, x0],
            y=[y0, y0, y1, y1, y0],
            mode="lines",
            fill="toself",
            opacity=opacity,
            marker_color=color,
            hoveron="fills",
            name=name,
            hoverlabel_namelength=0,
            text=text,
            legendgroup=group,
            showlegend=showlegend,
        ))
        
    add_bbox(
        fig,
        word.bounding_box.top_left.x,
        word.bounding_box.top_left.y,
        word.bounding_box.bottom_right.x,
        word.bounding_box.bottom_right.y,
        text=word.text,
    )
    

    그리다


    마지막으로 fig.show() 그림을 표시합니다.Jupter Notebook에서 실행되는 경우 이미지에 사각형 차트가 그려져야 합니다.
    fig.update_layout(title=title, showlegend=showlegend)
    fig.show()
    

    총결산


    이번에는 이미지에서 OCR 결과를 상호 확인하기 위해 플래토리를 이용한 시각화 방법을 소개했다.좌표 정보를 바탕으로 문자와 이미지 간의 왕래가 상당히 어려운데 이런 보조 도구가 있다면 개발이 쉬워질 것이다.

    참고 자료

  • plotly/dash-detr: A User Interface for DETR built with Dash. 100% Python.

  • [plotly를 통해 각종 이미지 분석] plotly를 통해 동적 시각화된 [python, 이미지] - Qita
  • PIL과 이미지의 조합은 이 글에서도 상세한 해설이 있다
  • 좋은 웹페이지 즐겨찾기