簡體   English   中英

如何去歪斜文本圖像並檢索該圖像 Python OpenCV 的新邊界框?

[英]How to de-skew a text image and retrieve the new bounding box of that image Python OpenCV?

這是我得到的收據圖像,我使用 matplotlib 繪制了它,如果您看到圖像,則其中的文本不直。 我怎樣才能消除偏差並修復它?

from skimage import io
import cv2

# x1, y1, x2, y2, x3, y3, x4, y4
bbox_coords = [[20, 68], [336, 68], [336, 100], [20, 100]]

image = io.imread('https://i.ibb.co/3WCsVBc/test.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)

fig, ax = plt.subplots(figsize=(20, 20))
ax.imshow(gray, cmap='Greys_r')

# for plotting bounding box uncomment the two lines below
#rect = Polygon(bbox_coords, fill=False, linewidth=1, edgecolor='r')
#ax.add_patch(rect)
plt.show()

print(gray.shape)
(847, 486)

收據圖片

我認為如果我們想先去歪斜,我們必須找到邊緣,所以我嘗試使用 canny 算法找到邊緣,然后得到如下輪廓。

from skimage import filters, feature, measure

def edge_detector(image):
    image = filters.gaussian(image, 2, mode='reflect')
    edges = feature.canny(image)
    contours = measure.find_contours(edges, 0.8)
    return edges, contours

fig, ax = plt.subplots(figsize=(20, 20))

ax.imshow(gray, cmap='Greys_r'); 
gray_image, contours = edge_detector(gray)

for n, contour in enumerate(contours):
    ax.plot(contour[:, 1], contour[:, 0], linewidth=2)

我從上面的代碼中得到的邊緣是每個文本的邊緣,但這不是我需要的。 我需要得到收據的邊緣嗎?

我還需要一種在圖像去偏斜(即拉直圖像)后獲取新邊界框坐標的方法嗎?

如果有人解決過類似的問題,請幫幫我? 謝謝。

這是 Projection Profile Method 的修改實現,用於校正傾斜圖像,如JBIG 壓縮圖像的 Projection profile based skew estimation algorithm 中所述。 得到二值圖像后,思路是將圖像旋轉各個角度,在每次迭代中生成像素直方圖。 為了確定傾斜角度,我們比較了峰值之間的最大差異,並使用該傾斜角度旋轉圖像以校正傾斜。 要確定的峰值數量可以通過delta值進行調整,delta 越低,將檢查的峰值越多,但過程將花費更長的時間。


之前->之后

傾斜角度:-2

代碼

import cv2
import numpy as np
from scipy.ndimage import interpolation as inter

def correct_skew(image, delta=1, limit=5):
    def determine_score(arr, angle):
        data = inter.rotate(arr, angle, reshape=False, order=0)
        histogram = np.sum(data, axis=1, dtype=float)
        score = np.sum((histogram[1:] - histogram[:-1]) ** 2, dtype=float)
        return histogram, score

    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1] 

    scores = []
    angles = np.arange(-limit, limit + delta, delta)
    for angle in angles:
        histogram, score = determine_score(thresh, angle)
        scores.append(score)

    best_angle = angles[scores.index(max(scores))]

    (h, w) = image.shape[:2]
    center = (w // 2, h // 2)
    M = cv2.getRotationMatrix2D(center, best_angle, 1.0)
    corrected = cv2.warpAffine(image, M, (w, h), flags=cv2.INTER_CUBIC, \
            borderMode=cv2.BORDER_REPLICATE)

    return best_angle, corrected

if __name__ == '__main__':
    image = cv2.imread('1.jpg')
    angle, corrected = correct_skew(image)
    print('Skew angle:', angle)
    cv2.imshow('corrected', corrected)
    cv2.waitKey()

注意:您可能需要根據圖像調整deltalimit值。 delta值控制迭代步長,它會一直迭代到控制最大角度的limit 該方法通過迭代檢查每個角度 + delta很簡單,目前僅適用於糾正 +/- 5 度范圍內的偏斜。 如果需要在更大的角度進行校正,請調整limit 對於另一種處理傾斜的方法,請查看將傾斜的圖像旋轉到直立位置以獲得替代方法

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM