imx8mini openCV mipi摄像头报错: VIDIOC_QUERYCTRL: Inappropriate ioctl for device

imx8mini openCV摄像头报错: VIDIOC_QUERYCTRL: Inappropriate ioctl for device

      • 简单介绍:
      • 首先来看python 源码
      • 然后是openCV的源码(这是C++)
      • 解决办法:

简单介绍:

摄像头为mipi 摄像头 设备为/dev/video0 ;有python 和openCV 获取摄像头图像都是一种报错,但是用USB摄像头根本没有问题,找了很久,终于解决问题。问题在于驱动中没实现。
报错信息为:VIDIOC_QUERYCTRL: Inappropriate ioctl for device

首先来看python 源码

#!/usr/bin/env python

# Python 2/3 compatibility
from __future__ import print_function

import cv2 as cv

def decode_fourcc(v):
    v = int(v)
    return "".join([chr((v >> 8 * i) & 0xFF) for i in range(4)])

font = cv.FONT_HERSHEY_SIMPLEX
color = (0, 255, 0)

cap = cv.VideoCapture(0)
cap.set(cv.CAP_PROP_AUTOFOCUS, False)  # Known bug: https://github.com/opencv/opencv/pull/5474

cv.namedWindow("Video")

convert_rgb = True
fps = int(cap.get(cv.CAP_PROP_FPS))
focus = int(min(cap.get(cv.CAP_PROP_FOCUS) * 100, 2**31-1))  # ceil focus to C_LONG as Python3 int can go to +inf

#cv.createTrackbar("FPS", "Video", fps, 30, lambda v: cap.set(cv.CAP_PROP_FPS, v))
#cv.createTrackbar("Focus", "Video", focus, 100, lambda v: cap.set(cv.CAP_PROP_FOCUS, v / 100))

while True:
    status, img = cap.read()

    fourcc = decode_fourcc(cap.get(cv.CAP_PROP_FOURCC))

    fps = cap.get(cv.CAP_PROP_FPS)

    if not bool(cap.get(cv.CAP_PROP_CONVERT_RGB)):
        if fourcc == "MJPG":
            img = cv.imdecode(img, cv.IMREAD_GRAYSCALE)
        elif fourcc == "YUYV":
            img = cv.cvtColor(img, cv.COLOR_YUV2GRAY_YUYV)
        else:
            print("unsupported format")
            break

    cv.putText(img, "Mode: {}".format(fourcc), (15, 40), font, 1.0, color)
    cv.putText(img, "FPS: {}".format(fps), (15, 80), font, 1.0, color)
    cv.imshow("Video", img)

    k = cv.waitKey(1)

    if k == 27:
        break
    elif k == ord('g'):
        convert_rgb = not convert_rgb
        cap.set(cv.CAP_PROP_CONVERT_RGB, convert_rgb)

然后是openCV的源码(这是C++)

#include 
#include 

using namespace std;
using namespace cv; 

#include"cv.h"
#include"highgui.h"
#include"iostream"
using namespace std;
 
int main(int argc,char* argv[])
{
	CvCapture* cap;
	cap=cvCaptureFromCAM(0);
	if(!cap)
	{
		cout<<"create camera capture error"<<endl;
		return -1;
	}
	cvNamedWindow("img",1);
	IplImage* img;
	cvWaitKey(2);
	while(1)
	{
		img=cvQueryFrame(cap);
		if(!img)
			break;
		cvShowImage("img",img);
		cvWaitKey(3);
	}
	cvReleaseCapture(&cap);
	cvDestroyAllWindows();
	cvReleaseImage(&img);
	return 0;
}

都是运行到这种打开设备video0 就报错 如果是usb摄像头就没问题

cap = cv.VideoCapture(0)
cap=cvCaptureFromCAM(0);

解决办法:

找到内核相应位置去配置实现加配置,注意光实现是不行的,下面是我修改的地方:

#if 1 //add by jinzi
static struct v4l2_queryctrl ov5640_qctrl[] = {
	
