关于YUV422格式转灰度图像,算法优化问题
YUV422格式 ,Y分量占一个字节,UV合起来占一个字节,现在只提取Y分量,相当于只需要数组中的偶数字节,图像大小是640×480,如果按单字节提取1帧,大概40ms,如果按4字节处理,大约20ms,请教坛里大侠,有没有更好的方法。
#define IMAGE_SIZE(640×480)
//按4字节处理,大概20ms
void copy_image_data(uint32_t* src, uint32_t* dst)
{
uint32_t s1, s2, d1;
for (int i = 0; i < IMAGE_SIZE*2; i += 16) {
s1 = *src++;
s2 = *src++;
d1 = s1 & 0x000000ff;
d1 |= (s1 >> 8) & 0x0000ff00;
d1 |= (s2 << 16) & 0x00ff0000;
d1 |= (s2 << 8) & 0xff000000;
*dst++ = d1;
}
}
//按单字节处理,大概40ms
void copy_image_data(uint8_t* src, uint8_t* dst)
{
for (int i = 0, j = 0; j < IMAGE_SIZE; i += 2, j += 1) {
dst = src;
}
}
希望抛砖引玉 用数组方式操作指针可能会降低效率,直接指针自加要好些吧 #define IMAGE_SIZE(640×480)
这个是啥意思? x 是啥玩意儿? *么?
for (int i = 0; i < IMAGE_SIZE*2; i += 16)
for (int i = 0, j = 0; j < IMAGE_SIZE; i += 2, j += 1)
这两个,没个循环都做一次乘法么?这开销可真是不小啊。不知道啥CPU 。
本帖最后由 shiva_shiva 于 2017-10-19 16:01 编辑
嵌入式优化和硬件关系比较大:
1、c语言编译局部优化开到最大;
2、改成汇编实现
3、关键代码特殊照顾(比如有些小arm是在flash执行,改到ram会提高速度,有些芯片放到内部sram比外部扩展的DRAM要快等)
4、... tongdayusu 发表于 2017-10-19 15:35
#define IMAGE_SIZE(640×480)
这个是啥意思? x 是啥玩意儿? *么?
应该是 #define IMAGE_SIZE(640*480)输入法问题,不会每个循环都乘法的,这个是常数,编译器自动会算的
CPU 是 君正 X1000,LIUNX 系统,频率1G 直接移位操作已经是最快的了 不知DMA能否实现,楼主可以研究一下。
比如把外设地址设为16位,内存地址设为8位。
如果不行,还有硬件的办法:
我在使用OV7670的时候,数据时钟接到TIM4_CH1,将它的捕获分频设置为2分频去触发DMA即可只采集Y信号。
void copy_image_data(uint16_t* src, uint8_t* dst)
{
for (int i = 0;i < IMAGE_SIZE) {
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
dst = (uint8_t)(src);
}
}
测试下这个代码要多久呢? wx85105157 发表于 2017-10-19 20:52
void copy_image_data(uint16_t* src, uint8_t* dst)
{
for (int i = 0;i < IMAGE_SIZE) {
直接*dst++=*src++;
复制image size遍,无分枝,不会打断流水线 wx85105157 发表于 2017-10-19 20:52
void copy_image_data(uint16_t* src, uint8_t* dst)
{
for (int i = 0;i < IMAGE_SIZE) {
这个 40ms
*dst++=*src++; 的方式 22ms 请自行搜索 让你的程序飞起来 这篇文章,就是讲类似档主的应用的。rgb转灰度,查表处理,速度极快。 如果还不行,只能汇编优化了。
页:
[1]