VID_20230625_222439
opencv输入测试
-
直接使用 opencv VideoCapture 读取摄像头:
cv::VideoCapture capture;
capture.open(vid);
cv::Mat frame;
double rate = capture.get(cv::CAP_PROP_POS_FRAMES);
int delay = cvRound(1000.000 / rate);
while (1)
{
capture >> frame;
if (frame.empty())
break;
cv::imshow("读取摄像头", frame);
cv::waitKey(30);
}
-
在cmakelist文件加入opencv的库支持:
file(GLOB OPENCV_LIBS "/mnt/usr/lib/arm-linux-gnueabihf/libopencv*.so")
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${OPENCV_LIBS})
-
报错:
[ WARN:0] global ../modules/videoio/src/cap_gstreamer.cpp (480) isPipelinePlaying OpenCV | GStreamer warning: GStreamer: pipeline have not been created
[ WARN:0] global ../modules/videoio/src/cap_v4l.cpp (887) open VIDEOIO(V4L2:/dev/video0): can't open camera by index
-
根据报错信息,这些摄像头设备应该是无法像uvc摄像头那样直接通过 index 打开读取的。
v4l2方式读取
-
使用 v4l2-ctl 抓取:
v4l2-ctl -d /dev/video0 --try-fmt-video=width=1920,height=1080,pixelformat=NV12 --stream-mmap=3 --stream-to=/tmp/test.yuv --stream-count=10 --stream-poll
ffplay -f rawvideo -video_size 1920x1080 -pix_fmt nv12 test.yuv
发现依然是一片花屏绿幕
-
使用 v4l2 命令是可以捕获图像的,猜测 v4l2 方式可以打开摄像头
char videoName[100] = "/dev/video0";
sprintf(videoName, "/dev/video%d", vid);
int fd = open(videoName, O_RDWR);
struct v4l2_capability cap;
ioctl(fd, VIDIOC_QUERYCAP, &cap);
printf("DriverName\t%s\r\nCard Name\t%s\r\nBus info\t%s\r\nDriverVersion\t%u.%u.%u\r\n",
cap.driver, cap.card, cap.bus_info, (cap.version >> 16) & 0XFF, (cap.version >> 8) & 0XFF, (cap.version) & 0xFF);
struct v4l2_fmtdesc fmtdesc;
unsigned int min = 0;
fmtdesc.index = 0;
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
printf("Supportformat:\r\n");
while (ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) != -1)
{
printf("\t%d.%s\r\n", fmtdesc.index + 1, fmtdesc.description);
fmtdesc.index++;
}
struct v4l2_format fmt;
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = 1080;
fmt.fmt.pix.height = 1920;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
fmt.fmt.pix.field = V4L2_FIELD_NONE;
ioctl(fd, VIDIOC_S_FMT, &fmt);
ioctl(fd, VIDIOC_G_FMT, &fmt);
printf("Currentdata format information:\r\n\twidth:%d\r\n\theight:%d\r\n", fmt.fmt.pix.width, fmt.fmt.pix.height);
fmtdesc.index = 1;
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
while (ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) != -1)
{
if (fmtdesc.pixelformat & fmt.fmt.pix.pixelformat)
{
printf("\tformat:%s\n", fmtdesc.description);
break;
}
fmtdesc.index++;
}
struct v4l2_requestbuffers req;
req.count = n_buffers;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
ioctl(fd, VIDIOC_REQBUFS, &req);
buffers = (buffer *)calloc(req.count, sizeof(*buffers));
if (!buffers)
{
fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
for (unsigned int n_buffers = 0; n_buffers < req.count; ++n_buffers)
{
struct v4l2_buffer buf;
memset(&buf, 0, sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = n_buffers;
if (-1 == ioctl(fd, VIDIOC_QUERYBUF, &buf))
exit(-1);
buffers[n_buffers].length = buf.length;
buffers[n_buffers].start =
mmap(
NULL,
buf.length,
PROT_READ | PROT_WRITE,
MAP_SHARED,
fd,
buf.m.offset);
if (MAP_FAILED == buffers[n_buffers].start)
exit(-1);
}
unsigned int i;
enum v4l2_buf_type type;
for (i = 0; i < n_buffers; ++i)
{
struct v4l2_buffer buf;
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
ioctl(fd, VIDIOC_QBUF, &buf);
}
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ioctl(fd, VIDIOC_STREAMON, &type);
cv::VideoWriter Writer("dect_result2.avi", cv::VideoWriter::fourcc('D', 'I', 'V', 'X'), 30, cv::Size(640, 480), true);
while (cv::waitKey(30) != 'q')
{
struct v4l2_buffer buf;
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
ioctl(fd, VIDIOC_DQBUF, &buf);
cv::Mat image(480, 640, CV_8UC2, (unsigned char *)buffers[buf.index].start);
cv::Mat img2;
cv::cvtColor(image, img2, cv::COLOR_YUV2BGR_YUYV);
cv::imshow("current", img2);
ioctl(fd, VIDIOC_QBUF, &buf);
}
Writer.release();
close(fd);
-
但依然失败:
DriverName rkcif
Card Name rkcif
Bus info platform:rkcif_mipi_lvds
DriverVersion 4.19.111
Supportformat:
Currentdata format information:
width:1080
height:1920
库方式读取
-
查询了rv1126 isp相关资料后发现,mipi及isp相关驱动应该是闭源,可能需要签nda的批量用户才能获取,easy-eai也采用.a .so封装,应该是不予开放,因此必须使用 easy-eai 的库驱动:
int ret = 0;
char *pbuf = NULL;
int skip = 0;
pthread_t mTid;
cv::Mat algorithm_image;
pthread_mutex_t img_lock;
cv::Mat image;
#define CAMERA_WIDTH 720
#define CAMERA_HEIGHT 1280
#define IMGRATIO 3
#define IMAGE_SIZE (CAMERA_WIDTH * CAMERA_HEIGHT * IMGRATIO)
ret = rgbcamera_init(CAMERA_WIDTH, CAMERA_HEIGHT, 90);
if (ret)
{
printf("error: %s, %d\n", __func__, __LINE__);
goto exit4;
}
pbuf = NULL;
pbuf = (char *)malloc(IMAGE_SIZE);
if (!pbuf)
{
printf("error: %s, %d\n", __func__, __LINE__);
ret = -1;
goto exit3;
}
skip = 10;
while (skip--)
{
ret = rgbcamera_getframe(pbuf);
if (ret)
{
printf("error: %s, %d\n", __func__, __LINE__);
goto exit2;
}
}
pthread_mutex_init(&img_lock, NULL);
#define SCREEN_WIDTH 720
#define SCREEN_HEIGHT 1280
ret = disp_init(SCREEN_WIDTH, SCREEN_HEIGHT);
if (ret)
{
printf("error: %s, %d\n", __func__, __LINE__);
goto exit1;
}
while (1)
{
pthread_mutex_lock(&img_lock);
ret = rgbcamera_getframe(pbuf);
if (ret)
{
printf("error: %s, %d\n", __func__, __LINE__);
pthread_mutex_unlock(&img_lock);
continue;
}
algorithm_image = cv::Mat(CAMERA_HEIGHT, CAMERA_WIDTH, CV_8UC3, pbuf);
image = algorithm_image.clone();
pthread_mutex_unlock(&img_lock);
disp_commit(image.data, IMAGE_SIZE);
usleep(20 * 1000);
}
exit1:
pthread_mutex_destroy(&img_lock);
exit2:
free(pbuf);
pbuf = NULL;
exit3:
rgbcamera_exit();
exit4:
return ret;
-
cmakelist 文件加入 easy eai 和 rockchip 支持
SET(MYSYSSDKLIB "/mnt/usr/lib")
SET(toolkit_root /home/developer/project/demo/EASY-EAI-Toolkit-C-Solution/easyeai-api)
LINK_DIRECTORIES(${MYSYSSDKLIB})
LINK_DIRECTORIES(${toolkit_root}/common_api/system_opt)
LINK_DIRECTORIES(${toolkit_root}/peripheral_api/camera)
LINK_DIRECTORIES(${toolkit_root}/peripheral_api/display)
INCLUDE_DIRECTORIES(
${toolkit_root}/peripheral_api/camera
${toolkit_root}/peripheral_api/display
)
TARGET_LINK_LIBRARIES(${PROJECT_NAME}
${toolkit_root}/peripheral_api/display/libdisplay.a pthread
${toolkit_root}/peripheral_api/camera/libcamera.a easymedia rga
${toolkit_root}/common_api/system_opt/libsystem_opt.a easymedia rga rkaiq
)
-
其中尤其注意,除了 SDK EASY-EAI-Toolkit-C-Solution 里的libdisplay.a等几个库,还有库里面的 easymedia rga rkaiq;
- easymedia 应该是 easy eai 适配的摄像头驱动库;
- rga rkaiq 是瑞芯微 isp 类的驱动库
- libcamera.a 这些就是 easy eai 适配的摄像头应用库;
- libdisplay.a 是屏幕驱动库,如果使用Qt应该就不需要走这个库。
-
程序:仓库
|