title: Detecting edges of lasers/lights in images using Python
body: <p>I am writing a program in Python to loop through images extracted from the frames of a video and detect lines within them. The images are of fairly poor quality and vary significantly in their content. Here are two examples:
  <a href="http://i.stack.imgur.com/nqAvm.jpg" rel="nofollow">Sample Image 1</a> | <a href="http://i.stack.imgur.com/2pQ0B.jpg" rel="nofollow">Sample Image 2</a></p>
  
  <p>I am trying to detect the lasers in each image and look at their angles. Eventually I would like to look at the distribution of these angles and output a sample of three of them.</p>
  
  <p>In order to detect the lines in the images, I have looked at various combinations of the following:</p>
  
  <ul>
  <li>Hough Lines</li>
  <li>Canny Edge Detection</li>
  <li>Bilateral / Gaussian Filtering</li>
  <li>Denoising</li>
  <li>Histogram Equalising</li>
  <li>Morphological Transformations</li>
  <li>Thresholding</li>
  </ul>
  
  <p>I have tried lots of combinations of lots of different methods and I can't seem to come up with anything that really works. What I have been trying is along these lines:</p>
  
  <pre><code>import cv2
  import numpy as np
  
  img = cv2.imread('testimg.jpg')
  grey = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
  
  clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
  equal = clahe.apply(grey)
  
  denoise = cv2.fastNlMeansDenoising(equal, 10, 10, 7, 21)
  
  blurred = cv2.GaussianBlur(denoise, (3, 3), 0)
  blurred = cv2.medianBlur(blurred, 9)
  
  (mu, sigma) = cv2.meanStdDev(blurred)
  edge = cv2.Canny(blurred, mu - sigma, mu + sigma)
  
  lines = cv2.HoughLines(edge, 1, np.pi/180, 50)
  
  if lines is not None:
      print len(lines[0])
  
      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.imshow("preview", img)
  cv2.waitKey(0)
  </code></pre>
  
  <p>This is just one of many different attempts. Even if I can find a method that works slightly better for one of the images, it proves to be much worse for another one. I am not expecting completely perfect results, but I'm sure that they could be better than I've managed so far!</p>
  
  <p>Could anyone suggest a tactic to help me move forward?</p>