Search code examples
python-2.7opencvdetectionlines

Python Opencv\ Detect and delete a line on an image


My personal project is to study how image processing works using Python. I am totally new to the field. I have a little problem that has bothered me for several minutes (Actually it's been an hour that I block something so simple though probably in your eyes ...)


Let me explain:


I would like to extract (or rather "delete") this line on my image (I ironed this one in red so that we can see it at best): http://prntscr.com/hhgzhk

By following this tutorial (https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/py_gradients/py_gradients.html#gradients) I managed to make the line in question appear more prominently, as shown this image. http://prntscr.com/hhgy72

I would now like to detect the lines in this image using this method: https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/py_houghlines/py_houghlines.html#py-hough-lines

Once the methods applied to my image, I get the following error:

   for rho,theta in lines[0]:
TypeError: 'NoneType' object has no attribute '__getitem__'

Here is the content of the code (It corresponds totally to the tutorial:')):

import cv2
import numpy as np

img = cv2.imread('houghlines3.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray,50,150,apertureSize = 3)

lines = cv2.HoughLines(edges,1,np.pi/180,200)
for rho,theta in lines[0]:
    a = np.cos(theta)
    b = np.sin(theta)
    x0 = a*rho
    y0 = b*rho
    x1 = int(x0 + 1000*(-b))
    y1 = int(y0 + 1000*(a))
    x2 = int(x0 - 1000*(-b))
    y2 = int(y0 - 1000*(a))

    cv2.line(img,(x1,y1),(x2,y2),(0,0,255),2)

cv2.imwrite('houghlines4.jpg',img)

Once I have analyzed it, I realize that the error probably comes from the fact that the content of the variable "lines" is None. Thus, I deduce that he found no lines on my image.

The question I'm asking myself now is how to extract this line in question?

I do not know if a person has an idea.

I realize that I want to do this on a captcha, and so it's not too ethical. Know that this is entirely educational, I do not want to hurt anyone :(


EDIT

After some advice, I managed to detect the famous line in question :) Here is the line detected after using Canny and modified the parameters: http://prntscr.com/hhmhe4

Here is the code (It is not very clean at all but it works):

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('la.png',0)
# gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(img,50,150,apertureSize = 3)

lines = cv2.HoughLines(edges,1,np.pi/50,50)
for rho,theta in lines[0]:
    a = np.cos(theta)
    b = np.sin(theta)
    x0 = a*rho
    y0 = b*rho
    x1 = int(x0 + 1000*(-b))
    y1 = int(y0 + 1000*(a))
    x2 = int(x0 - 1000*(-b))
    y2 = int(y0 - 1000*(a))

    cv2.line(img,(x1,y1),(x2,y2),(0,0,255),2)

cv2.imwrite('555.jpg',img)

My mistake was not having changed the right settings. I now understand better how these functions work


Solution

  • I suggest the following approach to test your code:

    1. try cv2.imshow(edge) to see if Canny edge detection detected the lines that you want to get rid of. If it hasn't, you can change the parameters so that they are detected.

    2.If you can see the line there, then you can adjust the parameters of cv2.HoughLines. I particularly suspect the parameter value 200 there.You should try reducing it to be less than the length of the lines in your image.

    My opinion is that it is perfectly fine to try and break CAPTCHA. There are some research papers where deep learning methods have decoded them with good accuracy. If you want to try a machine learning approach for solving this problem, you can do it with keras and I can provide a link to a research paper.