#include "imagecamera.h"
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <linux/videodev2.h>
#include <QDir>
#include <dirent.h>
#include <unistd.h>
#include <asm/types.h>
#include <math.h>
#include <malloc.h>
#include <QImage>
#define log_debug qDebug
void yuyv_to_rgb888(unsigned char* yuv,unsigned char* rgb, int imgWidth, int imgHeight)
{
unsigned int i;
unsigned char* y0 = yuv + 0;
unsigned char* u0 = yuv + 1;
unsigned char* y1 = yuv + 2;
unsigned char* v0 = yuv + 3;
unsigned char* r0 = rgb + 0;
unsigned char* g0 = rgb + 1;
unsigned char* b0 = rgb + 2;
unsigned char* r1 = rgb + 3;
unsigned char* g1 = rgb + 4;
unsigned char* b1 = rgb + 5;
//DBG("yuyv_to_rgb start\n");
float rt0 = 0, gt0 = 0, bt0 = 0, rt1 = 0, gt1 = 0, bt1 = 0;
for(i = 0; i <= (imgWidth * imgHeight) / 2 ;i++)
{
bt0 = 1.164 * (*y0 - 16) + 2.018 * (*u0 - 128);
gt0 = 1.164 * (*y0 - 16) - 0.813 * (*v0 - 128) - 0.394 * (*u0 - 128);
rt0 = 1.164 * (*y0 - 16) + 1.596 * (*v0 - 128);
bt1 = 1.164 * (*y1 - 16) + 2.018 * (*u0 - 128);
gt1 = 1.164 * (*y1 - 16) - 0.813 * (*v0 - 128) - 0.394 * (*u0 - 128);
rt1 = 1.164 * (*y1 - 16) + 1.596 * (*v0 - 128);
if(rt0 > 250) rt0 = 255;
if(rt0 < 0) rt0 = 0;
if(gt0 > 250) gt0 = 255;
if(gt0 < 0) gt0 = 0;
if(bt0 > 250) bt0 = 255;
if(bt0 < 0) bt0 = 0;
if(rt1 > 250) rt1 = 255;
if(rt1 < 0) rt1 = 0;
if(gt1 > 250) gt1 = 255;
if(gt1 < 0) gt1 = 0;
if(bt1 > 250) bt1 = 255;
if(bt1 < 0) bt1 = 0;
*r0 = (unsigned char)bt0;
*g0 = (unsigned char)gt0;
*b0 = (unsigned char)rt0;
*r1 = (unsigned char)bt1;
*g1 = (unsigned char)gt1;
*b1 = (unsigned char)rt1;
yuv = yuv + 4;
rgb = rgb + 6;
if(yuv == NULL)
break;
y0 = yuv;
u0 = yuv + 1;
y1 = yuv + 2;
v0 = yuv + 3;
r0 = rgb + 0;
g0 = rgb + 1;
b0 = rgb + 2;
r1 = rgb + 3;
g1 = rgb + 4;
b1 = rgb + 5;
}
}
ImageCamera::ImageCamera(QString c, QObject *parent) : QThread(parent)
{
camera = c;
err.clear();
nWidth = 1280;
nHeight = 960;
nSize = nWidth * nHeight * 2;
bKeep = false;
memset(pix_format, 0, sizeof(pix_format));
cam_fd = -1;
buffer_count = 5;
video_buffer_ptr = new u8*[buffer_count];
}
bool ImageCamera::initCamera()
{
int index = 0;
int ret = 0;
if(camera.isEmpty())
{
err = QString("设备节点位置为空");
return false;
}
if(cam_fd != -1)
{
close(cam_fd);
}
// 打开相机
cam_fd = open(camera.toStdString().c_str(), O_RDWR);
if(cam_fd == -1)
{
err = QString("打开相机节点失败");
return false;
}
// 设置使用的相机通道,此处为0
if(0 != ioctl(cam_fd, VIDIOC_S_INPUT, &index))
{
err = QString("%1").arg(strerror(errno));
return false;
}
// 查询相机的基本信息
struct v4l2_capability cap;
ioctl(cam_fd,VIDIOC_QUERYCAP,&cap);
log_debug("Driver Name:%s Card Name:%s Bus info:%s Driver Version:%u.%u.%u",
cap.driver,cap.card,cap.bus_info,(cap.version>>16)&0xFF, (cap.version>>8)&0xFF,cap.version&0xFF);
// 查询相机支持的采图格式
struct v4l2_fmtdesc fmtdesc;
fmtdesc.index=0;
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
log_debug("Support format:");
do{
ret=ioctl(cam_fd, VIDIOC_ENUM_FMT, &fmtdesc);
log_debug("index %d, format %s", fmtdesc.index, fmtdesc.description);
fmtdesc.index++;
}while(0==ret);
// 查询相机支持的帧率范围
struct v4l2_streamparm stream_parm;
memset(&stream_parm, 0, sizeof(struct v4l2_streamparm));
stream_parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ret = ioctl(cam_fd, VIDIOC_G_PARM, &stream_parm);
log_debug("befor:framerate: numerator = %d,denominator = %d",
stream_parm.parm.capture.timeperframe.numerator,stream_parm.parm.capture.timeperframe.denominator);
// 设置相机的输出格式,图片大小等数据
struct v4l2_format format;
memset(&format, 0, sizeof(format));
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
format.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; //V4L2_PIX_FMT_YUYV 设置相机输出为JPEG,也可设置为yuyv,但具体的输出格式不能依靠此处
format.fmt.pix.width = nWidth; // 设置输出图片宽、高
format.fmt.pix.height = nHeight;
//********
// format.fmt.pix.bytesperline = IMAGE_WIDTH * 1;
// format.fmt.pix.sizeimage = IMAGE_WIDTH * IMAGE_HEIGHT * 1;
// format.fmt.pix.field = V4L2_FIELD_NONE;
// 尝试相机是否支持改格式
ret = ioctl(cam_fd, VIDIOC_TRY_FMT, &format);
if (ret != 0)
{
err = QString::asprintf("ioctl(VIDIOC_TRY_FMT) failed %d(%s)", errno, strerror(errno));
log_debug(err.toLatin1().constData());
return false;
}
// 真正进行设置改格式
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ret = ioctl(cam_fd, VIDIOC_S_FMT, &format);
if (ret != 0)
{
err = QString::asprintf("ioctl(VIDIOC_S_FMT) failed %d(%s)", errno, strerror(errno));
log_debug(err.toLatin1().constData());
return false;
}
// 获取相机输出的图片参数
if(-1 == ioctl(cam_fd, VIDIOC_G_FMT, &format)){//得到图片格式
err = QString("set format failed!");
log_debug(err.toLatin1().constData());
return false;
}
log_debug("fmt.type:\t\t%d",format.type);
/**************************************************************/
// 此处的图片格式,决定着采集到的图片数据要怎么解析,一般分为 MJPG 和 YUYV,上面设置的和此处获取的在某些情况下会不一致,因此需要此处决定解析格式
sprintf(pix_format, "%c%c%c%c", \
format.fmt.pix.pixelformat & 0xFF,\
(format.fmt.pix.pixelformat >> 8) & 0xFF, \
(format.fmt.pix.pixelformat >> 16) & 0xFF,\
(format.fmt.pix.pixelformat >> 24) & 0xFF);
log_debug("pix.pixelformat:\t%s", pix_format);
log_debug("pix.width:\t\t%d",format.fmt.pix.width);
log_debug("pix.height:\t\t%d",format.fmt.pix.height);
log_debug("pix.field:\t\t%d",format.fmt.pix.field);
// 查询相机需要开辟的内存信息
struct v4l2_requestbuffers req;
req.count = buffer_count;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
ret = ioctl(cam_fd, VIDIOC_REQBUFS, &req);
if (ret != 0)
{
err = QString::asprintf("ioctl(VIDIOC_REQBUFS) failed %d(%s)", errno, strerror(errno));
log_debug(err.toLatin1().constData());
return false;
}
log_debug("req.count: %d", req.count);
if (req.count < buffer_count)
{
err = QString::asprintf("request buffer failed");
log_debug(err.toLatin1().constData());
return false;
}
// 逐一将相机开辟的内存进行内存映射
struct v4l2_buffer buffer;
memset(&buffer, 0, sizeof(buffer));
buffer.type = req.type;
buffer.memory = V4L2_MEMORY_MMAP;
for (int i=0; i<req.count; i++)
{
buffer.index = i;
ret = ioctl (cam_fd, VIDIOC_QUERYBUF, &buffer);
if (ret != 0)
{
err = QString::asprintf("ioctl(VIDIOC_QUERYBUF) failed %d(%s)", errno, strerror(errno));
log_debug(err.toLatin1().constData());
return false;
}
log_debug("buffer.length: %d", buffer.length);
log_debug("buffer.m.offset: %d", buffer.m.offset);
video_buffer_ptr[i] = (u8*) mmap(NULL, buffer.length, PROT_READ|PROT_WRITE, MAP_SHARED, cam_fd

北极熊的奋斗史
- 粉丝: 149
最新资源
- 第八篇范本格式和程序.doc
- 安全教育计划制度.doc
- 壁挂炉与其他采暖方式费用对比分析.doc
- 中国区块链技术发展及应用研究.docx
- STM32F0内核介绍.pdf
- 大卸料平台技术交底.doc
- 福建某医院病房楼施工组织设计(5层-框剪结构).doc
- 幼儿园数学活动教案.doc
- 微机原理与接口技术漆强版第1章微型计算机系统概述.ppt
- 模板、拱架及支架安装质量检查记录表.doc
- 大数据背景下孤儿学生化学学科课前预习习惯培养的研究.docx
- STM32L4四线串行外设接口模块(QSPI)介绍.pdf
- 钢结构专业分包制作招标文件.doc
- AUTOCAD绘制道路工程图的方法和实例.doc
- 标准化法实施条例.docx
- 郑州某房地产开发项目风险分析.doc
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈



- 1
- 2
前往页