OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 10049|回复: 19

OV2640转灰度图像

[复制链接]

12

主题

63

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
408
金钱
408
注册时间
2016-1-28
在线时间
72 小时
发表于 2016-7-9 10:22:51 | 显示全部楼层 |阅读模式
10金钱
最近在做OV2640输出灰度图像,一直没有搞出来,不确定是YUV422格式转灰度,还是RGB565转灰度,原子哥在论坛回复的两次还不同,如图


还有怎么设置YUV422输出,根据探索者给的例程,是不是可以直接在OV2640_JPEG_Mode()函数里,调用YUV422输出就可以了?

YUV输出

YUV输出

直接RGB输出

直接RGB输出

探索者例程

探索者例程

最佳答案

查看完整内容[请看2#楼]

仅供参考,有错误,请指正。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

71

帖子

0

精华

高级会员

Rank: 4

积分
758
金钱
758
注册时间
2015-8-25
在线时间
165 小时
发表于 2016-7-9 10:22:52 | 显示全部楼层
zhang911 发表于 2016-7-9 11:11
你好  多谢回复,能不能给份源码参考参考,谢谢

仅供参考,有错误,请指正。

摄像头实验_输出YUV转灰度显示到LCD(寄存器版).zip

2.73 MB, 下载次数: 1288

回复

使用道具 举报

12

主题

63

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
408
金钱
408
注册时间
2016-1-28
在线时间
72 小时
 楼主| 发表于 2016-7-9 10:24:44 | 显示全部楼层
如果是YUV输出,怎么将Y分类转换为RGB,请路过的做过OV2640的前辈们多多指教
回复

使用道具 举报

0

主题

71

帖子

0

精华

高级会员

Rank: 4

积分
758
金钱
758
注册时间
2015-8-25
在线时间
165 小时
发表于 2016-7-9 10:47:30 | 显示全部楼层
本帖最后由 phoenix 于 2016-7-16 17:17 编辑
zhang911 发表于 2016-7-9 10:24
如果是YUV输出,怎么将Y分类转换为RGB,请路过的做过OV2640的前辈们多多指教

先得让OV2640输出YUV422格式数据


void OV2640_YUV422_Mode(void);//设置OV2640输出YUV422.(YUYV)格式(16位数据的高字节为亮度值Y)
{
        u8 temp;
        SCCB_slave_address = 0x60; //设备的地址(0x60用于写/0x61用于读)
        write_SCCB(0xff, 0x00);  //要设置0xDA寄存器,必须让0xFF=0x00

        write_SCCB(0xda, 0x00);//设置OV2640输出YUYV格式

        temp = read_SCCB(0xc2); //读寄存器 0xc2 并赋值给temp
        temp &= 0xef;                //变量temp 位4为0
        write_SCCB(0xc2, temp);//寄存器 0xc2 位4为0
}


如格式正确输出,LCD上会出现五颜六色的波纹图像,然后你在把Y分量转换为灰度输出到LCD上。








定义个变量:

u16 Gray;//灰度值


Gray =(((yuv422>>(8+3))<<11)|((yuv422>>(8+2))<<5)|((yuv422>>(8+3))<<0));

这是把YUV422格式转换为灰度值以RGB565格式显示在LCD上



yuv422 即:YVYU 格式(16位) ,其中,Y为亮度值(8位)。

奇次输出YV(16位) ,偶次输出YU(16位),按此规律循环输出直至最后数据。就是说YVYU 格式数据每次输出(16位)的数据高字节部分为亮度值 Y 。

RGB565格式为(16位),即R为16位中的高5位,即G为16位中的中6位,即B为16位中的低5位。

因此:

yuv422>>(8+3);//即,只取Y值的高5位(丢弃U或V)

yuv422>>(8+2);//即,只取Y值的高6位(丢弃U或V)

yuv422>>(8+3);//即,只取Y值的高5位(丢弃U或V)

把这三个(高5位、高6位、高5位)Y值位或运算,即可得灰度图像值(RGB565格式)

就是这个:

Gray =(((yuv422>>(8+3))<<11)|((yuv422>>(8+2))<<5)|((yuv422>>(8+3))<<0));



YUV.jpg
回复

使用道具 举报

12

主题

63

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
408
金钱
408
注册时间
2016-1-28
在线时间
72 小时
 楼主| 发表于 2016-7-9 11:11:21 | 显示全部楼层
phoenix 发表于 2016-7-9 10:47
先得让OV2640输出YUV422格式数据

你好  多谢回复,能不能给份源码参考参考,谢谢
回复

使用道具 举报

12

主题

63

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
408
金钱
408
注册时间
2016-1-28
在线时间
72 小时
 楼主| 发表于 2016-7-9 22:42:28 | 显示全部楼层
本帖最后由 zhang911 于 2016-7-9 22:44 编辑
phoenix 发表于 2016-7-9 10:22
仅供参考,有错误,请指正。

你好,谢谢你的程序,可以在LCD屏上进行灰度显示。
现在想把LCD->LCD_RAM的16位数据拆分开来8位数据发送到智能车调试助手,进行灰度显示,这个助手结束指令是0xff,通过串口发送,但现在不能正常显示,不知道问题出在哪里??
调试助手.png
输出调试助手灰度.png
回复

使用道具 举报

0

主题

71

帖子

0

精华

高级会员

Rank: 4

积分
758
金钱
758
注册时间
2015-8-25
在线时间
165 小时
发表于 2016-7-11 21:11:55 | 显示全部楼层
zhang911 发表于 2016-7-9 22:42
你好,谢谢你的程序,可以在LCD屏上进行灰度显示。
现在想把LCD->LCD_RAM的16位数据拆分开来8位数据发送 ...

1、我的例子是寄存器版本,你的串口2发送数据是用的库函数,没有报错?

回复

使用道具 举报

12

主题

63

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
408
金钱
408
注册时间
2016-1-28
在线时间
72 小时
 楼主| 发表于 2016-7-16 09:25:25 | 显示全部楼层
phoenix 发表于 2016-7-11 21:11
1、我的例子是寄存器版本,你的串口2发送数据是用的库函数,没有报错?

我用的是库函数版本,移植了你的部分代码,没有报错
回复

使用道具 举报

11

主题

46

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
244
金钱
244
注册时间
2016-4-15
在线时间
66 小时
发表于 2016-7-16 15:43:19 | 显示全部楼层
本帖最后由 li1207519730 于 2016-7-16 15:47 编辑
phoenix 发表于 2016-7-9 10:22
仅供参考,有错误,请指正。

DMA配置成双缓冲模式,把YUV422写进外部SRAM,然后转成灰度图像用LCD显示,但显示效果和层主的的这个完全不一样,也不知道问题出在哪儿,求帮助

摄像头实验寄存器实验 - 副本.zip

3.21 MB, 下载次数: 3769

回复

使用道具 举报

0

主题

71

帖子

0

精华

高级会员

Rank: 4

积分
758
金钱
758
注册时间
2015-8-25
在线时间
165 小时
发表于 2016-7-16 16:59:46 | 显示全部楼层
zhang911 发表于 2016-7-16 09:25
我用的是库函数版本,移植了你的部分代码,没有报错

有图像是吗?如果有,只是不正常,那能不能是,高低字节顺序错了?颠倒下试试。
回复

使用道具 举报

0

主题

71

帖子

0

精华

高级会员

Rank: 4

积分
758
金钱
758
注册时间
2015-8-25
在线时间
165 小时
发表于 2016-7-16 18:07:30 | 显示全部楼层
本帖最后由 phoenix 于 2016-7-16 18:14 编辑
li1207519730 发表于 2016-7-16 15:43
DMA配置成双缓冲模式,把YUV422写进外部SRAM,然后转成灰度图像用LCD显示,但显示效果和层主的的这个完全 ...

抱歉,双缓冲模式没有试过,也没有去关注,并不熟悉。

我建议你,分步测试。

先让OV2640输出RGB565格式到外部SRAM后,能正确把图像数据传输到LCD上。
再让OV2640输出YUV422格式到外部SRAM后,能正确把图像数据传输到LCD上。
再让OV2640输出YUV422格式到外部SRAM后,把数据转换为灰度数据传输到LCD上。

但使用外部SRAM应该注意以下几点(原子哥原话)

1,设置存储器地址自增。
2,传输长度为1(参考我们摄像头例程)。
3,注意在每一帧传输完成后,重新设置存储器首地址。
4,注意降低OV2640的输出速率,否则SRAM存储不过来。

在你的代码中:
pic_buff=0x68000000;
bufsize=16;
DCMI_DMA_Init(pic_buff,bufsize,2,1);//DCMI DMA配置


bufsize 为什么设置为16?不太理解。你的 LCD是240X320?
回复

使用道具 举报

11

主题

46

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
244
金钱
244
注册时间
2016-4-15
在线时间
66 小时
发表于 2016-7-16 18:07:36 | 显示全部楼层
本帖最后由 li1207519730 于 2016-7-16 19:00 编辑
phoenix 发表于 2016-7-16 16:59
有图像是吗?如果有,只是不正常,那能不能是,高低字节顺序错了?颠倒下试试。

有图像,就是感觉图像整体发白,甚至白到模模糊糊看不出拍到的东西,不清晰,“黑白”层次感不强。(手机拍摄问题导致屏幕稍微发蓝)
77R(VHFAZ`3B[YHP`C2K(2D.png
回复

使用道具 举报

0

主题

71

帖子

0

精华

高级会员

Rank: 4

积分
758
金钱
758
注册时间
2015-8-25
在线时间
165 小时
发表于 2016-7-16 18:25:08 | 显示全部楼层
li1207519730 发表于 2016-7-16 18:07
有图像,就是感觉图像整体发白,甚至白到模模糊糊看不出拍到的东西,不清晰,“黑白”层次感不强。(手机 ...

我建议
1、先把摄像头固定(始终拍同一个位置的图像)
2、让OV2640把灰度图像传输到LCD上,并把图像记录下来(如:用手机拍照)
3、用其它”串口助手“接收数据,检验数据是否正确(用photoshop新建并储存一个与摄像头相同分辨率的RGB565格式的bmp文件,并用WinHex把这bmp中的图像数据替换为串口助手接收到数据后,打开这个bmp文件,对比下手机拍照的图像)
回复

使用道具 举报

11

主题

46

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
244
金钱
244
注册时间
2016-4-15
在线时间
66 小时
发表于 2016-7-16 19:06:11 | 显示全部楼层
phoenix 发表于 2016-7-16 18:07
抱歉,双缓冲模式没有试过,也没有去关注,并不熟悉。

我建议你,分步测试。

16是随便设的,3,4,8,16,32,随便找个值用RGB565测试,都能转化为灰度图像输出到LCD上,这点我也很纳闷儿,而且这个数据传输量到底指的是什么、一个数据项所含的位数到底取决于什么我也一直搞不懂
回复

使用道具 举报

0

主题

71

帖子

0

精华

高级会员

Rank: 4

积分
758
金钱
758
注册时间
2015-8-25
在线时间
165 小时
发表于 2016-7-16 21:41:08 | 显示全部楼层
li1207519730 发表于 2016-7-16 19:06
16是随便设的,3,4,8,16,32,随便找个值用RGB565测试,都能转化为灰度图像输出到LCD上,这点我也很纳闷儿 ...

//DCMI DMA配置
//memaddr:存储器地址    将要存储摄像头数据的内存地址(也可以是外设地址)
//memsize:存储器长度    0~65535
//memblen:存储器位宽    0,8位,1,16位,2,32位
//meminc:存储器增长方式,0,不增长;1,增长
void DCMI_DMA_Init(u32 memaddr,u16 memsize,u8 memblen,u8 meminc)


【1】  16是随便设的,3,4,8,16,32,随便找个值用RGB565测试,都能转化为灰度图像输出到LCD上,这点我也很纳闷儿,而且这个数据传输量到底指的是什么

这个"数据传输量"是:存储器长度

【2】  一个数据项所含的位数到底取决于什么我也一直搞不懂
取决于:存储器位宽,比如,LCD的显存位宽为16位,探索者外部SRAM位宽为:16位
回复

使用道具 举报

3

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
70
金钱
70
注册时间
2017-7-12
在线时间
13 小时
发表于 2017-8-5 00:37:43 | 显示全部楼层
li1207519730 发表于 2016-7-16 18:07
有图像,就是感觉图像整体发白,甚至白到模模糊糊看不出拍到的东西,不清晰,“黑白”层次感不强。(手机 ...

YUV422格式网上有好多种,不知道这里用的格式是哪一种,能告诉一下吗
回复

使用道具 举报

41

主题

226

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
481
金钱
481
注册时间
2017-7-29
在线时间
233 小时
发表于 2017-8-6 22:01:09 | 显示全部楼层
phoenix 发表于 2016-7-9 10:22
仅供参考,有错误,请指正。

学到了,非常好的程序,也简单易懂!
回复

使用道具 举报

41

主题

226

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
481
金钱
481
注册时间
2017-7-29
在线时间
233 小时
发表于 2017-8-7 09:49:19 | 显示全部楼层
phoenix 发表于 2016-7-9 10:47
先得让OV2640输出YUV422格式数据

有个小问题,就是二值化后的图形有“噪点”,有点像光线影响的,照全白纸张时周边有些许黑色,用手机在附近打闪光灯,黑色噪点就消失,能不能通过程序进行优化消除噪点呢?
回复

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
23
金钱
23
注册时间
2018-1-24
在线时间
4 小时
发表于 2018-1-25 15:43:25 | 显示全部楼层
phoenix 发表于 2016-7-9 10:47
先得让OV2640输出YUV422格式数据

这个是按照你的方法输出的YUV422图像,向纹波一样
下面这个是按照你给的公式得出的灰度图像
怎么感觉图像是花的,难道是我弄错了,下面是我的代码

u32 RGB_BUF[Width][High];       

void RGB_data_process(void)
{
        u16 i,j;
        for(i=0;i<Width;i++)
                for(j=0;j<High;j++)
                {
                         LCD_SetCursor(j,i);
                         LCD_WriteRAM_Prepare();
                         Gray =(((RGB_BUF[j]>>(8+3))<<11)|((RGB_BUF[j]>>(8+2))<<5)|((RGB_BUF[j]>>(8+3))<<0));
                         LCD->LCD_RAM = RGB_BUF[j];
                       
                }
       
}




void OV2640_YUV422_Mode(void)
{
        //éè&#214;&#195;:YUV422&#184;&#241;ê&#189;
        SCCB_WR_Reg(0xFF, 0x00);//éè&#214;&#195;:YUV422ê&#228;3&#246;
        SCCB_WR_Reg(0xDA, 0x01);//YUV422.YVYU       
       
}


DCMI_DMA_Init((u32)&RGB_BUF,RGB_BUF_Size,DMA_MemoryDataSize_HalfWord,DMA_MemoryInc_Enable);

回复

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
23
金钱
23
注册时间
2018-1-24
在线时间
4 小时
发表于 2018-1-25 15:45:28 | 显示全部楼层
phoenix 发表于 2016-7-9 10:47
先得让OV2640输出YUV422格式数据

这个是按照你的方法输出的YUV422图像,向纹波一样
下面这个是按照你给的公式得出的灰度图像
怎么感觉图像是花的,难道是我弄错了,下面是我的代码

u32 RGB_BUF[Width][High];
void OV2640_YUV422_Mode(void)
{
        //éè&#214;&#195;:YUV422&#184;&#241;ê&#189;
        SCCB_WR_Reg(0xFF, 0x00);//éè&#214;&#195;:YUV422ê&#228;3&#246;
        SCCB_WR_Reg(0xDA, 0x01);//YUV422.YVYU       
       
}


DCMI_DMA_Init((u32)&RGB_BUF,RGB_BUF_Size,DMA_MemoryDataSize_HalfWord,DMA_MemoryInc_Enable);//DCMI DMA&#197;&#228;&#214;&#195;  


void RGB_data_process(void)
{
        u16 i,j;
        for(i=0;i<Width;i++)
                for(j=0;j<High;j++)
                {
                         LCD_SetCursor(j,i);
                         LCD_WriteRAM_Prepare();
                         Gray =(((RGB_BUF[j]>>(8+3))<<11)|((RGB_BUF[j]>>(8+2))<<5)|((RGB_BUF[j]>>(8+3))<<0));
                         LCD->LCD_RAM = Gray;
                       
                }
       
}

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-8 21:57

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表