之前用的好好解析YUV,MJPEG,换了个核心板就不好使了,opencv6>>>opencvMat,cvMat,IplImage的类型转换也不好使了。
//old version
#include "camera_thread.h"
#include <QByteArray>
#include <QImageReader>
#include <QBuffer>
#include <QImage>
#include <QDebug>
#include <QMutex>
#include <ctime>
#include <QString>
#include <QTimer>
#include <utils.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <stdbool.h>
#include <unistd.h>
#include <linux/videodev2.h>
#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
//#include "opencv2/core/types_c.h"
#include "device.h"
#include "qtimer.h"
#include "camera2.h"
#include "numeric"
int init_v4l2(void);
int v4l2_grab(void);
#define IMAGEWIDTH 640
#define IMAGEHEIGHT 480
#define FILE_VIDEO1 "/dev/video10"
#define TRUE 1
#define FALSE 0
char *deviceid;
using namespace cv;
QImageReader reader;
video_thread::video_thread():QThread()
{
quit_flag = false;
}
video_thread::~video_thread()
{
this->quit();
quit_flag = true;
show_picture_flag = false;
this->wait();
}
void video_thread::run()
{
int close_ret = 0;
if(device_video==1){
deviceid= "/dev/video0";
}else{
deviceid= "/dev/video2";
}
if(init_v4l2() == FALSE){
quit_flag = true;
exit(1);
}
if(v4l2_grab() == FALSE){
quit_flag = true;
exit(2);
}
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
isopen = true;
IplImage* img;
IplImage* img1;
CvMat cvmat;
double t;
QImage *qmg;
while(!quit_flag)
{
msleep(1);
// not show picture, continue next loop.
if ( !show_picture_flag )
continue;
t = (double)cvGetTickCount();
ioctl(fd,VIDIOC_DQBUF,&buf);
buf.index = 0;
cvmat =cvMat(IMAGEHEIGHT,IMAGEWIDTH,CV_8UC3,(void*)buffer);//CV_8UC3
img = cvDecodeImage(&cvmat,1);
cv::Mat MImg=cv::cvarrToMat(img);//Mat
// MImg=MImg(cv::Rect(0,0,630,470));
cv::rotate(MImg,MImg,cv::ROTATE_180);
IplImage iplImage1(MImg);
img1=&iplImage1;
qmg=new QImage((unsigned char*)img1->imageData,img1->width,img1->height,img1->widthStep,QImage::Format_RGB888);
if(!img) qDebug("CAM2 No img
");
cvReleaseImage(&img);
ioctl(fd,VIDIOC_QBUF,&buf);
t=(double)cvGetTickCount()-t;
if(device_video==1){
emit image_data(qmg->copy());
}
if(device_video==2){
emit image_data1(qmg->copy());
}
}
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
close_ret = ioctl(fd,VIDIOC_STREAMOFF,&type);
close_ret = close( fd );
if ( close_ret == 0 )
{
qDebug("close success!");
}
}
int video_thread::init_v4l2(void){
if ((fd = open(deviceid, O_RDWR)) == -1){
return FALSE;
}
if(fcntl(fd,F_SETFD, FD_CLOEXEC) == -1)
{
}
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1){
return FALSE;
}
else
{}
fmtdesc.index = 0;
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
while(ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc) != -1){
fmtdesc.index++;
}
//set fmt
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = IMAGEWIDTH;
fmt.fmt.pix.height = IMAGEHEIGHT;
// fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; //*************************V4L2_PIX_FMT_YUYV****************
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; //*************************V4L2_PIX_FMT_YUYV****************
fmt.fmt.pix.field = V4L2_FIELD_NONE;
if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1){
// if (ioctl(fd, VIDIOC_TRY_FMT, &fmt) == -1){
return FALSE;
}
if(ioctl(fd,VIDIOC_G_FMT,&fmt) == -1){
return FALSE;
}
return TRUE;
}
int video_thread::v4l2_grab(void){
//struct v4l2_requestbuffers req = {0};
//4 request for 4 buffers
req.count = 1;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1)
{
return FALSE;
}
//5 mmap for buffers
buffer = (uchar*)malloc(req.count * sizeof(*buffer));
if(!buffer){
return FALSE;
}
unsigned int n_buffers;
for(n_buffers = 0;n_buffers < req.count; n_buffers++){
//struct v4l2_buffer buf = {0};
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = n_buffers;
if(ioctl(fd, VIDIOC_QUERYBUF, &buf) == -1){
return FALSE;
}
buffer = (uchar*)mmap (NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
if(buffer == MAP_FAILED){
return FALSE;
}
}
//6 queue
for(n_buffers = 0;n_buffers <req.count;n_buffers++){
buf.index = n_buffers;
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
if(ioctl(fd,VIDIOC_QBUF,&buf)){
// qDebug("query buffer error
");
return FALSE;
}
}
//7 starting
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if(ioctl(fd,VIDIOC_STREAMON,&type) == -1){
// qDebug("stream on error
");
return FALSE;
}
return TRUE;
}
于是换一种打开方式:头文件:
文章为作者独立观点,不代表 股票程序化软件自动交易接口观点