Celotos
Celotos

Reputation: 21

Edge detection in dark images with background noise

I have many images from a high-speed camera that I would like to analyze. In the first step, I want to recognize the edges of a wiper, but I have problems recognizing them automatically because they are only displayed negatively, i.e. they are black in the image.example picture

I have tried to output the straight lines via canny and HoupHLinesP using the cv2 library or, in another attempt, to display the gradient transitions via Sobel and then to display the straight lines again via canny and HoupHLinesP in the gradient image. Furthermore, I have varied the thresholds of HoupHLines but have the problem that I get many lines displayed that I do not want and those that I want are not displayed. Several lines are displayed that are very close to each other or parts of the lines I want are not displayed. In addition, the straight lines do not lie perfectly on the edge, as you can see from the straight line on the right. Furthermore, I have to adjust the thresholds for the individual image so that all straight lines are visible. If I adjust the thresholds automatically until only x straight lines are visible, the desired ones are often not included. Image Sobel Image with detected lines

Ideally, the whole thing should work in such a way that at the end only the right and left straight lines are output and the edge in the middle is hidden and the whole thing can be done for all images without manual adjustment.

Does anyone have any ideas on how this could be implemented or are there other commands or libraries that do the job better?

Here is a code example of one of my attempts:

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

def is_vertical_line(x1, y1, x2, y2, angle_threshold=5):
    """Überprüft, ob eine Linie innerhalb des angegebenen Winkelbereichs senkrecht ist."""
    angle = np.degrees(np.arctan2(y2 - y1, x2 - x1))
    angle = abs(angle) % 180
    return abs(angle - 90) <= angle_threshold


image = cv2.imread('F:\Studienarbeit\Testdaten\SourceDaten\DEG_30kgh_8mbar_250rpm_110grad_HD2bar_Img000087.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)


sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3)
abs_sobelx = np.absolute(sobelx)
sobelx_8u = np.uint8(abs_sobelx)
edges = cv2.Canny(sobelx_8u, 5, 250, apertureSize=3)



lines = cv2.HoughLinesP(edges, 1, np.pi / 180, threshold=5, minLineLength=250, maxLineGap=40)

image_with_lines = image.copy()
if lines is not None:
    for line in lines:
        x1, y1, x2, y2 = line[0]
        if is_vertical_line(x1, y1, x2, y2):
            cv2.line(image_with_lines, (x1, y1), (x2, y2), (0, 0, 255), 2)



plt.figure(figsize=(12, 6))

plt.subplot(1, 2, 1)
plt.imshow(cv2.convertScaleAbs(sobelx_8u), cmap='gray')
plt.title('Sobel Gradient')

plt.subplot(1, 2, 2)
plt.imshow(cv2.cvtColor(image_with_lines, cv2.COLOR_BGR2RGB))
plt.title('HoughLinesP')

plt.show()

Here are a few pictures that show how the wiper moves through the picture(Beween the first and the last picture are 7 pictures that are not shown here): enter image description here

enter image description here

enter image description here

Image when it is slightly rotated: enter image description here

Upvotes: 0

Views: 207

Answers (1)

Mark Setchell
Mark Setchell

Reputation: 208052

Maybe it helps if you sum the pixels down the columns. I did that and appended the result at the bottom.

enter image description here

It's just convert to greyscale, then :

colSums = np.sum(image, axis=0)

Or, you may fare better using np.mean(image, axis=0) if your images vary in height and you want to set a threshold.

Upvotes: 2

Related Questions