OV2640无法实现缩放功能

2019-07-20 13:24发布

最近在用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输出,求解答!!!

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
8条回答
yzhajlydy
2019-07-20 17:58
回复【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,缩放效果就出来了,并且值越大,缩放越厉害。

总之,问题解决了。

一周热门 更多>