opencv3+python3.5成語填字遊戲(一)印刷體漢字的分割

   首先這是一個成語填字遊戲,大概就是一張成語填字遊戲圖片,通過opencv圖像識別後轉爲矩陣,再通過解算法,解出答案,在顯示到圖片上。

   源代碼:https://github.com/mayue801/crossword-puzzle--idiom


   本文采用投影分割法對印刷體漢字進行分割。

   投影分割是先水平方向投影,在豎直方向投影,或者先豎直方向再水平方向投影。本文選用先豎直,再水平。

   1.豎直投影。


 ------------

----------------

代碼:

#針對的是印刷版的漢字,所以採用了投影法分割
#此函數是行分割,結果是一行文字
def YShadow(path):
    img  = cv2.imread(path)   #原圖像
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #灰度圖像
    height,width = img.shape[:2]
    
    #blur = cv2.GaussianBlur(gray,(5,5),0) #高斯模糊
    
    blur = cv2.blur(gray,(8,8)) #均值模糊
    thresh = cv2.adaptiveThreshold(blur,255,1,1,11,2)  #自適應閾值分割
    temp = thresh
    
    if(width > 500 and height > 400): #圖像字體較小時,需要進行膨脹操作
        kernel = np.ones((5,5),np.uint8) #卷積核
        dilation = cv2.dilate(thresh,kernel,iterations = 1) #膨脹操作使得單個文字圖像被黑像素填充
        temp = dilation
    
    '''
    cv2.imshow('image',temp)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    '''
    
    perPixelValue = 1 #每個像素的值
    projectValArry = np.zeros(width, np.int8) #創建一個用於儲存每列黑色像素個數的數組


    for i in range(0,height):
        for j in range(0,width):
            perPixelValue = temp[i,j]
            if (perPixelValue == 255): #如果是黑字,對應位置的值+1
                projectValArry[i] += 1
       # print(projectValArry[i])
            
    canvas = np.zeros((height,width), dtype="uint8")
    
    for i in range(0,height):
        for j in range(0,width):
            perPixelValue = 255 #白色背景
            canvas[i, j] = perPixelValue
   

    for i in range(0,height):
        for j in range(0,projectValArry[i]):
            perPixelValue = 0 #黑色直方圖投影
            canvas[i, width-j-1] = perPixelValue
    '''
    cv2.imshow('canvas',canvas)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    '''
    
    list = []
    startIndex = 0 #記錄進入字符區的索引  
    endIndex = 0 #記錄進入空白區域的索引  
    inBlock = 0 #是否遍歷到了字符區內  


    for i in range(height):
        if (inBlock == 0 and projectValArry[i] != 0): #進入字符區
            inBlock = 1  
            startIndex = i
        elif (inBlock == 1 and projectValArry[i] == 0):#進入空白區
            endIndex = i
            inBlock = 0
            subImg = gray[startIndex:endIndex+1,0:width] #將對應字的圖片截取下來
            #print(startIndex,endIndex+1)
            list.append(subImg)#添加這個字圖像到list
    #print(len(list))
    return list
   2.水平投影

 ------------------------

------------------

#對行字進行單個字的分割
def XShadow(path):
    img  = cv2.imread(path)       
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    height,width = img.shape[:2]
   # print(height,width)
    #blur = cv2.GaussianBlur(gray,(5,5),0)
    
    blur = cv2.blur(gray,(8,8))
    thresh = cv2.adaptiveThreshold(blur,255,1,1,11,2) 
    
    if(width > 500):
        kernel = np.ones((4, 4),np.uint8) #卷積核
    else:
        kernel = np.ones((2, 2),np.uint8) #卷積核
    dilation = cv2.dilate(thresh,kernel,iterations = 1) #膨脹操作使得單個文字圖像被黑像素填充
    
    '''
    cv2.imshow('image',thresh)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    '''
    
    perPixelValue = 1 #每個像素的值
    projectValArry = np.zeros(width, np.int8) #創建一個用於儲存每列黑色像素個數的數組


    for i in range(0,width):
        for j in range(0,height):
            perPixelValue = dilation[j,i]
            if (perPixelValue == 255): #如果是黑字
                projectValArry[i] += 1
       # print(projectValArry[i])
            
    canvas = np.zeros((height,width), dtype="uint8")
    
    for i in range(0,width):
        for j in range(0,height):
            perPixelValue = 255 #白色背景
            canvas[j, i] = perPixelValue
   

    for i in range(0,width):
        for j in range(0,projectValArry[i]):
            perPixelValue = 0 #黑色直方圖投影
            canvas[height-j-1, i] = perPixelValue
    '''
    cv2.imshow('canvas',canvas)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    '''
    
    list = []
    startIndex = 0 #記錄進入字符區的索引  
    endIndex = 0 #記錄進入空白區域的索引  
    inBlock = 0 #是否遍歷到了字符區內  


    for i in range(width):
        if (inBlock == 0 and projectValArry[i] != 0): #進入字符區
            inBlock = 1  
            startIndex = i
        elif (inBlock == 1 and projectValArry[i] == 0): #進入投影區
            endIndex = i
            inBlock = 0
            #subImg = gray[0:height, startIndex:endIndex+1] #endIndex+1
            #print(startIndex,endIndex+1)
            list.append([startIndex, 0, endIndex-startIndex-1, height])
    #print(len(list))
    return list

   分割完後,將對應圖片樣本存儲到對應文件夾,每個字共10種樣本

   將這些樣本及標記保存後,分別加載到samples.npy, label.npy中。供後續的機器學習算法訓練使用。

   下篇講解填字圖片漢字的提取與機器學習算法訓練樣本,識別漢字的過程。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章