问题
I have this source image:
My goal is to remove the bottom line while keep the letters/numbers untouched.
This is the code I use:
import cv2
import numpy as np
img = cv2.imread('src.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray,100,200,apertureSize = 5)
minLineLength = 0
maxLineGap = 19
lines = cv2.HoughLinesP(edges,1,np.pi/180,15,minLineLength,maxLineGap)
for x in range(0, len(lines)):
for x1,y1,x2,y2 in lines[x]:
cv2.line(img,(x1,y1),(x2,y2),(255,255,255),2)
cv2.imshow('hough',img)
cv2.waitKey(0)
The best result I achieved by now is this:
How can I improve it more, to clean the image as much as possible ? For example, all the debris all around the image, points and (still) lines under the words, how can I remove them ?
Thank you.
OT: is there a way to create a trackbar of this which change the parameters (apertureSize, minLineLength, maxLineGap, etc) to see results in real time ?
回答1:
As per @Link 's request:
I have limited experience in python so I don't know how thread safe this code is, but this should show you the basics of creating trackbars in python OpenCV.
def onChange(pos):
global img
global gray
global dst
dst = np.copy(img)
apertureSize = cv2.getTrackbarPos("ApertureSize", "Result")
minLineLength = cv2.getTrackbarPos("LineLength", "Result")
maxLineGap = cv2.getTrackbarPos("LineGap", "Result")
# according to OpenCV, aperture size must be odd and between 3 and 7
if apertureSize % 2 == 0:
apertureSize += 1
if apertureSize < 3:
apertureSize = 3
edges = cv2.Canny(gray,100,200,apertureSize = apertureSize)
lines = cv2.HoughLinesP(edges,1,np.pi/180,15,minLineLength,maxLineGap)
for x in range(0, len(lines)):
for x1,y1,x2,y2 in lines[x]:
cv2.line(dst,(x1,y1),(x2,y2),(255,255,255),2)
#Run Main
if __name__ == "__main__" :
img = cv2.imread("image.png", -1)
dst = np.copy(img)
cv2.namedWindow("Result", cv2.WINDOW_NORMAL)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#default values for trackbars
defaultApertureSize = 5
minLineLength = 0
maxLineGap = 19
# according to OpenCV, aperture size must be odd and between 3 and 7
# the aperture size range is (0 - 6)
cv2.createTrackbar("ApertureSize", "Result", defaultApertureSize, 6, onChange)
# line length range is (0 - 10)
cv2.createTrackbar("LineLength", "Result", minLineLength, 10, onChange)
# line gap range is (0 - 19)
cv2.createTrackbar("LineGap", "Result", maxLineGap, 19, onChange)
while True:
cv2.imshow("Result", dst)
key = cv2.waitKey(1)
if key == ord('q'):
break
cv2.destroyAllWindows()
回答2:
Once you have the line segments from Hough you could search them to find the ones likely to be part of the bottom line (ie correct angle and intercept) then remove all black dots along this predicted line rather than just the segments found by hough.
Another tip, try cv::adaptivethreshold rather than canny and try doing a small Gaussian blur first to remove background specks.
Edit: You are using HoughP which finds each lien segment individually. You are looking for a single (broken) line so would probably be better using regular Hough and from the results select the strongest horizontal line in the bottom half of the image - then erase all dots along that direction.
ot: the cv::namedWindow can have a trackbar where you can easily get back the value
来源:https://stackoverflow.com/questions/46472713/improve-houghlines-for-horizontal-lines-detect-python-opencv