|
从淘宝上买了个无驱USB数码显微镜(应该跟摄像头一样的用法),连接到windows 7上,分辨率大概为640x480,截图分辨率达到1280x1024。
从网上找了些代码,调试运行后,发现几个问题不知如何解决:
1,设备的像素分辨率过低,只有160x120,为win7上的1/4,不知道该如何设置提高视频分辨率?
2,转换YUVY为BITMAP后,像素分辨率也只有160x120,不知该如何提高截图像素分辨率?
附1:初始化代码:
- static int fd = -1;
- static struct v4l2_capability cap;
- struct v4l2_fmtdesc fmtdesc;
- struct v4l2_format fmt, fmtack;
- struct v4l2_streamparm setfps;
- struct v4l2_requestbuffers req;
- struct v4l2_buffer buf;
- enum v4l2_buf_type type;
- unsigned char frame_buffer[IMAGEWIDTH * IMAGEHEIGHT * 3];
- struct buffer
- {
- void* start;
- unsigned int length;
- } *buffers;
-
- int enum_frame_intervals( int dev, __u32 pixfmt, __u32 width, __u32 height )
- {
- int ret;
- struct v4l2_frmivalenum fival;
- memset(&fival, 0, sizeof(fival));
- fival.index = 0;
- fival.pixel_format = pixfmt;
- fival.width = width;
- fival.height = height;
- printf("\tTime interval between frame: ");
- while ( (ret = ioctl(dev, VIDIOC_ENUM_FRAMEINTERVALS, &fival)) == 0 )
- {
- if (fival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
- printf("%u/%u, ",
- fival.discrete.numerator, fival.discrete.denominator);
- } else if (fival.type == V4L2_FRMIVAL_TYPE_CONTINUOUS) {
- printf("{min { %u/%u } .. max { %u/%u } }, ",
- fival.stepwise.min.numerator, fival.stepwise.min.numerator,
- fival.stepwise.max.denominator, fival.stepwise.max.denominator);
- break;
- } else if (fival.type == V4L2_FRMIVAL_TYPE_STEPWISE) {
- printf("{min { %u/%u } .. max { %u/%u } / "
- "stepsize { %u/%u } }, ",
- fival.stepwise.min.numerator, fival.stepwise.min.denominator,
- fival.stepwise.max.numerator, fival.stepwise.max.denominator,
- fival.stepwise.step.numerator, fival.stepwise.step.denominator);
- break;
- }
- fival.index++;
- }
- printf("\n");
- if ( ret != 0 && errno != EINVAL ) {
- perror("ERROR enumerating frame intervals");
- return errno;
- }
- return 0;
- }
- static int enum_frame_sizes(int dev, __u32 pixfmt)
- {
- int ret;
- struct v4l2_frmsizeenum fsize;
- memset(&fsize, 0, sizeof(fsize));
- fsize.index = 0;
- fsize.pixel_format = pixfmt;
- while ( (ret = ioctl(dev, VIDIOC_ENUM_FRAMESIZES, &fsize)) == 0 )
- {
- if (fsize.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
- printf("{ discrete: width = %u, height = %u }\n",
- fsize.discrete.width, fsize.discrete.height);
- ret = enum_frame_intervals(dev, pixfmt,
- fsize.discrete.width, fsize.discrete.height);
- if (ret != 0)
- printf(" Unable to enumerate frame sizes.\n");
- } else if (fsize.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) {
- printf("{ continuous: min { width = %u, height = %u } .. "
- "max { width = %u, height = %u } }\n",
- fsize.stepwise.min_width, fsize.stepwise.min_height,
- fsize.stepwise.max_width, fsize.stepwise.max_height);
- printf(" Refusing to enumerate frame intervals.\n");
- break;
- } else if (fsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
- printf("{ stepwise: min { width = %u, height = %u } .. "
- "max { width = %u, height = %u } / "
- "stepsize { width = %u, height = %u } }\n",
- fsize.stepwise.min_width, fsize.stepwise.min_height,
- fsize.stepwise.max_width, fsize.stepwise.max_height,
- fsize.stepwise.step_width, fsize.stepwise.step_height);
- printf(" Refusing to enumerate frame intervals.\n");
- break;
- }
- fsize.index++;
- }
- if ( ret != 0 && errno != EINVAL ) {
- perror("ERROR enumerating frame sizes");
- return errno;
- }
- return 0;
- }
- static void video_list_formats( int dev )
- {
- struct v4l2_fmtdesc fmt;
- int ret;
- memset(&fmt, 0, sizeof(fmt));
- fmt.index = 0;
- fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- while ( (ret = ioctl(dev, VIDIOC_ENUM_FMT, &fmt)) == 0 )
- {
- printf("{ pixelformat = '%c%c%c%c', description = '%s' }\n",
- fmt.pixelformat & 0xFF, (fmt.pixelformat >> 8) & 0xFF,
- (fmt.pixelformat >> 16) & 0xFF, (fmt.pixelformat >> 24) & 0xFF,
- fmt.description);
- ret = enum_frame_sizes(dev, fmt.pixelformat);
- if ( ret != 0 )
- printf("Unable to enumerate frame sizes.\n");
- fmt.index++;
- }
- if ( errno != EINVAL ) {
- perror("ERROR enumerating frame formats");
- }
- }
- int init_v4l2(void)
- {
- //opendev
- if ( (fd = open(FILE_VIDEO, O_RDWR)) == -1 )
- {
- printf("Error opening V4L interface\n");
- return FALSE;
- }
- //query cap
- if ( ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1 )
- {
- printf("Error opening device %s: unable to query device.\n", FILE_VIDEO);
- return FALSE;
- }
- else
- {
- printf("driver:\t\t%s\n", cap.driver);
- printf("card:\t\t%s\n", cap.card);
- printf("bus_info:\t%s\n", cap.bus_info);
- printf("version:\t%d\n", cap.version);
- printf("capabilities:\t%x\n", cap.capabilities);
- if ( (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == V4L2_CAP_VIDEO_CAPTURE )
- {
- printf("Device %s: supports capture.\n", FILE_VIDEO);
- }
- if ( (cap.capabilities & V4L2_CAP_STREAMING) == V4L2_CAP_STREAMING )
- {
- printf("Device %s: supports streaming.\n", FILE_VIDEO);
- }
- }
- //emu all support fmt
- #if 0
- fmtdesc.index = 0;
- fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- printf("Support format:\n");
- while ( ioctl(fd,VIDIOC_ENUM_FMT, &fmtdesc) != -1 )
- {
- printf("\t%d.%s\n", fmtdesc.index+1, fmtdesc.description);
- fmtdesc.index++;
- }
- #else
- video_list_formats(fd);
- #endif
- //set fmt
- fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
- fmt.fmt.pix.height = IMAGEHEIGHT;
- fmt.fmt.pix.width = IMAGEWIDTH;
- fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
-
- if ( ioctl(fd, VIDIOC_S_FMT, &fmt) == -1 )
- {
- printf("Unable to set format\n");
- return FALSE;
- }
-
- if ( ioctl(fd, VIDIOC_G_FMT, &fmt) == -1 )
- {
- printf("Unable to get format\n");
- return FALSE;
- }
-
- {
- printf("fmt.type:\t\t%d\n", fmt.type);
- printf("pix.pixelformat:\t%c%c%c%c\n",
- fmt.fmt.pix.pixelformat & 0xFF,
- (fmt.fmt.pix.pixelformat >> 8) & 0xFF,(fmt.fmt.pix.pixelformat >> 16) & 0xFF,
- (fmt.fmt.pix.pixelformat >> 24) & 0xFF);
- printf("pix.height:\t\t%d\n", fmt.fmt.pix.height);
- printf("pix.width:\t\t%d\n", fmt.fmt.pix.width);
- printf("pix.field:\t\t%d\n", fmt.fmt.pix.field);
- }
- //set fps
- setfps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- setfps.parm.capture.timeperframe.numerator = 10;
- setfps.parm.capture.timeperframe.denominator = 10;
-
- printf("init %s \t[OK]\n", FILE_VIDEO);
- return TRUE;
- }
复制代码
附2:采集及转换BITMAP代码:
- int v4l2_grab(void)
- {
- unsigned int n_buffers;
-
- //request for 4 buffers
- req.count = 4;
- req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- req.memory = V4L2_MEMORY_MMAP;
- if ( ioctl(fd, VIDIOC_REQBUFS, &req) == -1 ) {
- printf("request for buffers error\n");
- }
- //mmap for buffers
- buffers = malloc(req.count * sizeof(*buffers));
- if ( !buffers ) {
- printf ("Out of memory\n");
- return FALSE;
- }
-
- for ( n_buffers = 0; n_buffers < req.count; n_buffers++ )
- {
- buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- buf.memory = V4L2_MEMORY_MMAP;
- buf.index = n_buffers;
-
- //query buffers
- if ( ioctl(fd, VIDIOC_QUERYBUF, &buf) == -1 ) {
- printf("query buffer error\n");
- return FALSE;
- }
- buffers[n_buffers].length = buf.length;
-
- // map
- buffers[n_buffers].start = mmap(NULL, buf.length, PROT_READ |PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
- if ( buffers[n_buffers].start == MAP_FAILED ) {
- printf("buffer map error\n");
- return FALSE;
- }
- }
-
- //queue
- for ( n_buffers = 0; n_buffers < req.count; n_buffers++ )
- {
- buf.index = n_buffers;
- ioctl(fd, VIDIOC_QBUF, &buf);
- }
-
- type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- ioctl(fd, VIDIOC_STREAMON, &type);
-
- ioctl(fd, VIDIOC_DQBUF, &buf);
- printf("grab yuyv OK\n");
- return TRUE;
- }
- int yuyv_2_rgb888(void)
- {
- int i, j;
- unsigned char y1, y2, u, v;
- int r1, g1, b1, r2, g2, b2;
- char* pointer;
-
- pointer = buffers[0].start;
-
- for ( i = 0; i < IMAGEHEIGHT; i++ )
- {
- int wid = IMAGEWIDTH >> 1;
- for ( j = 0; j < wid; j++ )
- {
- y1 = *(pointer + (i*wid+j)*4);
- u = *(pointer + (i*wid+j)*4 + 1);
- y2 = *(pointer + (i*wid+j)*4 + 2);
- v = *(pointer + (i*wid+j)*4 + 3);
-
- r1 = y1 + 1.042 * (v-128);
- g1 = y1 - 0.34414 * (u-128) - 0.71414*(v-128);
- b1 = y1 + 1.772 * (u-128);
-
- r2 = y2 + 1.042*(v-128);
- g2 = y2 - 0.34414*(u-128) - 0.71414*(v-128);
- b2 = y2 + 1.772*(u-128);
-
- if( r1 > 255 ) r1 = 255;
- else if( r1 < 0 ) r1 = 0;
-
- if ( b1 > 255 ) b1 = 255;
- else if( b1 < 0 ) b1 = 0;
-
- if( g1 > 255 ) g1 = 255;
- else if( g1 < 0 ) g1 = 0;
-
- if ( r2 > 255 ) r2 = 255;
- else if( r2 < 0 ) r2 = 0;
-
- if( b2 > 255 ) b2 = 255;
- else if( b2 < 0 ) b2 = 0;
-
- if ( g2 > 255 ) g2 = 255;
- else if( g2 < 0 ) g2 = 0;
-
- *(frame_buffer + ((IMAGEHEIGHT-1-i)*wid+j)*6) = (unsigned char)b1;
- *(frame_buffer + ((IMAGEHEIGHT-1-i)*wid+j)*6 + 1) = (unsigned char)g1;
- *(frame_buffer + ((IMAGEHEIGHT-1-i)*wid+j)*6 + 2) = (unsigned char)r1;
- *(frame_buffer + ((IMAGEHEIGHT-1-i)*wid+j)*6 + 3) = (unsigned char)b2;
- *(frame_buffer + ((IMAGEHEIGHT-1-i)*wid+j)*6 + 4) = (unsigned char)g2;
- *(frame_buffer + ((IMAGEHEIGHT-1-i)*wid+j)*6 + 5) = (unsigned char)r2;
- }
- }
-
- printf("change to RGB OK \n");
- return 0;
- }
复制代码
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注册
×
|