opencvimage-processinghoughlinespstraight-line-detection

How to detect all the verticle background lines using Probabilistic Hough lines transform?


I'm trying to detect background lines of a pre-processed binary image of a newspaper article using Hough lines transform.

The code I used is given below and it detects only one vertical background line, but I want to detect all the vertical background lines.

How can I improve my code to detect all the vertical background lines only as I marked in the expected output image?

import cv2 as cv
import numpy as np
import os
    
#binary image
image = cv.imread('../outputs/contour.jpg')
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)  # convert2grayscale
(thresh, binary) = cv.threshold(gray, 150, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
#cv.imshow('binary',binary)
#cv.waitKey(0)
    
minLineLength = 10
maxLineGap = 40
lines=np.array([])
    
lines = cv.HoughLinesP(binary,rho=np.pi/180,theta=np.pi/180,threshold=10,lines=lines,minLineLength=minLineLength,maxLineGap=maxLineGap)

for x1,y1,x2,y2 in lines[0]:
   cv.line(image,(x1,y1),(x2,y2),(0,255,0),2)
    
cv.imshow('lines',image)
path='../outputs'
cv.imwrite(os.path.join(path , 'line.jpg'), image)
cv.waitKey(0)

The expected Output is like this:enter image description here

But the output I get from above code is this: enter image description here

The input image is: enter image description here


Solution

  • This is a brute-force solution, you might want to optimize the parameters to make it better:

    result

    #------------------#
    # Import Libraries #
    #------------------#
    import matplotlib.pyplot as plt
    import numpy as np
    import cv2
    
    # Read Image
    image = cv2.imread('input.jpg', 0)
    # Gaussian Blur 
    blur = cv2.GaussianBlur(image,(13,13),5)
    # Morphological opening
    kernel = np.ones((11,11), dtype=np.uint8)
    opening = cv2.morphologyEx(blur, cv2.MORPH_OPEN, kernel)
    
    # Thresholding
    (_, thresh) = cv2.threshold(opening, 150, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
    (_, thresh2) = cv2.threshold(image, 150, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
    # Stacking the image to draw lines in colour
    image = np.stack([image, image, image], axis=2)
    
    # Define Hough Parameters
    minLineLength = 40
    maxLineGap = 10
    # Hough Lines Detection
    lines1 = cv2.HoughLinesP(thresh,rho=np.pi/180,theta=np.pi/180,threshold=1,minLineLength=minLineLength,maxLineGap=maxLineGap)
    lines2 = cv2.HoughLinesP(thresh,rho=np.pi/180,theta=np.pi/180,threshold=10,minLineLength=minLineLength,maxLineGap=maxLineGap)
    lines3 = cv2.HoughLinesP(thresh2,rho=np.pi/180,theta=np.pi/180,threshold=10,minLineLength=minLineLength,maxLineGap=maxLineGap)
    
    # Stack the detections
    Lines = np.vstack([lines1[0], lines2[0], lines3[0]])
    
    # Draw the Lines
    for row in range(Lines.shape[0]):
        x1,y1,x2,y2 = Lines[row, 0], Lines[row, 1], Lines[row, 2], Lines[row, 3]
        cv2.line(image,(x1,y1),(x2,y2),(0,255,0),2)
    
    # Visualize results
    cv2.imshow('lines',image)
    cv2.waitKey(0)