简单的基于opencv实现的KCF框选跟踪
让chatgpt写了一个可以实时重新进行框选的kcf框选跟踪,但是chatgpt直接写的有点小问题,我小改了下之后可以跑成了,就是kcf_demo_1.py。
通过python3 kcf_demo_1.py可以运行起来,按"s"键会弹出一个窗口让你框选,框选完成敲回车可以开始跟踪,想重新框选的时候就再按一下键盘"s",这个时候画面会暂停,在暂停的画面上鼠标点击框选,框选完敲回车,就可以跟踪新框选的物体了。注意按键盘"s"之后就不要移动摄像头了,直到框选完,敲完回车后再移动摄像头,因为框选的时候是画面静止的,是按键盘"s"时截图的那时的图像,来框选,如果框选的时候摄像头图像移动过大,可能导致敲回车的时候开始跟踪新的摄像头帧已经没有那个框选的物体了或者距离大了,导致没法跟了或者跟踪失败,但是我测了一次,框选的时候摄像头移动,开始跟踪后显示跟踪失败,但是我摄像头移动回去,又自动识别到并开始跟踪了,看来鲁棒性也还是有一点的,之前框选的信息应该是存着的,就算中途丢了,后面摄像头图像帧重新检测到还是能继续跟的。
现在就喜欢自己能写这种功能的感觉,就像T265定点和二维码降落一样。特别是原本复杂用别人代码实现的功能,现在能自己写,而且相对简单的代码就实现了。
https://gitee.com/maxibooksiyi/xianfei_-z-9-b_pod_test/blob/xianfei-ros2/kcf_demo/kcf_demo_1.py
import cv2
def main():
# 打开USB摄像头
cap = cv2.VideoCapture(0)
width = 640
height = 480
cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
# 初始化跟踪器和初始目标框
bbox = None
#tracker = cv2.TrackerKCF_create()
# 标记是否需要重新框选目标
selecting_object = False
while True:
# 读取当前帧图像
ret, frame = cap.read()
if not ret:
break
# 在需要时重新框选目标
if selecting_object:
tracker = cv2.TrackerKCF_create()
bbox = None
bbox = cv2.selectROI(frame, False)
tracker.init(frame, bbox)
selecting_object = False
# 更新跟踪器,获取跟踪结果
if bbox is not None:
success, bbox = tracker.update(frame)
# 绘制跟踪框
if success:
# 目标成功跟踪
x, y, w, h = [int(x) for x in bbox]
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
else:
# 跟踪失败
cv2.putText(frame, "Tracking failure detected", (100, 80),
cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2)
# 显示当前帧
cv2.imshow("KCF Tracking", frame)
# 监听键盘事件
key = cv2.waitKey(1)
if key == ord('s'):
# 按下's'键重新框选目标
selecting_object = True
#bbox = None
elif key == 27:
# 按下ESC键退出循环
break
# 释放资源
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
对应的cpp版本代码
让chatgpt把kcf_demo_1.py改为C++的,而且给出编译命令,改完放到kcf_demo_1.cpp里面,g++ -o kcf_demo_1 kcf_demo_1.cpp pkg-config --cflags --libs opencv
命令编译通过,运行OK,而且发现比kcf_demo_1.py好的一点就是按下按键"s"后重新进行框选时,不像kcf_demo_1.py是在一个另一个弹出的窗口框选,就是直接在原来的窗口框选,框选完敲回车也是在原来的窗口继续跟踪。
是基于opencv3.4.1编译的
g++ -o kcf_demo_1 kcf_demo_1.cpp `pkg-config --cflags --libs opencv`
./kcf_demo_1
https://gitee.com/maxibooksiyi/xianfei_-z-9-b_pod_test/blob/xianfei-ros2/kcf_demo/kcf_demo_1.cpp
#include <opencv2/opencv.hpp>
#include <opencv2/tracking.hpp>
int main() {
// 打开USB摄像头
cv::VideoCapture cap(0);
// 初始化跟踪器和初始目标框
cv::Rect2d bbox;
cv::Ptr<cv::Tracker> tracker;
// 标记是否需要重新框选目标
bool selecting_object = false;
while (true) {
// 读取当前帧图像
cv::Mat frame;
cap >> frame;
if (frame.empty()) {
break;
}
// 在需要时重新框选目标
if (selecting_object) {
tracker = cv::TrackerKCF::create();
bbox = cv::selectROI("KCF Tracking", frame, false);
tracker->init(frame, bbox);
selecting_object = false;
}
// 更新跟踪器,获取跟踪结果
if (!bbox.empty()) {
bool success = tracker->update(frame, bbox);
// 绘制跟踪框
if (success) {
// 目标成功跟踪
cv::rectangle(frame, bbox, cv::Scalar(0, 255, 0), 2);
} else {
// 跟踪失败
cv::putText(frame, "Tracking failure detected", cv::Point(100, 80),
cv::FONT_HERSHEY_SIMPLEX, 0.75, cv::Scalar(0, 0, 255), 2);
}
}
// 显示当前帧
cv::imshow("KCF Tracking", frame);
// 监听键盘事件
int key = cv::waitKey(1);
if (key == 's') {
// 按下's'键重新框选目标
selecting_object = true;
} else if (key == 27) {
// 按下ESC键退出循环
break;
}
}
// 释放资源
cap.release();
cv::destroyAllWindows();
return 0;
}
基于opencv实现先飞吊舱的KCF框选跟踪 20231110