2014-02-18 25 views
1

骨架化過程產生的圖像大致代表了形狀的骨架,但它不是輪廓。如何將骨架轉換爲輪廓?如何將曲線擬合成鏤空圖像?

enter image description here


使用下面的OpenCV/Python代碼就可以通過骨架化過程中的以下's.png的形象上獲得:

enter image description here

import numpy as np 
import cv2, cv 
img = cv2.imread("s.png",0) 
size = np.size(img) 
skel = np.zeros(img.shape,np.uint8) 

ret,img = cv2.threshold(img,127,255,0) 
element = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3)) 
done = False 

img =cv2.bitwise_not(img) 
original = img 

while(not done): 
    eroded = cv2.erode(img,element) 
    temp = cv2.dilate(eroded,element) 
    temp = cv2.subtract(img,temp) 
    skel = cv2.bitwise_or(skel,temp) 
    img = eroded.copy() 

    zeros = size - cv2.countNonZero(img) 
    if zeros==size: 
     done = True 

cv2.imshow("original", original) 
cv2.imshow("skeleton",skel) 
cv2.imshow("dilate-skeleton",cv2.dilate(skel, element)) 

回答

0
#!/usr/bin/env python 

import pylab as pl 
import numpy as np 
import cv2 


def skeletonize(image): 
    img = image 
    size = np.size(img) 
    skel = np.zeros(img.shape,np.uint8) 

    ret,img = cv2.threshold(img,127,255,0) 
    element = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3)) 
    done = False 

    img =cv2.bitwise_not(img) 
    # original = img 

    while(not done): 
     eroded = cv2.erode(img,element) 
     temp = cv2.dilate(eroded,element) 
     temp = cv2.subtract(img,temp) 
     skel = cv2.bitwise_or(skel,temp) 
     img = eroded.copy() 

     zeros = size - cv2.countNonZero(img) 
     if zeros==size: 
      done = True 

    return skel, cv2.dilate(skel, element) 


def collapse_contours(contours): 
    contours = np.vstack(contours) 
    contours = contours.squeeze() 
    return contours 


def get_rough_contour(image): 
    """Return rough contour of character. 
    image: Grayscale image. 
    """ 
    skeleton, dskeleton = skeletonize(image) 
    contours, hierarchy = cv2.findContours(skeleton, 
              cv2.RETR_EXTERNAL, 
              cv2.CHAIN_APPROX_SIMPLE) 
    contour = collapse_contours(contours) 
    return contour 


def draw_contour(image, contour, colors=(255, 0, 0)): 
    for p in contour: 
     cv2.circle(image, tuple(p), 1, colors, -1) 


def main(): 
    image = cv2.imread("s.png", 0) 
    contour = get_rough_contour(image) 
    # You will probably want to do some spline fitting here to 
    # smooth the contour 
    draw_contour(image, contour) 
    pl.imshow(image, cmap=pl.cm.gray) 


if __name__ == '__main__': 
    main() 

結果: enter image description here