2

I have this source image:

src

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:

out

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 ?

lucians
  • 2,239
  • 5
  • 36
  • 64
  • Have you thought about running an OCR over the top and using the data gathered from that to turn everything else white? – GPPK Sep 28 '17 at 15:22
  • In fact yes. I used yesterday OCR with this in mind, trying to extract the chars and delete everything else. But, as you can see, here there are handwriting characters and OCR simply fail at this. Is this you mean ? – lucians Sep 28 '17 at 15:24
  • 1
    C++ trackbar: http://docs.opencv.org/3.3.0/da/d6a/tutorial_trackbar.html Python trackbar: http://docs.opencv.org/3.3.0/d9/dc8/tutorial_py_trackbar.html – zindarod Sep 28 '17 at 15:39
  • Thanks, I will try to convert it to Python. Know (nearly) nothig of C++ :) – lucians Sep 28 '17 at 15:41
  • @Zindarod you know how to implement the code above into trackbar ? – lucians Sep 29 '17 at 09:52

2 Answers2

1

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

Martin Beckett
  • 94,801
  • 28
  • 188
  • 263
  • I will do threshold and gaussian to see what happens, but I don't know how to do the first part you explained. I mean, is what I wanted to do, along X coordinate detect all the dots and delete them. Also, Hough was the "best" recomandation I had until now for this kind of work. BTW, I will try what you said. – lucians Sep 28 '17 at 15:40
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()
zindarod
  • 6,328
  • 3
  • 30
  • 58