OpenEdv-开源电子网

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

OV2640无法实现缩放功能

[复制链接]

5

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2013-5-24
在线时间
1 小时
发表于 2015-11-18 17:27:12 | 显示全部楼层 |阅读模式
5金钱
最近在用OV2640做图像处理,自己设计了一个pcb,上面有正点原子4.3‘的TFT屏幕和OV2640,单片机是stm32f407。调试了一天,发现无论如何变更初始化系数都无法实现缩放功能。翻看过论坛里的一个帖子,说是要设置好开窗函数和输出窗口,但是问题好像没有那么简单,下面我详细说明一下我遇到的情况。
首先,OV2640有四个窗口设置,分别为传感器窗口、图像尺寸、图像窗口和图像输出大小设置。根据《STM32F4开发指南-寄存器版本》_V1.1中所写:“如果设置的图像输出大小不等于图像窗口设置大小,那么图像就会被缩放处理,只有这两者设置一样大的时候,输出比例才是1:1的”(参见p.538)。这句话也在事例代码中体现了:
[mw_shl_code=c,true]if(scale==0) { OV2640_ImageWin_Set((1600-lcddev.width)/2,(1200-lcddev.height)/2,lcddev.width,lcddev.height);//1:1真实尺寸 OV2640_OutSize_Set(lcddev.width,lcddev.height); sprintf((char*)msgbuf,"Full Size 1:1"); }else { OV2640_ImageWin_Set(0,0,1600,1200); OV2640_OutSize_Set(lcddev.width,lcddev.height);//全尺寸缩放 sprintf((char*)msgbuf,"Scale"); }[/mw_shl_code]
代码中写的很清楚,当scale=0时,也就是1:1的真实尺寸,传感器的尺寸是1600*1200,也就是说有这么多个像素点,而4.3‘的LCD屏幕有800*480个像素,所谓的1:1真实尺寸就是在1600*1200这个矩阵中开一个800*480的窗口,这个窗口在传感器正中心,传感器的每一个像素点对应LCD上的每一个像素点,这就是1:1的意思。
当scale=1时,也就是全尺寸缩放,显然LCD只有800*480的空间,但是传感器有1600*1200,因此这里的意思是说将1600*1200这么多像素通过OV2640内部的DSP功能进行全自动尺寸缩放为800*480输出,在LCD上看到的内容就是整个传感器所拍摄到的内容。

以上是我对这代代码的理解,如果没有错误,请继续往下看。

我用的LCD屏幕就是正点原子800*480的4.3‘的屏幕,但是我的输出窗口设置为200*200,也就是OV2640_OutSize_Set(200, 200),然后在LCD上左上角开始显示200*200的图像。
四个窗口的设置:
传感器尺寸初始化与示例代码一致(均为1600*1200):
[mw_shl_code=c,true]0x12, 0x00,// UXGA 1600*1200 0x17, 0x11, 0x18, 0x75, 0x19, 0x01, 0x1a, 0x97, 0x32, 0x36, 0x03, 0x0f,[/mw_shl_code]
图像尺寸也相同(均为1600*1200):
[mw_shl_code=c,true]0xc0, 0xc8,// 图像尺寸 1600*1200 0xc1, 0x96, 0x8c, 0x00,[/mw_shl_code]
而图像窗口和图像输出大小设置如下:
[mw_shl_code=c,true]uint16_t outh = 200, outw = 200; uint8_t temp = 0; uint16_t hsize, vsize; uint16_t offx, offy; offx = 0; offy = 0; hsize = 1600 / 4; vsize = 1200 / 4; SCCB_WriteByte(SCCB_ID, 0xFF, 0x00); SCCB_WriteByte(SCCB_ID, 0xE0, 0x04); SCCB_WriteByte(SCCB_ID, 0x51, hsize & 0xFF);// 设置H_SIZE的低八位 SCCB_WriteByte(SCCB_ID, 0x52, vsize & 0xFF);// 设置V_SIZE的低八位 SCCB_WriteByte(SCCB_ID, 0x53, offx & 0xFF);// 设置offx的低八位 SCCB_WriteByte(SCCB_ID, 0x54, offy & 0xFF);// 设置offy的低八位 temp = (vsize >> 1) & 0x80; temp |= (offy >> 4) & 0x70; temp |= (hsize >> 5) & 0x08; temp |= (offx >> 8) & 0x07; SCCB_WriteByte(SCCB_ID, 0x55, temp); // 设置H_SIZE/V_SIZE/OFFX,OFFY的高位 SCCB_WriteByte(SCCB_ID, 0x57, (hsize >> 2) & 0x80); // 设置H_SIZE/V_SIZE/OFFX,OFFY的高位 SCCB_WriteByte(SCCB_ID, 0xE0, 0x00); Delay_ms(100); outw = width / 4; outh = height / 4; SCCB_WriteByte(SCCB_ID, 0xFF, 0x00); SCCB_WriteByte(SCCB_ID, 0xE0, 0x04); SCCB_WriteByte(SCCB_ID, 0x5A, outw & 0xFF); // 设置OUTW的低八位 SCCB_WriteByte(SCCB_ID, 0x5B, outh & 0xFF); // 设置OUTH的低八位 temp = (outw >> 8) & 0x03; temp |= (outh >> 6) & 0x04; SCCB_WriteByte(SCCB_ID, 0x5C, temp); // 设置OUTH/OUTW的高位 SCCB_WriteByte(SCCB_ID, 0xE0, 0x00);[/mw_shl_code]
为了保证一致性,上述两个窗口的设置与示例代码也一致。可以看到,图像窗口设置为1600*1200,图像输出大小为200*200。如果说之前分析正点原子的那两段代码没错,那么这里无非就是将1600*1200的图像经过内部DSP图像处理之后缩放为200*200吧?也就是说在200*200的LCD屏幕范围上可以看到整个传感器所拍摄的东西?
但是,情况并不是这样,从LCD屏幕上看到的图像就感觉像是在1600*1200的传感器中开出了一个200*200的窗,然后显示出来。因为本人将上述代码的hisze和vsize(这两个值就是图像窗口大小)分别更换为800和800之后,显示图像的物体大小丝毫没有改变(应该是800*800的图像缩放到200*200),反而和1600*1200一模一样,就好比图像窗口的设置根本没起到作用。效果如图所示:

这个图是1600*1200的图像窗口设置
在200*200的图像输出大小下的结果。

这个图是800*800的图像窗口设置在200*200的图像输出大小下的结果。


总结一下,四个窗口设置分别为:
传感器窗口1600*1200
图像尺寸1600*1200
图像窗口???
图像输出大小设置200*200
第三个图像窗口设置无论设置成1600*1200还是800*800,图像输出始终没有缩放,感觉一直是1:1输出,求解答!!!

最佳答案

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

回复【2楼】正点原子: --------------------------------- 我用的初始化代码和设置函数都是你们的资料啊。。。。 下载了一个ST公司出的OV2640的驱动资料,比较了一下初始化。 0x50这个寄存器,他们初始化为0x92,即H_DIVIDER和V_DIVIDER均为2。你们的0x50寄存器设置了两遍,一次是0xa8(H_DIVIDER为5,V_DIVIDER为0),第二次是0x00,所以最后的结果就是两者均为0。导致的结果就是图像没有缩放,只是取框输出,不是scale dow ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

5

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2013-5-24
在线时间
1 小时
 楼主| 发表于 2015-11-18 17:27:13 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
我用的初始化代码和设置函数都是你们的资料啊。。。。

下载了一个ST公司出的OV2640的驱动资料,比较了一下初始化。
0x50这个寄存器,他们初始化为0x92,即H_DIVIDER和V_DIVIDER均为2。你们的0x50寄存器设置了两遍,一次是0xa8(H_DIVIDER为5,V_DIVIDER为0),第二次是0x00,所以最后的结果就是两者均为0。导致的结果就是图像没有缩放,只是取框输出,不是scale down输出。我把0x50改成0x89,即H_DIVIDER和V_DIVIDER均为1,缩放效果就出来了,并且值越大,缩放越厉害。

总之,问题解决了。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165359
金钱
165359
注册时间
2010-12-1
在线时间
2110 小时
发表于 2015-11-19 23:41:11 | 显示全部楼层
你可以试试我们的例程。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

0

主题

71

帖子

0

精华

高级会员

Rank: 4

积分
758
金钱
758
注册时间
2015-8-25
在线时间
165 小时
发表于 2016-1-1 11:53:04 | 显示全部楼层
我遇到与楼主一样的问题,最终也是把0x50设置为0x92,缩放效果出来了,但又有新的问题产生,就是设置后,不能运行图像窗口设置(OV2640_ImageWin_Set(0,0,1600,1200);)函数,一运行,马上死机。0x50设置为0后,运行图像窗口设置函数就不会死机,实验了很多遍,原因没有找到。又些郁闷,看样必须明白相关OV2640的寄存器设置才能解决问题。
回复

使用道具 举报

4

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2015-11-11
在线时间
2 小时
发表于 2016-1-26 17:21:58 | 显示全部楼层
请教楼主,图像缩放后,图像质量是变差了还是变好了呢?
回复

使用道具 举报

5

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2013-5-24
在线时间
1 小时
 楼主| 发表于 2016-3-4 20:43:33 | 显示全部楼层
phoenix 发表于 2016-1-1 11:53
我遇到与楼主一样的问题,最终也是把0x50设置为0x92,缩放效果出来了,但又有新的问题产生,就是设置后,不 ...

这种情况我没遇到过,你最好看看初始化代码把,我感觉这些设备的初始化代码每个开发板都不同,版本太多了,完全不统一。只能自己一个个看
回复

使用道具 举报

5

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2013-5-24
在线时间
1 小时
 楼主| 发表于 2016-3-4 20:45:04 | 显示全部楼层
半毛钱 发表于 2016-1-26 17:21
请教楼主,图像缩放后,图像质量是变差了还是变好了呢?

图像缩放后会出现桶形失真,因为取景范围是整个传感器范围缩放,所以会出现上述失真。具体实现方法应该是隔行采集的,图像范围是大了,但是细节缺失,分辨率降低,无法分辨很窄的细线
回复

使用道具 举报

2

主题

14

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2016-3-6
在线时间
11 小时
发表于 2016-3-12 17:56:21 | 显示全部楼层
好贴,顶
回复

使用道具 举报

3

主题

9

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2017-7-4
在线时间
3 小时
发表于 2017-7-15 18:23:35 | 显示全部楼层
请问楼主,如果只想要拍摄图像的中间位置,需要怎么设置开窗呢,要调用哪个函数呢?
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-12-18 21:49

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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