首頁 > 軟體

Python使用Keras OCR實現從影象中刪除文字

2022-03-28 16:00:58

介紹

本文將討論如何快速地從影象中刪除文字,作為影象分類器的預處理步驟。

刪除文字可能有多種或多種原因,例如,我們可以使用無文字影象進行資料增強。

在本教學中,我們將使用OCR(光學字元識別)檢測影象中的文字,並在修復過程中填充照片中丟失的部分以生成完整的影象——以刪除我們檢測到的文字。

處理

為了從影象中刪除文字,我們將執行以下三個步驟:

1.識別影象中的文字,並使用KerasOCR獲取每個文字的邊界框座標。

2.對於每個邊界框,應用一個遮罩來告訴演演算法我們應該修復影象的哪個部分。

3.最後,應用一種修復演演算法對影象的遮罩區域進行修復,從而得到一個無文字影象。

實現

Keras ocr簡介

KerasOCR提供現成的ocr模型和端到端訓練管道,以構建新的ocr模型(請參見:https://keras-ocr.readthedocs.io/en/latest/).

在這種情況下,我們將使用預訓練的模型,它對我們的任務非常有效。

KerasOCR將自動下載探測器和識別器的預訓練權重。

當通過Keras orc傳遞影象時,它將返回一個(word,box)元組,其中框包含四個角的座標(x,y)。

下面是一個快速範例:

import matplotlib.pyplot as plt
import keras_ocr
 
pipeline = keras_ocr.pipeline.Pipeline()
 
#read image from the an image path (a jpg/png file or an image url)
img = keras_ocr.tools.read(image_path)
 
# Prediction_groups is a list of (word, box) tuples
prediction_groups = pipeline.recognize([img])
 
#print image with annotation and boxes
keras_ocr.tools.drawAnnotations(image=img, predictions=prediction_groups[0])

如果我們看一下prediction_groups,我們會看到每個元素對應一組座標。

例如,prediction_groups[0][10]如下:

('tuesday',
 array([[ 986.2778 ,  625.07764],
        [1192.3856 ,  622.7086 ],
        [1192.8888 ,  666.4836 ],
        [ 986.78094,  668.8526 ]], dtype=float32))

陣列的第一個元素對應左上角的座標,第二個元素對應右下角,第三個元素是右上角,而第四個元素是左下角。

cv2修復函數

使用OpenCV應用修復演演算法時,需要提供兩幅影象:

輸入影象,包含我們要刪除的文字。

遮罩影象,它顯示影象中要刪除的文字在哪裡。第二個影象的尺寸應與輸入的尺寸相同。

Cv2具有兩種修復演演算法,並允許應用矩形、圓形或線遮罩(請參考)

在這種情況下,我決定使用線遮罩,因為它們更靈活地覆蓋不同方向的文字(矩形遮罩只適用於平行或垂直於x軸的單詞,圓形遮罩將覆蓋比較大的區域)。

為了應用遮罩,我們需要提供線的起點和終點座標以及線的厚度:

起點將是框的左上角和左下角之間的中點,終點將是右上角和右下角之間的中點。

對於厚度,我們將計算左上角和左下角之間的線長度。

import math
import numpy as np
 
def midpoint(x1, y1, x2, y2):
    x_mid = int((x1 + x2)/2)
    y_mid = int((y1 + y2)/2)
    return (x_mid, y_mid)
 
#example of a line mask for the word "Tuesday"
box = prediction_groups[0][10]
x0, y0 = box[1][0]
x1, y1 = box[1][1] 
x2, y2 = box[1][2]
x3, y3 = box[1][3] 
x_mid0, y_mid0 = midpoint(x1, y1, x2, y2)
x_mid1, y_mi1 = midpoint(x0, y0, x3, y3)
thickness = int(math.sqrt( (x2 - x1)**2 + (y2 - y1)**2 ))

現在我們可以建立我們的遮罩:

mask = np.zeros(img.shape[:2], dtype="uint8")
cv2.line(mask, (x_mid0, y_mid0), (x_mid1, y_mi1), 255, thickness)

我們還可以檢查遮罩區域,確保其正常工作。

masked = cv2.bitwise_and(img, img, mask=mask)
plt.imshow(masked)

最後,我們可以修復影象。

在這種情況下,我們將使用cv2.INPAINT_NS,指得是“Navier-Stokes, Fluid Dynamics, and Image and Video Inpainting”一文中描述的修復演演算法。

img_inpainted = cv2.inpaint(img, mask, 7, cv2.INPAINT_NS)
plt.imshow(img_inpainted)

正如你所看到的,“Tuesday”已從圖片中刪除。

彙總

現在,讓我們把它總結起來,建立一個函數來去除任何影象中的文字。

我們只需要生成框列表,並迭代每個文字方塊。

import matplotlib.pyplot as plt
import keras_ocr
import cv2
import math
import numpy as np
 
def midpoint(x1, y1, x2, y2):
 
    x_mid = int((x1 + x2)/2)
    y_mid = int((y1 + y2)/2)
 
    return (x_mid, y_mid)
 
pipeline = keras_ocr.pipeline.Pipeline()
 
def inpaint_text(img_path, pipeline):
 
    # read image
    img = keras_ocr.tools.read(img_path)
 
    # generate (word, box) tuples 
    prediction_groups = pipeline.recognize([img])
    mask = np.zeros(img.shape[:2], dtype="uint8")
 
    for box in prediction_groups[0]:
 
        x0, y0 = box[1][0]
        x1, y1 = box[1][1] 
        x2, y2 = box[1][2]
        x3, y3 = box[1][3] 
 
        x_mid0, y_mid0 = midpoint(x1, y1, x2, y2)
        x_mid1, y_mi1 = midpoint(x0, y0, x3, y3)
        thickness = int(math.sqrt( (x2 - x1)**2 + (y2 - y1)**2 ))
        cv2.line(mask, (x_mid0, y_mid0), (x_mid1, y_mi1), 255, thickness)
        img = cv2.inpaint(img, mask, 7, cv2.INPAINT_NS)
 
    return(img)

以下是最終結果(之前和之後):

另外兩個例子:

請注意,如果要儲存影象,需要將其轉換為RGB格式,否則顏色會反轉!

img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
cv2.imwrite(‘text_free_image.jpg',img_rgb)

如果你只對刪除某些單詞感興趣,則可以包括一個if條件,如下所示:

給出了一個要刪除的單詞列表

remove_list = [‘tuesday', ‘monday']

我們可以在for迴圈中包含if條件

def inpaint_text(img_path, remove_list, pipeline):
    
    # read image
    img = keras_ocr.tools.read(img_path)
    
    # generate (word, box) tuples 
    prediction_groups = pipeline.recognize([img])
    mask = np.zeros(img.shape[:2], dtype="uint8")
    
    for box in prediction_groups[0]:
        
        if box[0] in remove_list:
           x0, y0 = box[1][0]
           x1, y1 = box[1][1] 
           x2, y2 = box[1][2]
           x3, y3 = box[1][3] 
        
           x_mid0, y_mid0 = midpoint(x1, y1, x2, y2)
            
           x_mid1, y_mi1 = midpoint(x0, y0, x3, y3)
        
           thickness = int(math.sqrt( (x2 - x1)**2 + (y2 - y1)**2 ))
        
           cv2.line(mask, (x_mid0, y_mid0), (x_mid1, y_mi1), 255,    
           thickness)
            
           img = cv2.inpaint(img, mask, 7, cv2.INPAINT_NS)
                 
    return(img)

當然,這只是一個快速的例子,說明了如何對特定的單詞列表進行修復。

結尾

在這篇文章中,我們討論瞭如何實現一種演演算法來自動刪除影象中的文字,該演演算法使用一個預訓練好的OCR模型(使用Keras)和一個使用cv2的修復演演算法。該演演算法似乎可以很好地從影象中快速刪除文字,而無需為此特定任務訓練模型。

當文字方塊靠近其他物件時,它通常表現不好,因為它可能會扭曲周圍環境。

以上就是Python使用Keras OCR實現從影象中刪除文字的詳細內容,更多關於Python影象刪除文字的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com