	{
		.id		= V4L2_CID_TEST_PATTERN,
		.type		= V4L2_CTRL_TYPE_INTEGER,
		.name		= "Test pattern",
		.minimum	= 0,
		.maximum	= 3,
		.step		= 1,
		.default_value	= 3,
		.flags		= 0,
	},
	{		
		.id		= V4L2_CID_FOCUS_TRIGGER,
		.type		= V4L2_CTRL_TYPE_INTEGER,
		.name		= "Trigger focus",
		.minimum	= 0,
		.maximum	= 1,
		.step		= 1,
		.default_value	= 0,
		.flags		= 0,
	}
};

static int mx6s_vidioc_queryctrl(struct file *file, void *priv,
			struct v4l2_queryctrl *qc)
{
	int i;
	/* Fill in min, max, step and default value for these controls. */
	switch (qc->id) {
	case V4L2_CID_BRIGHTNESS:
		return v4l2_ctrl_query_fill(qc, -64, 64, 1, 0);
	case V4L2_CID_CONTRAST:
		return v4l2_ctrl_query_fill(qc, -12, 12, 1, 0);
	case V4L2_CID_SATURATION:
		return v4l2_ctrl_query_fill(qc, -48, 48, 1, 0);
	case V4L2_CID_HUE:
		return v4l2_ctrl_query_fill(qc, -180, 150, 30, 0);
	case V4L2_CID_VFLIP:
	case V4L2_CID_HFLIP:
		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
	case V4L2_CID_COLORFX:
		return v4l2_ctrl_query_fill(qc, V4L2_COLORFX_NONE, V4L2_COLORFX_VIVID, 1, V4L2_COLORFX_NONE);
	case V4L2_CID_AUTO_WHITE_BALANCE:
		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
	case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
		return v4l2_ctrl_query_fill(qc, 3000, 6000, 1000, 3000);
	case V4L2_CID_TEST_PATTERN:
		printk("ioctl_queryctrl: V4L2_CID_TEST_PATTERN \n");
	case V4L2_CID_FOCUS_TRIGGER:
		for(i = 0; i < ARRAY_SIZE(ov5640_qctrl); i++) {
			if(qc->id == ov5640_qctrl[i].id) {
				memcpy(qc, &(ov5640_qctrl[i]), sizeof(*qc));
				return 0;
			}
		}
	case V4L2_CID_AUTO_FOCUS_START:
		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
	case V4L2_CID_AUTO_FOCUS_STOP:
		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
	case V4L2_CID_FOCUS_ABSOLUTE:
		return v4l2_ctrl_query_fill(qc, 0, 255, 1, 0);

	case V4L2_CID_EXPOSURE:
		return v4l2_ctrl_query_fill(qc, 0, 0xFFFFF, 1, 0);
	case V4L2_CID_AUTOGAIN:
		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); // 1 for AGC/AEC
	case V4L2_CID_GAIN:
		return v4l2_ctrl_query_fill(qc, 0, 0xFFFF, 1, 0);

	}
	return -EINVAL;
	//printk("[%s] nothing to do\n",__func__);
	return 0;
}
#endif

在static const struct v4l2_ioctl_ops mx6s_csi_ioctl_ops 最后边添加
.vidioc_queryctrl = mx6s_vidioc_queryctrl,

	/* add by jinzi */
	.vidioc_queryctrl     = mx6s_vidioc_queryctrl,

还有要添加相应的宏,不然编译报错

#if 1 //add by jinzi
#define V4L2_CID_DRIVER_BASE            (V4L2_CID_USER_BASE | 0x1001)
//#define V4L2_CID_TEST_PATTERN           (V4L2_CID_DRIVER_BASE + 0)
#define V4L2_CID_FOCUS_TRIGGER          (V4L2_CID_DRIVER_BASE + 1)
#endif

如果不知道在什么文件修改,那就参考我给的内核驱动文件吧,里面是我修改好的。

下载地址:
https://download.csdn.net/download/qichongjin/12393581

你可能感兴趣的:(嵌入式linux驱动,摄像头,python,opencv,kernel,ubuntu)