0

I have a laser pointer that projects red cross shape. My aim is to write a python code that detects those two projected lines from a video source. I use my mobile phone camera as a source and the video is streamed via web IP source.

1

First, I wanted to detect the lines from a single image before trying it out with video input. I have written python code below, as a result I came out with multiple lines instead of the main lines on the cross. You can see input and output images. I want to get rid of unwanted lines and detect only the main two lines on the cross.

# import necessary modules
import numpy as np
import urllib.request
import cv2 as cv

# read the image
with open("input.jpg", "rb") as image:
    f = image.read()

    # convert to byte array
    bytef = bytearray(f)

    # convert to numpy array
    image = np.asarray(bytef)

    # Convert image to grayscale
    gray = cv.imdecode(image, 1)

    # Use canny edge detection
    edges = cv.Canny(gray, 50, 150, apertureSize=3) # default apertureSize: 3

    # Apply HoughLinesP method to
    # to directly obtain line end points
    lines_list = []
    lines = cv.HoughLinesP(
        edges,  # Input edge image
        1,  # Distance resolution in pixels
        np.pi / 180,  # Angle resolution in radians
        threshold=100,  # Min number of votes for valid line (default: 100)
        minLineLength=50,  # Min allowed length of line
        maxLineGap=10  # Max allowed gap between line for joining them (default: 10)
    )

    if lines is not None:
        # Iterate over points
        for points in lines:
            # Extracted points nested in the list
            x1, y1, x2, y2 = points[0]
            # Draw the lines joing the points
            # On the original image
            cv.line(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
            # Maintain a simples lookup list for points
            lines_list.append([(x1, y1), (x2, y2)])

    # display image
    cv.imshow("Image", image)
    cv.waitKey()

2

When I tried it with video source, it did not detect any lines at all. Mobile app that I used to stream video is "IP Webcam". You can see my code below.

import numpy as np
import cv2 as cv

# replace with your own IP provided in ip webcam mobile app "IPv4_address/video"
cap = cv.VideoCapture("http://192.168.1.33:8080/video")

while(True):
    _, image = cap.read()

    # Resize the image
    image = cv.resize(image, (500, 500))

    # Convert image to grayscale
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)

    # Use canny edge detection
    edges = cv.Canny(gray, 50, 150, apertureSize=3)

    # Apply HoughLinesP method to
    # to directly obtain line end points
    lines_list = []
    lines = cv.HoughLinesP(
        edges,  # Input edge image
        1,  # Distance resolution in pixels
        np.pi / 180,  # Angle resolution in radians
        threshold=10,  # Min number of votes for valid line (default: 100)
        minLineLength=5,  # Min allowed length of line
        maxLineGap=200  # Max allowed gap between line for joining them (default: 10)
    )

    if lines is not None:
        # Iterate over points
        for points in lines:
            # Extracted points nested in the list
            x1, y1, x2, y2 = points[0]
            # Draw the lines joing the points
            # On the original image
            cv.line(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
            # Maintain a simples lookup list for points
            lines_list.append([(x1, y1), (x2, y2)])

    cv.imshow('Livestream', image)
    if cv.waitKey(1) == ord('q'):
        break

cap.release()
cv.destroyAllWindows()


4
  • 2
    In your secound code example you draw the lines on gray but you display image. Commented Jun 2, 2024 at 20:04
  • 1
    Don't bother with Canny. In that first image, I'd look for the saturated pixels, those seem to make a nice, crisp line. Commented Jun 2, 2024 at 22:32
  • @Markus You are right, sorry. Corrected it. Commented Jun 4, 2024 at 20:05
  • Does the line detection using the video source work, now? Commented Jun 4, 2024 at 20:09

1 Answer 1

0

I had the same problem before with HouhLinesP this function desperately r-requires a non-max suppression.

My answer is not a complete answer but you can use the below function to eliminate the repetitive lines. Here is the approach:

  1. Find start and end points of all lines
  2. These points are on the screen (x in [0,width] and y in [0,height])
  3. Compare the start and end points of each line and eliminate the repetitions.

You can directly give output of the HoughLinesP to this function. Feel free to ask anything.

def findUniqueLines(lines):
    # Find start and end points of all lines and add them to list
    newlines = []
    for [[x1,y1,x2,y2]] in lines:
        if x1==x2:           #perfectly vertical line
            start = (x1,0)
            end = (x1,h)
    
        elif y1==y2:         #perfectly horizontal line
            start = (0,y1)
            end = (w,y1)
    
        else:                #lines with a slope                   
            m,n = numpy.polyfit((x1,x2),(y1,y2),deg=1) #line eq:y=mx+n

            if abs(m) > 1:          #vertical-like line
                start = (-n/m,0)
                end = ((h-n)/m,h)
            else:                   #horizontal-like line
                start = (0,m*0+n)
                end = (w,m*w+n)

        if start[0]*start[1]>=0 or end[0]*end[1]>=0:
            newlines.append([[start[0],start[1],end[0],end[1]]])

    #Comparing the start end points extract the unique lines 
    unique_lines = []
    unique_lines.append(newlines[0])
    for [[sx,sy,ex,ey]] in newlines:#iterate over all lines
        s = (sx,sy)
        e = (ex,ey)

        for [[sUx,sUy,eUx,eUy]] in unique_lines:#compare each with unique lines
            sU = (sUx,sUy)
            eU = (eUx,eUy)

            #If the start and end points are within 50px range its not a unique line
            if math.dist(s,sU)<50 and math.dist(e,eU)<50:
                break
        else:
            unique_lines.append([[sx,sy,ex,ey]])
    return unique_lines
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.