OpenCV Python:如何使用梯度和第一个点绘制一条线?

huangapple go评论111阅读模式
英文:

OpenCV python: How do I draw a line using the gradient and the first point?

问题

我正在尝试使用OpenCV从实时视频流中绘制一条线。我使用一个帧并存储x、y坐标。我使用下一个帧的点的x、y坐标来计算斜率((y2-y1)/(x2-x1))。我想绘制一条从第一个坐标开始直通第二个坐标并继续的直线,从而绘制一个轨迹。我目前可以使用cv2.line()在两点之间绘制一条直线。以下是我的代码。任何建议将不胜感激!谢谢

  1. import cv2
  2. import numpy as np
  3. import math
  4. import matplotlib.pyplot as plt
  5. lower_red = np.array([-10,160,160])
  6. upper_red = np.array([10,255,255])
  7. oX, oY = 0,0
  8. cap = cv2.VideoCapture(0)
  9. if not cap.isOpened():
  10. print("Cannot open camera")
  11. exit()
  12. while(1):
  13. ret, frame = cap.read()
  14. if not ret:
  15. print("Can't receive frame (stream end?). Exiting ...")
  16. break
  17. hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
  18. mask = cv2.inRange(hsv, lower_red, upper_red)
  19. #ret, thresh = cv2.threshold(mask, 80, 255, cv2.THRESH_BINARY)
  20. contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
  21. if len(contours) != 0:
  22. c = max(contours, key = cv2.contourArea)
  23. x1, y1, w, h = cv2.boundingRect(c)
  24. x2, y2 = x1 + w, y1 + h
  25. cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
  26. x3, y3 = round((x1+x2)/2), round((y1+y2)/2)
  27. cv2.circle(frame, (x3,y3), 4, (255,0,0), 2)
  28. #print(x3, y3)
  29. if oX and oY != 0:
  30. try:
  31. angle = (x3-oX)/(y3-oY)
  32. cv2.line(frame,(oX,oY),(x3, y3),(0,255,255),2)
  33. except ZeroDivisionError:
  34. oX, oY = x3, y3
  35. oX, oY = x3, y3
  36. cv2.imshow('frame', frame)
  37. cv2.imshow('mask', mask)
  38. if cv2.waitKey(1) == ord('q'):
  39. break
  40. # When everything done, release the capture
  41. cap.release()
  42. cv2.destroyAllWindows()
英文:

I am trying to draw a line using a live feed with opencv. I am using one frame and storing the x,y coordinates. I use the next frame's x,y coordinate of the point to work out the gradient ((y2-y1)/(x2-x1)). I want to draw a straight line from the first coordinate straight through the second and continue past which would draw a trajectory. I can currently draw a straight line between the two points using cv2.line(). My code is below. Any suggestions would be wonderful! Thank you

  1. import numpy as np
  2. import math
  3. import matplotlib.pyplot as plt
  4. lower_red = np.array([-10,160,160])
  5. upper_red = np.array([10,255,255])
  6. oX, oY = 0,0
  7. cap = cv2.VideoCapture(0)
  8. if not cap.isOpened():
  9. print("Cannot open camera")
  10. exit()
  11. while(1):
  12. ret, frame = cap.read()
  13. if not ret:
  14. print("Can't receive frame (stream end?). Exiting ...")
  15. break
  16. hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
  17. mask = cv2.inRange(hsv, lower_red, upper_red)
  18. #ret, thresh = cv2.threshold(mask, 80, 255, cv2.THRESH_BINARY)
  19. contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
  20. if len(contours) != 0:
  21. c = max(contours, key = cv2.contourArea)
  22. x1, y1, w, h = cv2.boundingRect(c)
  23. x2, y2 = x1 + w, y1 + h
  24. cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
  25. x3, y3 = round((x1+x2)/2), round((y1+y2)/2)
  26. cv2.circle(frame, (x3,y3), 4, (255,0,0), 2)
  27. #print(x3, y3)
  28. if oX and oY != 0:
  29. try:
  30. angle = (x3-oX)/(y3-oY)
  31. cv2.line(frame,(oX,oY),(x3, y3),(0,255,255),2)
  32. except ZeroDivisionError:
  33. oX, oY = x3, y3
  34. oX, oY = x3, y3
  35. cv2.imshow('frame', frame)
  36. cv2.imshow('mask', mask)
  37. if cv2.waitKey(1) == ord('q'):
  38. break
  39. # When everything done, release the capture
  40. cap.release()
  41. cv2.destroyAllWindows()

答案1

得分: 3

从这个答案中找到了一个解决方案,它是用C编写的,已转换为Python并根据您的用例进行了修改。

解决方案用于在给定两个点的情况下在图像中绘制无限线。

  1. def slope(x1, y1, x2, y2):
  2. ###找到斜率
  3. if x2 != x1:
  4. return ((y2 - y1) / (x2 - x1))
  5. else:
  6. return 'NA'
  7. def drawLine(image, x1, y1, x2, y2):
  8. m = slope(x1, y1, x2, y2)
  9. h, w = image.shape[:2]
  10. if m != 'NA':
  11. ### 这里我们实际上是将线段延伸到x=0和x=width,
  12. ### 并计算与之相关联的y
  13. ##起始点
  14. px = 0
  15. py = -(x1 - 0) * m + y1
  16. ##结束点
  17. qx = w
  18. qy = -(x2 - w) * m + y2
  19. else:
  20. ### 如果斜率为零,则绘制一条线段,其中x=x1且y=0和y=height
  21. px, py = x1, 0
  22. qx, qy = x1, h
  23. cv2.line(image, (int(px), int(py)), (int(qx), int(qy)), (0, 255, 0), 2)
  24. 您可以根据您的用例将`(px, py)`替换为`(x1, y1)`或将`(qx, qy)`替换为`(x2, y2)`
  25. [1]: https://stackoverflow.com/a/23186665/9605907
英文:

Found a solution from this answer which was in c, Converted to python and modified for your usecase.

Solution to draw infinte line in image given two points.

  1. def slope(x1,y1,x2,y2):
  2. ###finding slope
  3. if x2!=x1:
  4. return((y2-y1)/(x2-x1))
  5. else:
  6. return 'NA'
  7. def drawLine(image,x1,y1,x2,y2):
  8. m=slope(x1,y1,x2,y2)
  9. h,w=image.shape[:2]
  10. if m!='NA':
  11. ### here we are essentially extending the line to x=0 and x=width
  12. ### and calculating the y associated with it
  13. ##starting point
  14. px=0
  15. py=-(x1-0)*m+y1
  16. ##ending point
  17. qx=w
  18. qy=-(x2-w)*m+y2
  19. else:
  20. ### if slope is zero, draw a line with x=x1 and y=0 and y=height
  21. px,py=x1,0
  22. qx,qy=x1,h
  23. cv2.line(image, (int(px), int(py)), (int(qx), int(qy)), (0, 255, 0), 2)

you can replace (px,py) with (x1,y1) or (qx,qy) with (x2,y2) according to your usecase.

huangapple
  • 本文由 发表于 2020年1月3日 20:42:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/59578855.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定