/* * screenshot_demo — 摄像头截图保存 * ====================================== * 每次运行截一张图, 保存到 ./screenshot/image_N.jpg * 用法: * ./screenshot_demo 截一张图 + LCD 显示 * ./screenshot_demo --no-display 无 LCD */ #include #include #include #include #include #include #include #include #include #include using namespace cv; using namespace std; static uint16_t rgb565(uint8_t r, uint8_t g, uint8_t b) { return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); } 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; // ---- 创建目录 ---- mkdir("./screenshot", 0755); // ---- 摄像头 ---- VideoCapture cap; cap.open(0, CAP_V4L2); if (!cap.isOpened()) cap.open(0); if (!cap.isOpened()) { cerr << "无法打开摄像头" << endl; return 1; } cap.set(CAP_PROP_FRAME_WIDTH, 640); cap.set(CAP_PROP_FRAME_HEIGHT, 480); cap.set(CAP_PROP_FOURCC, VideoWriter::fourcc('M', 'J', 'P', 'G')); printf("摄像头: %dx%d\n", (int)cap.get(CAP_PROP_FRAME_WIDTH), (int)cap.get(CAP_PROP_FRAME_HEIGHT)); // ---- 丢弃前几帧 (曝光稳定) ---- Mat frame; for (int i = 0; i < 10; ++i) cap.read(frame); usleep(100000); // ---- 截图 ---- if (!cap.read(frame) || frame.empty()) { cerr << "截图失败" << endl; cap.release(); return 1; } // 自增文件名 int idx = 0; char fname[64]; struct stat st; do { snprintf(fname, sizeof(fname), "./screenshot/image_%05d.jpg", ++idx); } while (stat(fname, &st) == 0); imwrite(fname, frame); printf("截图: %s (%dx%d)\n", fname, frame.cols, frame.rows); // ---- LCD 显示 ---- if (!no_display) { int fb_fd = open("/dev/fb0", O_RDWR); if (fb_fd >= 0) { struct fb_var_screeninfo vinfo; ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo); int scr_w = vinfo.xres, scr_h = vinfo.yres; size_t fb_size = vinfo.yres_virtual * vinfo.xres_virtual * 2; uint16_t *fb_buf = (uint16_t *)mmap(nullptr, fb_size, PROT_READ|PROT_WRITE, MAP_SHARED, fb_fd, 0); Mat disp; resize(frame, disp, Size(scr_w, scr_h)); rectangle(disp, Point(0, 0), Point(disp.cols, disp.rows), Scalar(0, 255, 255), 3); for (int y = 0; y < scr_h; ++y) for (int x = 0; x < scr_w; ++x) { Vec3b px = disp.at(y, x); fb_buf[y * scr_w + x] = rgb565(px[2], px[1], px[0]); } sleep(1); munmap(fb_buf, fb_size); close(fb_fd); } } cap.release(); return 0; }