/* * gd13_demo — 斑马线检测演示 (调用 zebra_detect.h) */ #include #include #include #include #include #include #include #include #include #include #include "zebra_detect.h" using namespace cv; using namespace std; static atomic g_running{true}; static void signal_handler(int) { g_running.store(false); } static uint16_t rgb565(uint8_t r, uint8_t g, uint8_t b) { return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); } static void display_on_fb(const Mat &bgr, uint16_t *fb_buf, int scr_w, int scr_h) { Mat display; resize(bgr, display, Size(scr_w, scr_h)); for (int y = 0; y < scr_h; ++y) for (int x = 0; x < scr_w; ++x) { Vec3b px = display.at(y, x); fb_buf[y * scr_w + x] = rgb565(px[2], px[1], px[0]); } } int main(int argc, char *argv[]) { bool no_display = false; for (int i = 1; i < argc; ++i) if (strcmp(argv[i], "--no-display") == 0) no_display = true; signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); VideoCapture cap(0); cap.open(0, CAP_V4L2); if (!cap.isOpened()) cap.open(0); if (!cap.isOpened()) { cerr << "摄像头打开失败" << endl; return 1; } printf("摄像头已打开\n"); int fb_fd = -1; uint16_t *fb_buf = nullptr; int scr_w = 0, scr_h = 0; if (!no_display) { fb_fd = open("/dev/fb0", O_RDWR); if (fb_fd >= 0) { struct fb_var_screeninfo vinfo; ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo); scr_w = vinfo.xres; scr_h = vinfo.yres; size_t fb_size = vinfo.yres_virtual * vinfo.xres_virtual * 2; fb_buf = (uint16_t *)mmap(nullptr, fb_size, PROT_READ|PROT_WRITE, MAP_SHARED, fb_fd, 0); } } Mat frame, result; printf("开始斑马线检测...\n"); while (g_running) { if (!cap.read(frame) || frame.empty()) { usleep(5000); continue; } ZebraResult zr = detect_zebra_crossing(frame); result = frame.clone(); if (zr.detected) { putText(result, "ZEBRA! dist=" + to_string(zr.distance_px) + "px", Point(10, 30), FONT_HERSHEY_SIMPLEX, 0.8, Scalar(0, 0, 255), 2); printf("ZEBRA detected | distance=%d px\n", zr.distance_px); } else { printf("not detected | distance=%d\n", zr.distance_px); } if (!no_display && fb_buf) display_on_fb(result, fb_buf, scr_w, scr_h); } cap.release(); if (fb_buf) munmap(fb_buf, scr_w * scr_h * 2); if (fb_fd >= 0) close(fb_fd); return 0; }