我有一个可以投射红十字形状的激光笔。我的目标是编写一个 python 代码来检测视频源中的这两条投影线。我使用手机摄像头作为源,视频通过网络 IP 源进行流式传输。
首先,我想在尝试使用视频输入之前检测单个图像中的线条。我在下面编写了 python 代码,结果我得到了多行而不是十字上的主线。您可以看到输入和输出图像。我想去掉不需要的线并只检测十字上的主要两条线。
# 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()
当我用视频源尝试时,它根本没有检测到任何线条。我用来传输视频的移动应用程序是“IP Webcam”。你可以在下面看到我的代码。
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()
我之前也遇到过同样的问题,
HouhLinesP
这个函数迫切需要非最大抑制。
我的答案不是完整的答案,但您可以使用下面的函数来消除重复的行。方法如下:
您可以直接将
HoughLinesP
的输出提供给此函数。有什么问题请尽管问。
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