Search code examples
pythonopencvscikit-image

Any good OpenCV or SKImage techniques to thin out gridlines?


I have extracted a clean grid pattern:

Grid

This above is the grid before I "skeletonize" (or thin, or perform the medial axis transform).

An below is the image after an application of skimage.skeletonize|medial_axis|thin or method=lee for the skeletonize:

Oblated Grid

These seem to eliminate the grid entirely due to the "boldness" or "thickness" of the lines.

Is there a preferred method to thin out these lines?


Solution

  • I have modified @Miki's answer (actually my search revealed that it was originally posted by another SO user in 2013). See if this solution is something that you could modify, by maybe tweaking a few parameters, to work for your case.

    oElem = cv2.getStructuringElement(cv2.MORPH_RECT,(10,1))
    h = cv2.morphologyEx(img, cv2.MORPH_OPEN, oElem,  iterations = 5)
    
    oElem = cv2.getStructuringElement(cv2.MORPH_RECT,(1,10))
    v = cv2.morphologyEx(img, cv2.MORPH_OPEN, oElem,  iterations = 5)
    
    size = np.size(img)
    skelh = np.zeros(img.shape,np.uint8)
    skelv = np.zeros(img.shape,np.uint8)
    
    ret,img = cv2.threshold(img,127,255,0)
    element = cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))
    done = False
    while( not done):
        eroded = cv2.erode(h,element)
        temp = cv2.dilate(eroded,element)
        temp = cv2.subtract(h,temp)
        skelh = cv2.bitwise_or(skelh,temp)
        h = eroded.copy()
     
        if cv2.countNonZero(h)==0:
            done = True
            
    done = False
    while( not done):
        eroded = cv2.erode(v,element)
        temp = cv2.dilate(eroded,element)
        temp = cv2.subtract(v,temp)
        skelv = cv2.bitwise_or(skelv,temp)
        v = eroded.copy()
     
        if cv2.countNonZero(v)==0:
            done = True
            
    skel = cv2.bitwise_or(skelh,skelv)
    

    Result skeleton image