初级会员 
  
	- 积分
 - 149
 
        - 金钱
 - 149 
 
       - 注册时间
 - 2022-4-29
 
      - 在线时间
 - 44 小时
 
 
 
 | 
 
1金钱 
 本帖最后由 爱跑步的雯雯 于 2022-11-1 22:18 编辑  
 
我在qt上用v4l2驱动ov5640的相机在lcd屏上显示的时候,会有紫色的横条闪烁出现,效果视频请见附件 
除此以外的显示采集图像没有问题,我的相机加了滤波片所以会显示偏黄色因为闪烁的原因,后来通过二值化处理后显示发现还是有很多噪声的,照片如下。 
希望知道的或者有想法的大佬、兄弟可以帮忙提提建议,多多指教,多谢。 
 
我的摄像头驱动函数如下: 
//线程函数 run 
void camerathread::run() 
{ 
    static struct v4l2_buffer buf; 
    flag = false; 
    struct v4l2_format fmt = {}; 
    struct v4l2_requestbuffers req_bufs = {}; 
    enum v4l2_buf_type type; 
 
    /* 打开摄像头设备 */ 
    video_fd = open(VIDEO_DEV, O_RDWR); 
    if (0 > video_fd) { 
            printf("ERROR: failed to open video device %s\n", VIDEO_DEV); 
            exit(-1); 
    } 
 
    /* 设置摄像头格式 */ 
    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
    fmt.fmt.pix.width = 800; 
    fmt.fmt.pix.height = 480; 
    fmt.fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; 
    fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; 
    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24; 
 
    if (0 > ioctl(video_fd, VIDIOC_S_FMT, &fmt)) { 
            printf("ERROR: failed to VIDIOC_S_FMT\n"); 
            exit(-1); 
    } 
 
    /* 请求buffer */ 
    req_bufs.count = VIDEO_BUFFER_COUNT; 
    req_bufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
    req_bufs.memory = V4L2_MEMORY_MMAP; 
 
    if (0 > ioctl(video_fd, VIDIOC_REQBUFS, &req_bufs)) { 
            perror("ERROR: failed to VIDIOC_REQBUFS\n"); 
            exit(-1); 
    } 
 
    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
    buf.memory = V4L2_MEMORY_MMAP; 
    for (n_buf = 0; n_buf < VIDEO_BUFFER_COUNT; n_buf++) { 
 
            buf.index = n_buf; 
            if (0 > ioctl(video_fd, VIDIOC_QUERYBUF, &buf)) { 
                    perror("ERROR: failed to VIDIOC_QUERYBUF\n"); 
                    exit(-1); 
            } 
 
            //映射 
            bufs_info[n_buf].length = buf.length; 
            bufs_info[n_buf].start = (char *)mmap(NULL, buf.length, 
                                    PROT_READ | PROT_WRITE, MAP_SHARED, 
                                    video_fd, buf.m.offset); 
            if (MAP_FAILED == bufs_info[n_buf].start) { 
                    printf("ERROR: failed to mmap video buffer, size 0x%x\n", buf.length); 
                    exit(-1); 
            } 
    } 
 
    /* buffer入队*/ 
    for (n_buf = 0; n_buf < VIDEO_BUFFER_COUNT; n_buf++) { 
 
            buf.index = n_buf; 
            if (0 > ioctl(video_fd, VIDIOC_QBUF, &buf)) { 
                    perror("ERROR: failed to VIDIOC_QBUF\n"); 
                    exit(-1); 
            }printf("%d\n",n_buf); 
    } 
 
//申请临时缓冲区 
current.start = (char *)malloc(buf.length); 
if(current.start == NULL){ 
    perror("malloc"); 
    exit(-1); 
} 
 
usleep(1); 
    /* 开始采集 */ 
    type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
    if (0 > ioctl(video_fd, VIDIOC_STREAMON, &type)) { 
            perror("ERROR: failed to VIDIOC_STREAMON\n"); 
            exit(-1); 
    }qDebug()<<"VIDIOC_STREAMON"<<endl; 
 
   for(;;) { 
msleep(15); 
            if (0 > ioctl(video_fd, VIDIOC_DQBUF, &buf)) { 
                perror("ERROR: failed to VIDIOC_DQBUF\n"); 
                exit(-1); 
            } 
 
            memcpy(current.start, (unsigned char *)bufs_info[buf.index].start, buf.length); 
            printf("base = %x\nbufs_info[n_buf].start = %x\nscreensize = %d\n",current.start,bufs_info[buf.index].start,buf.length); 
 
            if (0 > ioctl(video_fd, VIDIOC_QBUF, &buf)) { 
                perror("ERROR: failed to VIDIOC_QBUF\n"); 
                exit(-1); 
            } 
 
            //通过信号把图像数据发送出去 
            QImage image = QImage((unsigned char *)current.start,800,480,QImage::Format_RGB888); 
            emit send_image(image); 
            //延时 
            msleep(10); 
            if(flag) 
                break; 
    } 
} 
 
 
 
 
 |   
 
 
最佳答案
查看完整内容[请看2#楼] 
问题解决了,之前是按照一个ov5640手册里的配置对着正点原子的驱动改的,之前是45.6M的时钟,显示的时候会出现闪烁啥的,后来直接用的正点原子的驱动,128M的pclk,改了时序控制、50、60Mhz的条纹和曝光等等,就正常亮了。
额,虽然解决了,但是不知道真正的问题在哪,之前也改了时钟频率,倍频,曝光什么的都没有效果,最大的可能是时序控制那边,希望有思路的大佬可以指教哦
硬件 真的 玄学!!!
最后,原子永远的神 
 
 
 
 
 
 
 |