2016-12-01 116 views
0

我想使用OpenCV分割圖像的字符以訓練Tesseract模型。drawContours無法在OpenCV 3.1.0中創建正確的蒙版

我使用的版本3.1.0(因爲MacPorts的升級 - 咩..),以及文件(對於Python)仍然不是很清楚/詳細記錄。

這裏是我做的:

  1. 二值化的形象,以準備找輪廓
  2. 找到輪廓(工作 - 至少我得到非零結果)
  3. 對於每個輪廓:

    1. 創建一個面具(這可能失敗 - 獲得零)
    2. 提取部分從原始圖像使用掩模(應該工作,但面具失敗,因此這並沒有工作)

的OpenCV的新版本有所不同的語法同樣,這使得它有時更加棘手。

這裏是我的代碼:

def characterSplit(img): 
    """ 
    Splits the characters in an image using contours, ready to be labelled and saved for training with Tesseract 
    """ 

    # Apply Thresholding to binarize Image 
    img = cv2.GaussianBlur(img, (3,3), 0) 
    img = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 75, 10) 
    img = cv2.bitwise_not(img) 

    # Find Contours 
    contours = cv2.findContours(img, cv2.RETR_EXTERNAL , cv2.CHAIN_APPROX_TC89_KCOS, offset=(0,0))[1] 

    # Iterate through the contours 
    for c in xrange(len(contours)): 
     mask = numpy.zeros(img.size) 

     cv2.drawContours(mask, contours, c, (0, 255, 0), cv2.FILLED) # Mask is zeros - It might fail here! 

     # Where the result will be stored 
     res = numpy.zeros(mask.size) 

     # Make a Boolean-type numpy array for the Mask 
     amsk = mask != 0 

     # I use this to copy a part of the image using the generated mask. 
     # The result is zeros because the mask is also zeros 
     numpy.copyto(res, img.flatten(), where = amsk) 

     ## (... Reshape, crop and save the result ...) 

據我所知,口罩應是相同的大小與原始圖像。但是它是否也具有相同的形狀?例如,我的圖像是640x74,但是我創建我的蒙版矩陣的方式是,我的蒙版是1x47360。也許這就是爲什麼它失敗... (但不會有任何錯誤)

任何幫助表示讚賞!

+1

你應該使用'cv :: connectedComponents'。 [它會更容易。](http://stackoverflow.com/a/36935370/5008845) – Miki

+0

好吧,我不知道'cv :: connectedComponents'。我會試一試 – ant0nisk

+0

@Miki好了,我玩過connectedComponents,但它沒有給出我需要的結果。在我的情況下,它可以檢測背景,但我想分割字符。所以,每個角色應該是一個區域/標籤。是否有可能通過connectedComponents完成? – ant0nisk

回答

1

我最終做了Miki在評論中提出的建議。我用cv::connectedComponents做字符分割。這裏是相應的代碼,對於任何有興趣的人:

def characterSplit(img, outputFolder=''): 
    # Splits the Image (OpenCV Object) into distinct characters and exports it in images withing the specified folder. 

    # Blurring the image with Gaussian before thresholding is important 
    img = cv2.GaussianBlur(img, (3,3), 0) 
    img = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 75, 10) 
    img = cv2.bitwise_not(img) 

    output = cv2.connectedComponentsWithStats(img, 8, cv2.CV_16S) 
    n_labels = output[0] 
    labels = output[1] 
    stats = output[2] 

    for c in xrange(n_labels): 
     # Mask is a boolean-type numpy array with True in the corresponding region 
     mask = labels == c 

     res = numpy.zeros(img.shape) 
     numpy.copyto(res, img, where=mask) 

     # The rectangle that bounds the region is stored in: 
     # stats[c][0:4] -> [x, y, w, h] 

     cv2.imwrite("region_{}.jpg".format(c), res) 

希望這有助於!