Python 用于检测视频中矩形形状(文本光标)的对象检测模型?
我目前正在做一些研究,以检测和定位屏幕录制视频中的文本光标(你知道,当你在计算机上键入时,指示字符位置的闪烁矩形)。为此,我使用自定义对象数据集(我从中获取了一个参考)训练了YOLOv4模型,并计划实现DeepSORT来跟踪移动的光标 下面是我用来训练YOLOv4的训练数据示例: 以下是我想要实现的目标: 您认为使用YOLOv4+DeepSORT是否被认为是完成此任务的过度手段?我这样问是因为到目前为止,只有70%-80%的包含文本光标的视频帧能够被模型成功检测到。如果这毕竟是过火了,那么您知道可以为这项任务实现的其他方法吗 无论如何,我计划不仅从VisualStudio代码窗口检测文本光标,还从浏览器(如Google Chrome)和文本处理器(如Microsoft Word)检测文本光标。大概是这样的: 我正在考虑将滑动窗口方法作为一种替代方法,但从我所读到的内容来看,该方法可能会消耗大量资源,并且执行速度较慢。我也在考虑从OpenCV()进行模板匹配,但我认为它的性能不会比YOLOv4更好更快 约束是关于性能速度(即,给定时间可以处理多少帧)和检测精度(即,我希望避免将字母“l”或“1”检测为文本光标,因为这些字符在某些字体中类似)。但我认为,更高的精度和较慢的FPS是可以接受的 我目前正在使用Python、Tensorflow和OpenCV来实现这一点。Python 用于检测视频中矩形形状(文本光标)的对象检测模型?,python,opencv,computer-vision,object-detection,yolo,Python,Opencv,Computer Vision,Object Detection,Yolo,我目前正在做一些研究,以检测和定位屏幕录制视频中的文本光标(你知道,当你在计算机上键入时,指示字符位置的闪烁矩形)。为此,我使用自定义对象数据集(我从中获取了一个参考)训练了YOLOv4模型,并计划实现DeepSORT来跟踪移动的光标 下面是我用来训练YOLOv4的训练数据示例: 以下是我想要实现的目标: 您认为使用YOLOv4+DeepSORT是否被认为是完成此任务的过度手段?我这样问是因为到目前为止,只有70%-80%的包含文本光标的视频帧能够被模型成功检测到。如果这毕竟是过火了,那么
多谢各位 如果光标是屏幕上唯一移动的对象,这将起作用。以下是之前和之后的内容: 之前: 之后: 守则:
import cv2
import numpy as np
BOX_WIDTH = 10
BOX_HEIGHT = 20
def process_img(img):
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
kernel = np.ones((5, 5))
img_canny = cv2.Canny(img_gray, 50, 50)
return img_canny
def get_contour(img):
contours, hierarchies = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
if contours:
return max(contours, key=cv2.contourArea)
def get_line_tip(cnt1, cnt2):
x1, y1, w1, h1 = cv2.boundingRect(cnt1)
if h1 > BOX_HEIGHT / 2:
if np.any(cnt2):
x2, y2, w2, h2 = cv2.boundingRect(cnt2)
if x1 < x2:
return x1, y1
return x1 + w1, y1
def get_rect(x, y):
half_width = BOX_WIDTH // 2
lift_height = BOX_HEIGHT // 6
return (x - half_width, y - lift_height), (x + half_width, y + BOX_HEIGHT - lift_height)
cap = cv2.VideoCapture("screen_record.mkv")
success, img_past = cap.read()
cnt_past = np.array([])
line_tip_past = 0, 0
while True:
success, img_live = cap.read()
if not success:
break
img_live_processed = process_img(img_live)
img_past_processed = process_img(img_past)
img_diff = cv2.bitwise_xor(img_live_processed, img_past_processed)
cnt = get_contour(img_diff)
line_tip = get_line_tip(cnt, cnt_past)
if line_tip:
cnt_past = cnt
line_tip_past = line_tip
else:
line_tip = line_tip_past
rect = get_rect(*line_tip)
img_past = img_live.copy()
cv2.rectangle(img_live, *rect, (0, 0, 255), 2)
cv2.imshow("Cursor", img_live)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
cv2.destroyAllWindows()
while
循环,并从视频中读取。处理视频中的帧和该帧之前的帧:cv2.bitwise\u xor
方法找到帧之间的差异,以获得屏幕上的运动位置。然后,我们可以使用定义的get\u contour
函数找到两帧之间的运动轮廓:get\u line\u tip
函数来查找光标的尖端。如果找到了提示,请将其保存到line\u tip\u pass
变量中以用于下一次迭代,如果未找到提示,我们可以将保存为当前提示的过去提示保存为:get_rect
函数定义一个矩形,并将其绘制到当前帧上。但在绘制之前,我们将帧保存为下一次迭代的当前帧之前的帧:DNN在这方面做得太过分了。“滑动窗口”是一整套方法,彼此之间最不相关。用于检测的DNN可被视为“滑动窗口”。如果您指的是haar级联,那么您可以使用它们进行检测(但不仅仅限于此)。模板匹配也是“滑动窗口”。所有这些都将比DNN更快。您应该查询操作系统API的“可访问性”以获取文本光标的位置。这是可能的。windows自己的放大镜(win++)使用它们。
import cv2
import numpy as np
BOX_WIDTH = 10
BOX_HEIGHT = 20
def process_img(img):
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
kernel = np.ones((5, 5))
img_canny = cv2.Canny(img_gray, 50, 50)
return img_canny
def get_contour(img):
contours, hierarchies = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
if contours:
return max(contours, key=cv2.contourArea)
def get_line_tip(cnt1, cnt2):
x1, y1, w1, h1 = cv2.boundingRect(cnt1)
if h1 > BOX_HEIGHT / 2:
if np.any(cnt2):
x2, y2, w2, h2 = cv2.boundingRect(cnt2)
if x1 < x2:
return x1, y1
return x1 + w1, y1
def get_rect(x, y):
half_width = BOX_WIDTH // 2
lift_height = BOX_HEIGHT // 6
return (x - half_width, y - lift_height), (x + half_width, y + BOX_HEIGHT - lift_height)
cap = cv2.VideoCapture("screen_record.mkv")
success, img_past = cap.read()
cnt_past = np.array([])
line_tip_past = 0, 0
while True:
success, img_live = cap.read()
if not success:
break
img_live_processed = process_img(img_live)
img_past_processed = process_img(img_past)
img_diff = cv2.bitwise_xor(img_live_processed, img_past_processed)
cnt = get_contour(img_diff)
line_tip = get_line_tip(cnt, cnt_past)
if line_tip:
cnt_past = cnt
line_tip_past = line_tip
else:
line_tip = line_tip_past
rect = get_rect(*line_tip)
img_past = img_live.copy()
cv2.rectangle(img_live, *rect, (0, 0, 255), 2)
cv2.imshow("Cursor", img_live)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
cv2.destroyAllWindows()