より単純な画像での処理コードを書いてみました。
- findContoursで文字の輪郭を抽出
- 文字の輪郭群を含む外接矩形を算出
- 外接矩形で切り抜き
しています。
なお、実際の提示画像には罫線や背景画像がふくまれているようですので、それらを除去する前、中間処理が必要になってくるかと思います。
Python
1import cv2
2
3# 輪郭に外接する矩形を返す
4def get_bounding_rect(img,cnt,rc): # 画像,輪郭,初期矩形
5 l,t,r,b = rc[0][0],rc[0][1],rc[1][0],rc[1][1]
6 for pt in cnt:
7 x,y = pt[0][0],pt[0][1]
8 if x < l: l = x
9 if y < t: t = y
10 if x > r: r = x
11 if y > b: b = y
12 return [(l,t),(r,b)]
13
14def main():
15 img_src = cv2.imread('src.png')
16
17 # 処理対象をモノクロ画像に
18 img_bin = cv2.cvtColor(img_src, cv2.COLOR_BGR2GRAY)
19 _,img_bin = cv2.threshold(img_bin, 100, 255, cv2.THRESH_BINARY)
20
21 # 輪郭抽出
22 _,cnts,_ = cv2.findContours(img_bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
23
24 # 全文字を含む外接図形
25 import copy
26 rc0 = [[img_bin.shape[1],img_bin.shape[0]],[-1,-1]] # 初期矩形
27 rect_img = copy.deepcopy(rc0)
28
29 for cnt in cnts: # cnt =文字毎の輪郭
30 # 外接矩形を求める
31 rect_img = get_bounding_rect(img_bin,cnt,rect_img) # 全文字を含む
32 rect_cnt = get_bounding_rect(img_bin,cnt,copy.deepcopy(rc0)) # 文字毎 ※チェック用
33
34 cv2.rectangle(img_src, rect_cnt[0], rect_cnt[1], (255,0,0), thickness=1, lineType=cv2.LINE_4) # 文字毎。青
35
36 cv2.rectangle(img_src, rect_img[0], rect_img[1], (0,0,255), thickness=1, lineType=cv2.LINE_4) # 全文字を含む。赤
37
38 img_crop = img_bin[rect_img[0][1]:rect_img[1][1],rect_img[0][0]:rect_img[1][0]] # 抽出領域
39
40 cv2.imwrite('check.png', img_src)
41 cv2.imwrite('dst.png',img_crop)
42
43if __name__ == "__main__":
44 main()
元画像
結果確認
クロップ後