我在復現(xiàn)paddleocr的印章彎曲文字識別的時候拇泛,發(fā)現(xiàn)使用paddle提供的彎曲文字定位模型DB++時穷绵,只能定位給到水平文字,無法定位到彎曲文字。
如下圖
因為我本人是個菜鳥啊提岔,我只會看paddle的教程啊,他說的我就照做冠息,他沒說,我就不會啊。
最終經(jīng)過我的研究,需要修改一個參數(shù)诈茧。參數(shù)的路徑如下:
PaddleOCR/ppocr/postprocess/db_postprocess.py
改了下面的參數(shù)就可以定位任意多邊形啦。效果圖如下:
但是呢棵介,我又發(fā)現(xiàn)用他的彎曲文字定位模型SVTR不能識別彎曲文字后雷,只能識別水平文字镇眷,我就很不高興咬最,我找了好久也沒找到類似的定位模型里面的參數(shù)欠动,所以無從下爪。
不著急慢慢分析具伍。
首先,根據(jù)paddle給出的做法望几,當我們拿到印章圖片,并且定位到印章中的文字之后橄抹,我們手里應該是有文字的坐標的祈坠,也就是下面代碼里的points,但是如果是水平文字(或者水平略傾斜)赦拘,那么我們的定位框就是一個四邊形,也就是下面代碼里assert 的points的長度是4阁猜,也就是4個點形成一個閉合框蹋艺。但是呢,如果我要預測彎曲文字怎么辦捎谨,points就不是四個點了啊。這時你看看最頂端被注銷掉的部分代碼畏邢,他的做法是什么检吆,其目的就是取一個緊貼定位框的四邊形。這么做的效果是什么呢蹭沛。
import cv2
import numpy as np
def get_rotate_crop_image(img, points):
'''
img_height, img_width = img.shape[0:2]
left = int(np.min(points[:, 0]))
right = int(np.max(points[:, 0]))
top = int(np.min(points[:, 1]))
bottom = int(np.max(points[:, 1]))
img_crop = img[top:bottom, left:right, :].copy()
points[:, 0] = points[:, 0] - left
points[:, 1] = points[:, 1] - top
'''
assert len(points) == 4, "shape of points must be 4*2"
img_crop_width = int(
max(
np.linalg.norm(points[0] - points[1]),
np.linalg.norm(points[2] - points[3])))
img_crop_height = int(
max(
np.linalg.norm(points[0] - points[3]),
np.linalg.norm(points[1] - points[2])))
pts_std = np.float32([[0, 0], [img_crop_width, 0],
[img_crop_width, img_crop_height],
[0, img_crop_height]])
M = cv2.getPerspectiveTransform(points, pts_std)
dst_img = cv2.warpPerspective(
img,
M, (img_crop_width, img_crop_height),
borderMode=cv2.BORDER_REPLICATE,
flags=cv2.INTER_CUBIC)
dst_img_height, dst_img_width = dst_img.shape[0:2]
if dst_img_height * 1.0 / dst_img_width >= 1.5:
dst_img = np.rot90(dst_img)
return dst_img
def run(data_dir, label_file, save_dir):
datas = open(label_file, 'r').readlines()
for idx, line in enumerate(datas):
img_path, label = line.strip().split('\t')
img_path = os.path.join(data_dir, img_path)
label = json.loads(label)
src_im = cv2.imread(img_path)
if src_im is None:
continue
for anno in label:
seal_box = anno['seal_box']
txt_boxes = anno['polys']
crop_im = get_rotate_crop_image(src_im, text_boxes)
save_path = os.path.join(save_dir, f'{idx}.png')
if not os.path.exists(save_dir):
os.makedirs(save_dir)
# print(src_im.shape)
cv2.imwrite(save_path, crop_im)
這么做的效果就如下圖臂寝,亂七八糟的章鲤,用腳指頭想,都知道識別的效果不會好的
下面是識別效果败徊,都是paddle的代碼和paddle的模型素征。
但是呢如果一張圖片里既有水平文字御毅,又有彎曲文字的時候,他對水平文字就是別的很好端蛆,彎曲文字就完全不行。如下圖
下圖是文字識別的結果
難道他的正確率55%是拋棄所有彎曲文字,只要水平文字得來的嗎呆躲?
搞得我都懷疑我自己了插掂,到底是哪里做錯了。
是不是因為我把定位和識別聯(lián)系起來的過程中用的文字切片有問題辅甥,人家在det和rec連接的時候還有什么高明的做法嗎?
我用截圖軟件要销,找了幾張非常清晰的圖片夏块,將彎曲文字切割出來,不通過det模型直接送給rec模型試試看效果脐供。如下面幾個圖的效果,是我用win自帶的截圖截出來的。win+shift+s
測試的結果如下圖匹颤,沒一個能看的,結果顯示的是識別出來的文字+置信度辽慕,你看看赦肃,甚至很多置信度都是0,完全識別不到文字船侧。
我累了厅各,我再找找原因吧,队塘,,遮怜,鸿市,
肯定還有一個隱藏的參數(shù),沒讓我發(fā)現(xiàn)灸芳。
這個世界對菜鳥太不友好了。