I'm doing a personal project in which I want to select some very specific lines in a microscopy image. The first picture is the raw image, the second picture is the image for the lines (in yellow) I would like to detect. Not straight lines yes, but lines indeed.

1st image, no lines detected

Lines of interest in yellow

Now, I made a very basic code for line detection that kind of "works" detecting lines, but it takes a lot of undesired detected lines in the process. See an example with another image (and the code below it, in Python, using OpenCV).

Outcome of my code

import cv2 as cv
import numpy as np

#Load and normalize .tif image:
img = 'imagenes.tif'
img = cv.imread(img, 0)
img_scaled = cv.normalize(img,  np.zeros((800, 800)), 0, 255, cv.NORM_MINMAX)

#Resizing images:
pct = 30
w = int(img.shape[1] * pct / 100)
h = int(img.shape[0] * pct / 100)
dim = (w, h)
resized = cv.resize(img_scaled, dim, interpolation = cv.INTER_AREA)

# First stage: Gaussian blur.
gaussian = cv.GaussianBlur(resized,(5, 5),0)
# Second Stage: edge detection with Canny.
low_threshold = 90
high_threshold = 150
edges = cv.Canny(gaussian, low_threshold, high_threshold)
# Third stage: Hough Line transform.
rho = 1
theta = np.pi / 180
threshold = 15
minLineLenght = 15
maxLineGap = 15
myBlankLines = resized.copy()
lines = cv.HoughLinesP(edges, rho, theta, threshold, np.array([]),
                    minLineLenght, maxLineGap)
for line in lines:
    for x1,y1,x2,y2 in line:

cv.imshow('image_resized', resized)
cv.imshow('Stage 1: Gaussian', gaussian)
cv.imshow('Stage 2: Edges', edges)
cv.imshow('Stage 3: Lines', myBlankLines)

Now. I don't mind building a filter from zero and avoid using OpenCV or any other image processing/computer vision library. But I feel a bit lost on what direction I should go. I'm not sure if:

  1. Doing more pre-filtering.
  2. Adjust parameters for Hough Lines Transform.
  3. Something else related with Machine Learning perhaps.

What would you suggest? Thanks for any heads up you might have on this interesting task.

  • I used Median Blur instead of Gaussian Blur, and used Sobel Filter to detect the edges, the results are not perfect, but you can improve them if you tuned the parameters well(and they are many!)


# Import Libraries
import numpy as np
import cv2
import matplotlib.pyplot as plt

# Read Image
img = cv2.imread('1.png', 0)

# Median Blur
img = cv2.medianBlur(img, 3)

# Sobel filter for Edge detection
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=5)
sobel = np.sqrt(sobelx**2+sobely**2)

# Threshold Sobel to locate the lines
maxi = 0.30*sobel.max()
sobel[sobel<maxi] = 0

# Normalize
sobel = (255*sobel) / (sobel.max()-sobel.min())
sobel = sobel.astype('uint8')

# Hough Line transform.
rho = 1
theta = np.pi / 180
threshold = 15
minLineLenght = 18
maxLineGap = 13
myBlankLines = img.copy()
lines = cv2.HoughLinesP(sobel, rho, theta, threshold, np.array([]),
                    minLineLenght, maxLineGap)
for line in lines:
    for x1,y1,x2,y2 in line:

# Visualize Results
plt.imshow(myBlankLines, cmap='gray')
  • $\begingroup$ What you call "tunning the parameter well" will indeed be a key factor, the thing is I'm not sure what are the best and most convenient settings. I would love to read any suggestions for literature on this matternof course. $\endgroup$ – Aquiles Páez Nov 6 '20 at 13:57
  • $\begingroup$ @AquilesPáez The problem description isn't very clear to me, there are many lines in the image that you can spot visually, but you don't want them in your desired output, can you please specify on which basis did you chose only those desired specific lines? I mean in which manner they differ from the other lines? $\endgroup$ – Bilal Nov 6 '20 at 14:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.