• 碑文书法汉字拆分


    废话不多说,先上图:

    此程序的主要目的,就是将碑文图片上的汉字截取出来,并且将文字周围多余边距去除,完成此后模式识别的先前准备工作。

    用的是opencv的库,在处理噪音和二值化处理的时候方便一点。

    其中涉及了一些在是使用opencv可能遇到的问题,比如矩形轮廓怎么画,用opencv提取出轮廓之后,怎么取舍这些轮廓……

    利用如上图所示的方法,对每个字进行切分,即寻找每个谷点。

    目录结构如下:

    calligraphies里面放的是原始碑文图片,split放的是切分后得到的图片,子文件夹以每个原始图片名命名。

    calligraphy_split.py为主程序。

    代码如下,有点长,步骤写得应该还算清楚,英文注释:

      1 import numpy as np
      2 import cv2
      3 from matplotlib import pyplot as plt
      4 import os
      5 
      6 
      7 class PrCalligraph(object):
      8 
      9     filename = 0
     10     dirname = ""
     11 
     12     def cut_img(self, img, flag_pi):
     13         row, col = img.shape
     14         for i in range(row-1):
     15             if img[i, col/2] <= flag_pi:
     16                 new_up_row = i
     17                 break
     18         for i in range(col-1):
     19             if img[row/2, i] <= flag_pi:
     20                 new_left_col = i
     21                 break
     22         for i in range(row-1, 0, -1):
     23             if img[i, col/2] <= flag_pi:
     24                 new_down_row = i
     25                 break
     26         for i in range(col-1, 0, -1):
     27             if img[row/2, i] <= flag_pi:
     28                 new_right_col = i
     29                 break
     30         print new_up_row, new_left_col, new_down_row, new_right_col
     31         return new_up_row, new_left_col, new_down_row, new_right_col
     32 
     33     # deal the image with binaryzation
     34     def thresh_binary(self, img):
     35         blur = cv2.GaussianBlur(img, (9, 9), 0)
     36         # OTSU's binaryzation
     37         ret3, th3 = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
     38         kernel = np.ones((2, 2), np.uint8)
     39         opening = cv2.morphologyEx(th3, cv2.MORPH_OPEN, kernel)
     40         return opening
     41 
     42     # sum the black pixel numbers in each cols
     43     def hist_col(self, img):
     44         list=[]
     45         row, col = img.shape
     46         for i in xrange(col):
     47             list.append((img[:, i] < 200).sum())
     48         return list
     49 
     50     # find the each segmentatoin cols
     51     def cut_col(self, img, hist_list):
     52         minlist = []
     53         images = []
     54         row, col = img.shape
     55         np_list = np.array(hist_list)
     56         avg = col/8
     57         i = 0
     58         # print np_list
     59         while i < col-1:
     60             if i >= col-10:
     61                 if np_list[i] < 40 and np_list[i] <= np_list[i+1: col].min():
     62                     minlist.append(i)
     63                     break
     64                 if i == col-1:
     65                     minlist.append(i)
     66                     break
     67             else:
     68                 if np_list[i] < 40 and np_list[i] < np_list[i+1: i+10].min():
     69                     minlist.append(i)
     70                     i += avg
     71             i += 1
     72         print minlist
     73         for j in xrange(len(minlist)-1):
     74             print j
     75             images.append(img[0:row, minlist[j]:minlist[j+1]])
     76         return images
     77 
     78     # sum the black pixel numbers in each rows
     79     def hist_row(self, img):
     80         list=[]
     81         row, col = img.shape
     82         for i in xrange(row):
     83             list.append((img[i, :] < 200).sum())
     84         return self.cut_row(img, list)
     85 
     86     # find each segmentation rows
     87     def cut_row(self, img, row_list):
     88         minlist = []
     89         single_images_with_rect = []
     90         row, col = img.shape
     91         np_list = np.array(row_list)
     92         avg = row/16
     93         i = 0
     94         while i <= row-1:
     95             if i >= row-10 and np_list[i] == 0:
     96                 minlist.append(i)
     97                 break
     98             elif np_list[i] == 0 and (np_list[i+1: i+10] < 200).sum() >= 5:
     99                 minlist.append(i)
    100                 i += avg
    101             i += 1
    102         print minlist
    103         for j in xrange(len(minlist)-1):
    104             single_img = img[minlist[j]:minlist[j+1], 0:col]
    105             single_img_with_rect = self.single_cut(single_img)
    106             if single_img_with_rect is not None:
    107                 single_images_with_rect.append(single_img_with_rect)
    108         return single_images_with_rect
    109 
    110     # find the single word's contours and take off the redundant margin
    111     def single_cut(self, img):
    112         blur = cv2.GaussianBlur(img, (9, 9), 0)
    113         ret3, th3 = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
    114         contours, hierarchy = cv2.findContours(th3, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    115         up, left = img.shape
    116         down, right = 0, 0
    117         for i in range(len(contours)):
    118             cnt = contours[i]
    119             x, y, w, h = cv2.boundingRect(cnt)
    120             if w < 6 and h < 6:
    121                 continue
    122             if x < up:
    123                 up = x
    124             if y < left:
    125                 left = y
    126             if x+w > down:
    127                 down = x+w
    128             if y+h > right:
    129                 right = y+h
    130         if down-up >= 40 and right-left >= 40:
    131             word = img[left:right, up:down]
    132             cv2.imwrite(self.dirname+str(self.filename)+'.png', word)
    133             cv2.rectangle(img,(up, left), (down, right), (0, 255, 0), 2)
    134             self.filename += 1
    135             return img
    136         else:
    137             return None
    138 
    139 if __name__ == '__main__':
    140 
    141     prcaligraphy = PrCalligraph()
    142     # read sys origin dir
    143     origin_images = os.listdir('./calligraphies/')
    144     # handle each picture
    145     for im in origin_images:
    146         # use for new single word filename
    147         prcaligraphy.filename = 0
    148         # take out the original picture's name
    149         outdir = os.path.splitext(im)[0]
    150         # mkdir  output dir name/path
    151         prcaligraphy.dirname = "./split/"+outdir+'/'
    152         os.makedirs(prcaligraphy.dirname, False)
    153         # use opencv read images
    154         img = cv2.imread('./calligraphies/'+im, cv2.IMREAD_GRAYSCALE)
    155         # preprocess original picture, cutout the redundant margin
    156         row, col = img.shape
    157         middle_pi = img[row/2, col/2]
    158         if middle_pi > 220:
    159             middle_pi = 220
    160         else:
    161             middle_pi += 10
    162         new_up_row, new_left_col, new_down_row, new_right_col = prcaligraphy.cut_img(img, middle_pi)
    163         cutedimg = img[new_up_row:new_down_row, new_left_col:new_right_col]
    164         # deal the image with binaryzation
    165         opening = prcaligraphy.thresh_binary(cutedimg)
    166         # split the image into pieces with cols
    167         hist_list = prcaligraphy.hist_col(opening)
    168         images = prcaligraphy.cut_col(opening, hist_list)
    169         # create two plt
    170         fig, axes = plt.subplots(1, len(images), sharex=True, sharey=True)
    171         fig2, axes2 = plt.subplots(len(images), 12, sharex=True, sharey=True)
    172         # split the pieces into single words by rows
    173         for i in range(len(images)):
    174             axes[i].imshow(images[i], 'gray')
    175             single_images_with_rect = prcaligraphy.hist_row(images[i])
    176             for j in range(len(single_images_with_rect)):
    177                 axes2[i, j].imshow(single_images_with_rect[j], 'gray')
    178         fig.savefig(prcaligraphy.dirname+'cut_col.png')
    179         fig2.savefig(prcaligraphy.dirname+'single.png')
    180         plt.clf()
    181     # plt.show()
    182 
    183 # cv2.imshow('image', imageee)
    184 # cv2.waitKey(0)
    185 # cv2.destroyAllWindows()
  • 相关阅读:
    欧拉函数 & 【POJ】2478 Farey Sequence & 【HDU】2824 The Euler function
    【BZOJ】2982: combination(lucas定理+乘法逆元)
    【vijos】1781 同余方程(拓展欧几里得)
    Disillusioning #1 水题+原题赛(被虐瞎)
    【HDU】3622 Bomb Game(2-SAT)
    小结:双连通分量 & 强连通分量 & 割点 & 割边
    【POJ】2942 Knights of the Round Table(双连通分量)
    【POJ】1523 SPF(割点)
    【POJ】1094 Sorting It All Out(拓扑排序)
    小结:网络流
  • 原文地址:https://www.cnblogs.com/phil-chow/p/5612270.html
Copyright © 2020-2023  润新知