图像信号处理

1.整体框图

(1)所选SOC为瑞芯微RK3566,或者rv1126,图像信号处理为ISP21,Sensor为imx219 或者 ar0144
图像信号处理_第1张图片

2.图像数据流拓扑

图像信号处理_第2张图片
(1)驱动程序有 4 个视频设备:

rkisp1_mainpath:用于检索图像的捕获设备,通常具有更高的分辨率。

rkisp1_selfpath:用于检索图像的捕获设备。

rkisp1_stats:发送统计数据的元数据捕获设备。

rkisp1_params:从用户空间接收参数配置的元数据输出设备。

(2)驱动程序有 3 个子设备:

rkisp1_resizer_mainpath:用于调整主路径捕获设备的帧大小和下采样帧。

rkisp1_resizer_selfpath:用于为自路径捕获设备调整帧大小和下采样帧。

rkisp1_isp:与传感器相连,负责所有的isp操作。

3.图像数据链路层

(1)链路图
图像信号处理_第3张图片
(2)如果mainpath没有开通需要开通(比如rv1126平台没有开通)

图像信号处理_第4张图片

4.根据链路层修改sensor、subdev、isp分辨率

(1)subdev

void setSubdev(int w,int h,const char *node_path)
{
    int subdev_fd = 0;
    subdev_fd = open(node_path, O_RDWR , 0); // set sensor
    if(-1 == subdev_fd)
    {
        ERR("open v4l-subdev3 fail \n");
    }

    struct v4l2_subdev_format subfmt;
    subfmt.pad = 0;
    subfmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
    subfmt.format.width = w;
    subfmt.format.height = h;
    DBG("---%s:set subdev:  w:%d  h:%d \n",__FUNCTION__,w,h);
    if (-1 == ioctl(subdev_fd,VIDIOC_SUBDEV_S_FMT, &subfmt))
    {
             ERR("VIDIOC_SUBDEV_S_FMT");
             exit(EXIT_FAILURE);
    }
    if (-1 == ioctl(subdev_fd,VIDIOC_SUBDEV_G_FMT, &subfmt))
    {
             ERR("VIDIOC_SUBDEV_G_FMT");
             exit(EXIT_FAILURE);
    }

    DBG("---%s:VIDIOC_SUBDEV_G_FMT:  w:%d  h:%d \n",__FUNCTION__,subfmt.format.width,subfmt.format.height);

    close(subdev_fd);
}

(2)sensor

void setSensor(int w,int h,const char *node_path)
{
    int sensor_fd = 0;
    sensor_fd = open(node_path, O_RDWR , 0);
    if(-1 == sensor_fd)
    {
        ERR("open /dev/video0 fail \n");
    }

    struct v4l2_crop video_crop;
    video_crop.c.left = 0;
    video_crop.c.top = 0;
    video_crop.c.width = w;
    video_crop.c.height = h;



    if (-1 == ioctl(sensor_fd,VIDIOC_S_CROP, &video_crop))
    {
        ERR("VIDIOC_S_CROP");
        exit(EXIT_FAILURE);
    }
    if (-1 == ioctl(sensor_fd,VIDIOC_G_CROP, &video_crop))
    {
        ERR("VIDIOC_G_CROP");
        exit(EXIT_FAILURE);
    }
    DBG("---%s:VIDIOC_G_CROP: w:%d  h:%d \n",__FUNCTION__,video_crop.c.width,video_crop.c.height);

    struct v4l2_format fmt;
    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    fmt.fmt.pix.width = w;
    fmt.fmt.pix.height = h;
    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_NV12;//V4L2_PIX_FMT_YUV420

    if (-1 == ioctl(sensor_fd, VIDIOC_S_FMT, &fmt))//set image format
    {
            ERR("VIDIOC_S_FMT");
            exit(EXIT_FAILURE);
    }
    if (-1 == ioctl(sensor_fd, VIDIOC_G_FMT, &fmt))//get image format
    {
            ERR("VIDIOC_G_FMT");
            exit(EXIT_FAILURE);
    }
    DBG("---%s:VIDIOC_G_FMT: w:%d  h:%d \n",__FUNCTION__,fmt.fmt.pix.width,fmt.fmt.pix.height);

    close(sensor_fd);
}

(3)isp

void setIsp(int w,int h,const char *node_path)
{
    int ispdev_fd = 0;
    ispdev_fd = open(node_path, O_RDWR , 0);
    if(-1 == ispdev_fd)
    {
        ERR("open v4l-subdev0 fail \n");
    }

    struct v4l2_subdev_format subfmt;
    subfmt.pad = 0;
    subfmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
    subfmt.format.width = w;
    subfmt.format.height = h;

    struct v4l2_subdev_selection subsel;
    subsel.r.left = 0;
    subsel.r.top = 0;
    subsel.r.width = w;
    subsel.r.height = h;
    subsel.target = V4L2_SEL_TGT_CROP;
    subsel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
    subfmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
    /* change fmt&size for RKISP1_ISP_PAD_SINK */
    subfmt.pad = 0;//RKISP1_ISP_PAD_SINK;
    subsel.pad = 0;//RKISP1_ISP_PAD_SINK;
    if (-1 == ioctl(ispdev_fd,VIDIOC_SUBDEV_S_FMT, &subfmt))
    {
            ERR("VIDIOC_SUBDEV_S_FMT");
            exit(EXIT_FAILURE);
    }
    if (-1 == ioctl(ispdev_fd,VIDIOC_SUBDEV_S_SELECTION, &subsel))
    {
            ERR("VIDIOC_SUBDEV_S_SELECTION");
            exit(EXIT_FAILURE);
    }

    subfmt.pad = 2;//RKISP1_ISP_PAD_SOURCE_PATH;
    subsel.pad = 2;//RKISP1_ISP_PAD_SOURCE_PATH;
    if (-1 == ioctl(ispdev_fd,VIDIOC_SUBDEV_S_FMT, &subfmt))
    {
            ERR("VIDIOC_SUBDEV_S_FMT");
            exit(EXIT_FAILURE);
    }
    if (-1 == ioctl(ispdev_fd,VIDIOC_SUBDEV_S_SELECTION, &subsel))
    {
            ERR("VIDIOC_SUBDEV_S_SELECTION");
            exit(EXIT_FAILURE);
    }

    close(ispdev_fd);

}

(4)测试


int main(void)
{

    int w = 1280;
    int h = 800;

    printf("Please inpu W and h:\n");
    scanf("%d %d",&w,&h);
    while((getchar())!='\n');
    setSubdev(w,h,"/dev/v4l-subdev3"); //source pad0
    setIsp(w,h,"/dev/v4l-subdev0"); //Sink pad0, source pad2
    setSensor(w,h,"/dev/video0");
    return 0;
}

你可能感兴趣的:(Linux,ARM,linux,isp,图像处理)