TQ2440 基于V4L2编程框架的 LCD实时显示(下)
来源:互联网 发布:数据库高并发处理 编辑:程序博客网 时间:2024/06/04 19:22
绪上一篇:
本次实验为基于V4L2框架,使用USB摄像头进行图像采集,用4.3寸LCD屏进行实时显示。由于,知识缺乏未能完整的进行下去,失败在图像实时显示上面,因为要放一段时间,所以在此做次记录,希望能帮助到一些小伙伴,站在前人的路上把该问题解决掉。
一、情况说明
1、使用TQ2440开发板、4.3寸TFT LCD屏,分辨率为480*272 16bpp
2、普通USB摄像头,采集的图像格式为YUV422,分辨率为320*240
二、实验进展
1、USB摄像头可以进行图片采集,但在lcd显示时不能全屏显示,只显示lcd屏上面一半,且出现三个窗口暂时不知怎么解决
2、摄像头采集的图片为YUV422格式要在LCD屏显示需要转成RGB565格式,这个已经完成
3、由于二十多块买的摄像头其分辨率320*240,需要将其放大到480*272,这个代码已经完成
三、所遇问题
现在不知如何解决图像正确显示问题。。。。
/*************************************************以上是上一次遇到的并停下的问题********************************************************************************/
最新情况:
又经过了一个多星期,应该说放了一个多星期,就在前天突然在韦东山老师的第三个项目中找到的可以相关代码,然后参考其实现代码,我在原来的基础上改了图片显示的方式。
之前由于摄像头采集到的图像像素为320*240,而lcd显示屏像素为480*272,因此采集到的图像像素和显示屏像素是不相等的。当时,我的想法是直接在lcd上从fb0的映射地址起始处写入数据,然后就出现了之前出现的三个一个屏三个窗口的结果。无奈之下,我就想就参考下韦东山老师项目中的居中显示吧,没想到一试竟然马上成功了。如下图所示。
然后仔细看代码,以及修改了一些代码进行测试,终于找出了以前困扰我许久的显示问题:为什么会出现三个或多个窗口?原来我之前是吧一张像素为320*240的图像,将其数据从其buf[0]->buf[Max_size]一股脑的直接写入fb映射的显存中去,而没有分行分行的去显示所采集图像的内容,这就导致原本下一行的像素数据直接填充到了这一行,这样自然会出现这些错位,多窗口的现象。
以前的代码:
memcpy(fb_addr,buf[index].start,buf[index].length) //这是错误的,将导致一开始的多窗口效果
修改之后:
for (i = 0; i <camdev->cHeight; i++) //camdev->cHeight为采集到的图像高度
{
//这里每次只拷贝一行的像素数据
memcpy(pucDst, pucSrc, camdev->cLineBytes);
pucSrc += camdev->cLineBytes;//到下一行取数据
pucDst += myfb->iLineBytes;//到下一行显示
}
修改代码后便可正常显示。下面这张截图是320*240像素放大到480*272像素的图像显示效果,图像放大,采用了最近邻插值法,这是最简单,但效果最不好的一种方法,所以图片会有点模糊,但已经可以完成由摄像头采集图像信息,并在lcd实时显示了。
以下是部分核心代码:
/*
*函数功能:图像处理并显示
*/
void display_pic(Cam_dev *camdev,Fb_dev *myfb)
{
struct v4l2_buffer buf;
unsigned char* ptmp;
unsigned long i,j;
CLEAR (buf);
buf.memory = V4L2_MEMORY_MMAP;
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
/*取出一缓冲帧*/
if (-1 == ioctl(camdev->cfd, VIDIOC_DQBUF, &buf))
{
printf(" VIDIOC_DQBUF error!\n");
exit(-1);
}
/*检查缓冲帧是否有效*/
assert(buf.index < 4);
/*图片格式转换:YUV422->RGB565*/
ptmp = (unsigned char*)buffers[buf.index].start;
Pyuv422torgb565(ptmp,camdev->displaybuf,camdev->cHeight,camdev->cWidth);
/*图像放大后LCD显示*/
PicZoomF(camdev,myfb);
/*小图像居中显示*/
//PicMerge(camdev,myfb);
if (-1 == ioctl(camdev->cfd, VIDIOC_QBUF, &buf))
{
printf("VIDIOC_QBUF error!\n");
exit(-1);
}
}
/*
*函数功能:居中显示小的图像
*/
int PicMerge(Cam_dev *camdev,Fb_dev *myfb)
{
int i;
int iX,iY;
unsigned char *pucSrc;
unsigned char *pucDst;
iX = (myfb->iWidth -camdev->cWidth )/2;
iY = (myfb->iHeight -camdev->cHeight )/2;
//指向yuv422->RGB565转换后的图像起始位置
pucSrc = camdev->displaybuf;
//计算空出来的起始的空格
pucDst = myfb->fb_addr + iY * myfb->iLineBytes + iX *myfb->iBpp/8;
for (i = 0; i <camdev->cHeight; i++)
{
//这里每次只拷贝一行的像素数据
memcpy(pucDst, pucSrc, camdev->cLineBytes);
pucSrc += camdev->cLineBytes;//到下一行取数据
pucDst += myfb->iLineBytes;//到下一行显示
}
return 0;
}
/*
*函数功能:进行图像缩放并显示
*/
int PicZoomF(Cam_dev *camdev,Fb_dev *myfb)
{
unsigned long dwDstWidth = myfb->iWidth; //LCD一行像素宽度
unsigned long* pdwSrcXTable;
unsigned long x;
unsigned long y;
unsigned long dwSrcY;
unsigned char *pucDest;
unsigned char *pucSrc;
unsigned long dwPixelBytes =myfb->iBpp/2; //每个像素字节数
//创建了放一行像素的空间
pdwSrcXTable = malloc(sizeof(unsigned long) * dwDstWidth);
if (NULL == pdwSrcXTable)
{
printf("malloc error!\n");
return -1;
}
//生成表 pdwSrcXTable
for (x = 0; x < dwDstWidth; x++)
{
pdwSrcXTable[x]=(x*camdev->cWidth/myfb->iWidth);
}
//进行列的缩放
for (y = 0; y < myfb->iHeight; y++)
{
dwSrcY = (y * camdev->cHeight / myfb->iHeight);
//目标图像的第x行起始地址
pucDest = myfb->fb_addr + y*myfb->iLineBytes;
//原始图像的第x行起始地址
pucSrc = camdev->displaybuf + dwSrcY*camdev->cLineBytes;
for (x = 0; x <dwDstWidth; x++)
{
/* 原图座标: pdwSrcXTable[x],srcy
* 缩放座标: x, y
*/
memcpy(pucDest+x*dwPixelBytes, pucSrc+pdwSrcXTable[x]*dwPixelBytes, dwPixelBytes);
}
}
free(pdwSrcXTable);
return 0;
}
- TQ2440 基于V4L2编程框架的 LCD实时显示(下)
- TQ2440 基于V4L2编程框架的 LCD实时显示(上)
- u-boot支持LCD显示(基于TQ2440)
- V4L2编程框架(*)
- V4L2编程框架(*)
- V4L2编程框架(*)
- V4L2编程框架(*)
- Linux下基于v4l2框架的图像采集
- TQ2440的学习——TFT LCD控制显示总结(硬件概念、初始化相关配置)
- TQ2440的学习——TFT LCD控制显示总结(硬件概念、初始化相关配置)
- 基于TQ2440的小车(4)网络编程控制
- 基于嵌入式Linux的视频采集系统6----视频在LCD上的实时显示
- 基于In-System Memory Content Editor的LCD实时显示字符更改
- Linux下的V4L2编程
- 基于V4L2框架的linux驱动程序编写
- 【转】TQ2440的学习——TFT LCD控制显示总结(硬件概念、初始化相关配置)
- (转)LCD编程框架
- 基于storm的实时框架
- Topo和Markdown在项目中的实践
- 一维搜索方法(一)黄金分割法
- Class.forName()用法详解
- 123
- 图像分析:阶段总结
- TQ2440 基于V4L2编程框架的 LCD实时显示(下)
- android 四种跨进程通讯方式
- Yii
- centos7 apache httpd安装和配置django项目
- 有关于100动态规划专栏的说明
- Tomcat 综述
- 运算符重载
- Netty源码解读(一)概述
- Floyd+路径输出