AppTurtle 发表于 2017-10-19 14:05:37

关于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;
   }
}

希望抛砖引玉

mcu5i51 发表于 2017-10-19 14:42:10

用数组方式操作指针可能会降低效率,直接指针自加要好些吧

tongdayusu 发表于 2017-10-19 15:35:08

#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 15:54:59

本帖最后由 shiva_shiva 于 2017-10-19 16:01 编辑

嵌入式优化和硬件关系比较大:
1、c语言编译局部优化开到最大;
2、改成汇编实现
3、关键代码特殊照顾(比如有些小arm是在flash执行,改到ram会提高速度,有些芯片放到内部sram比外部扩展的DRAM要快等)
4、...

AppTurtle 发表于 2017-10-19 16:18:43

tongdayusu 发表于 2017-10-19 15:35
#define   IMAGE_SIZE(640×480)
这个是啥意思?    x   是啥玩意儿?   *么?



应该是 #define   IMAGE_SIZE(640*480)输入法问题,不会每个循环都乘法的,这个是常数,编译器自动会算的

CPU 是 君正 X1000,LIUNX 系统,频率1G

not_at_all 发表于 2017-10-19 19:17:25

直接移位操作已经是最快的了

lcw_swust 发表于 2017-10-19 20:15:17

不知DMA能否实现,楼主可以研究一下。
比如把外设地址设为16位,内存地址设为8位。
如果不行,还有硬件的办法:
我在使用OV7670的时候,数据时钟接到TIM4_CH1,将它的捕获分频设置为2分频去触发DMA即可只采集Y信号。

wx85105157 发表于 2017-10-19 20:52:11

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);
   }
}

   测试下这个代码要多久呢?

canspider 发表于 2017-10-20 00:51:50

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遍,无分枝,不会打断流水线

AppTurtle 发表于 2017-10-20 11:42:25

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

sbusr 发表于 2017-10-20 23:43:31

请自行搜索 让你的程序飞起来 这篇文章,就是讲类似档主的应用的。rgb转灰度,查表处理,速度极快。

wuzhujian 发表于 2018-4-22 08:39:44

如果还不行,只能汇编优化了。
页: [1]
查看完整版本: 关于YUV422格式转灰度图像,算法优化问题