Search code examples
imageimage-processingcomputer-visioncell

How to repair incomplete grid cells and fix missing sections in image


I used Hough lines to get intersection of horizontal and vertical lines in this image:

enter image description here

but the complexity grows with the grid cells count significantly.

Is there any simple way to complete the grid without using line detection ?

Thank you.


Solution

  • Here's a potential solution using morphological operations with OpenCV

    1. Obtain binary image. Load image, grayscale, Gaussian blur, Otsu's threshold

    2. Obtain horizontal/vertical lines masks. Create horizontal/vertical kernel and isolate horizontal/vertical grid lines with cv2.getStructuringElement() and cv2.morphologyEx()

    3. Combine masks. Bitwise-and masks together to complete grid

    4. Fill individual grid holes. Find contours and fix holes by filling in each grid cell


    Binary image

    Horizontal mask (left) and vertical mask (right)

    Combine masks

    Repair individual grid holes

    Invert for result

    import cv2
    
    # Load image, grayscale, blur, Otsu's threshold
    image = cv2.imread('1.jpg')
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    blur = cv2.GaussianBlur(gray, (3,3), 0)
    thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
    
    # Obtain horizontal lines mask
    horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (50,1))
    horizontal_mask = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=1)
    horizontal_mask = cv2.dilate(horizontal_mask, horizontal_kernel, iterations=9)
    
    # Obtain vertical lines mask
    vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,50))
    vertical_mask = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, vertical_kernel, iterations=1)
    vertical_mask= cv2.dilate(vertical_mask, vertical_kernel, iterations=9)
    
    # Bitwise-and masks together
    result = 255 - cv2.bitwise_or(vertical_mask, horizontal_mask)
    
    # Fill individual grid holes
    cnts = cv2.findContours(result, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    for c in cnts:
        x,y,w,h = cv2.boundingRect(c)
        cv2.rectangle(result, (x, y), (x + w, y + h), 255, -1)
    
    cv2.imshow('thresh', thresh)
    cv2.imshow('vertical_mask', vertical_mask)
    cv2.imshow('horizontal_mask', horizontal_mask)
    cv2.imshow('result', result)
    cv2.waitKey()