0

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

3

1 Answer 1

1

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)
Sign up to request clarification or add additional context in comments.

2 Comments

Could you please explain this part of your code# 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)
@Shashiwadana Stack the detections part to join the arrays which contain the detected lines all together in one array(vertically) instead of 3. # Draw the Lines part is for each row in the array get the 4 coordinates x1, x2, y1, y2 and simply draw the line over the image, to understand it perfectly try to print the shape of the array before, and after stacking.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.