zoukankan      html  css  js  c++  java
  • 碑文书法汉字拆分

    废话不多说,先上图:

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

    用的是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()
  • 相关阅读:
    io学习
    asp.net文件上传进度条研究
    asp.net页面中的Console.WriteLine结果如何查看
    谨慎跟随初始目的不被关联问题带偏
    android 按钮特效 波纹 Android button effects ripple
    安卓工作室 日志设置
    安卓工作室 文件浏览器 android studio File browser
    一个新的Android Studio 2.3.3可以在稳定的频道中使用。A new Android Studio 2.3.3 is available in the stable channel.
    新巴巴运动网上商城 项目 快速搭建 教程 The new babar sports online mall project quickly builds a tutorial
    码云,git使用 教程-便签
  • 原文地址:https://www.cnblogs.com/phil-chow/p/5612270.html
Copyright © 2011-2022 走看看