注册 登录
查看: 12091|回复: 116

[鹰眼] 鹰眼图像解压,转为 二维数组

  [复制链接]
发表于 2013-5-2 10:45:48 | 显示全部楼层 |阅读模式
一维数组和二维数组,在内存存储上都是一样的!!!

图像的存储图:(0在左上角)



假设 采集回来的图像地址是: img_bin_buff        (鹰眼是 8个像素一个字节)

你想解压到: uint8 img_buf[H][W];  这个 二维数组里。(当然也可以是一维数组: uint8 img_buf[H*W];  )
则需要调用这个函数:
  1. img_extract((uint8 *)img_buf,(uint8 *) img_bin_buff, H*W/8);        //解压为灰度图像,方便发送到上位机显


img_buf定义成二维数值时,与一维数组不同的是,这里img_buf 传递进去的时候多了强制类型转换 (uint8 *)!!


为了方便对比,我这里写一下定义成一维和二维数组的具体代码(自己根据需要是想一维还是二维,挑一个)
二维数组的方法:

  1. uint8 img_buf[H][W];   //二维数组
  2. img_extract((u8 *)img_buf,(uint8 *) img_bin_buff, H*W/8);        //解压为灰度图像,方便发送到上位机显

一维数组的方法:(例程默认是这样)

  1. uint8 img_buf[H*W];   //一维数组
  2. img_extract(img_buf,(u8 *) img_bin_buff, H*W/8);        //解压为灰度图像,方便发送到上位机显




img_extract 函数的具体代码如下:(不管是一维还是二维,都是用这个函数,不需要修改。最新版本已经集成了)
  1. //压缩二值化图像解压(空间 换 时间 解压)
  2. //srclen 是二值化图像的占用空间大小
  3. void img_extract(uint8 *dst, uint8 *src, uint32 srclen)
  4. {
  5.         uint8 colour[2] = {255, 0};   //0 和 1 分别对应的颜色
  6.                                                //注:山外的摄像头 0 表示 白色,1表示 黑色
  7.         uint8 tmpsrc;
  8.         while(srclen --)
  9.         {
  10.                 tmpsrc = *src++;
  11.                 *dst++ = colour[ (tmpsrc >> 7 ) & 0x01 ];
  12.                 *dst++ = colour[ (tmpsrc >> 6 ) & 0x01 ];
  13.                 *dst++ = colour[ (tmpsrc >> 5 ) & 0x01 ];
  14.                 *dst++ = colour[ (tmpsrc >> 4 ) & 0x01 ];
  15.                 *dst++ = colour[ (tmpsrc >> 3 ) & 0x01 ];
  16.                 *dst++ = colour[ (tmpsrc >> 2 ) & 0x01 ];
  17.                 *dst++ = colour[ (tmpsrc >> 1 ) & 0x01 ];
  18.                 *dst++ = colour[ (tmpsrc >> 0 ) & 0x01 ];
  19.          }
  20. }




关于解压数组:
  1. uint8 colour[2] = {255, 0};   //0 和 1 分别对应的颜色
  2.                                                //注:山外的摄像头 原始输出数据 0 表示 白色,1表示 黑色,解压后的数据由此数组的值决定

这里再补充说明:
解压前,0 表示 白色,1表示 黑色;
解压后,由这个数组来定。上述的代码是:
        colour[0]=255 ,即白色
        colour[1]=0    ,即黑色

换句话说,上面的解压代码,解压后,0表示黑色,255表示白色。 (之所以设置,是为了方便灰度显示)

如果对解压后的数据有其他的要求,自行修改数组内的值。

===================================================================================================
假如需要解压指定的行,方法也是类似,也是用 img_extract 函数,但不是全部解压,而是仅解压指定的行。
假如需要解压 第 3行 (从第一行数起),图像本身 60行,80列 。
就压缩后的图像而言,一行 共 80/8 =10 个字节。第 3 行,在压缩图像数组的偏移就是 (3-1)*10

那么:
img_extract(buff , img_bin_buff+(3-1)*10, 10);    把第3行,共10个字节,解压到 buff 数组上
如果需要解压指定多行呢? 用数组来存储要指定第几行咯,然后用变量来代替上面的 3 。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

本帖被以下淘专辑推荐:

回复

使用道具 举报

发表于 2014-11-24 17:30:02 | 显示全部楼层
请问我只需要把  uint8 img[CAMERA_W*CAMERA_H];  这个一维数组写成uint8 img[CAMERA_W][CAMERA_H]; 这样的二位数组就可以把采集的数据装
img[CAMERA_W][CAMERA_H]这个二维数组了是吗?????就这么简单吗???

回复 支持 2 反对 0

使用道具 举报

发表于 2014-4-30 17:07:42 | 显示全部楼层
山外メ雲ジ 发表于 2013-5-6 21:52
img_extract 的第一个参数是 u8 * 类型的啊!!而img_buf 是 u8 (*)[CAMERA_H][CAMERA_W] 类型 ,必须格式 ...

还是没看懂,求详解,
回复 支持 1 反对 1

使用道具 举报

发表于 2013-5-5 22:02:39 | 显示全部楼层
小蛇丸 发表于 2013-5-5 21:07
但是
定义了u8 img_buf[CAMERA_H][CAMERA_W];
调用 img_extract( img_buf ,img_bin_buff, CAMERA_SIZE);
...

你好,一维数组和二维数组在内存上都是相同的。
只不过编译器在编译的时候的处理不相同而已。

可以百度“二维数组”,还有建议学深入一点C语言,强制类型转换是很常见的
回复 支持 1 反对 0

使用道具 举报

发表于 2013-5-4 10:52:46 | 显示全部楼层
其实就是一个宏 ,你试试#define TransformArray(Ax,Ay)  ((img_buf[(Ax)/8+(Ay)*10]>>(7-(Ax)%8))&1)        //转换二维数组(注:只读数组)       //转换二维数组(注:只读数组)
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-5-4 11:02:43 | 显示全部楼层
过期Cookie 发表于 2013-5-4 10:52
其实就是一个宏 ,你试试#define TransformArray(Ax,Ay)  ((img_buf[(Ax)/8+(Ay)*10]>>(7-(Ax)%8))&1)      ...

我的只是把压缩的数据解压为非压缩模式

山外鹰眼默认是 一个字节 8个像素,需要解压才能用。

为什么for 里有那么多条语句?主要是 flash 空间或 时间,加快解压而已

一维数组和二维数组,本来内存空间就是相同的,用类型转换也行
回复 支持 反对

使用道具 举报

发表于 2013-5-4 11:46:59 | 显示全部楼层
支持一下
回复 支持 反对

使用道具 举报

发表于 2013-5-5 18:31:58 | 显示全部楼层
有山外库,进步神速
回复 支持 反对

使用道具 举报

发表于 2013-5-5 21:07:09 | 显示全部楼层
但是
定义了u8 img_buf[CAMERA_H][CAMERA_W];
调用 img_extract( img_buf ,img_bin_buff, CAMERA_SIZE);
会报错Error[Pe167]: argument of type "u8 (*)[80]" is incompatible with parameter of type "u8 *"
img_extract((u8 *) img_buf ,img_bin_buff, CAMERA_SIZE);        就不报错,但这强制转换实现了解压到二维数组么      
回复 支持 反对

使用道具 举报

发表于 2013-5-5 21:08:25 | 显示全部楼层
求解啊啊啊啊
回复 支持 反对

使用道具 举报

发表于 2013-5-5 21:18:50 | 显示全部楼层
小蛇丸 发表于 2013-5-5 21:07
但是
定义了u8 img_buf[CAMERA_H][CAMERA_W];
调用 img_extract( img_buf ,img_bin_buff, CAMERA_SIZE);
...

哥们,你没看清楚 版主的代码哦

他的是
img_extract(img_buf,(u8 *) img_bin_buff, H*W/8);
回复 支持 反对

使用道具 举报

发表于 2013-5-5 21:19:26 | 显示全部楼层
小蛇丸 发表于 2013-5-5 21:07
但是
定义了u8 img_buf[CAMERA_H][CAMERA_W];
调用 img_extract( img_buf ,img_bin_buff, CAMERA_SIZE);
...

你应该是:

img_extract( img_buf ,(u8 *)img_bin_buff, CAMERA_SIZE);
回复 支持 反对

使用道具 举报

发表于 2013-5-6 20:26:32 | 显示全部楼层
img_extract( img_buf ,(u8 *)img_bin_buff, CAMERA_SIZE);也报错,、
定义了u8 img_buf[CAMERA_H][CAMERA_W]好像是因为img_buf不是指针类型啊
这样img_extract((u8 *) img_buf ,img_bin_buff, CAMERA_SIZE);就不报错了
求大神指点~~~~
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-5-6 21:52:23 | 显示全部楼层
小蛇丸 发表于 2013-5-6 20:26
img_extract( img_buf ,(u8 *)img_bin_buff, CAMERA_SIZE);也报错,、
定义了u8 img_buf[CAMERA_H][CAMER ...

img_extract 的第一个参数是 u8 * 类型的啊!!而img_buf 是 u8 (*)[CAMERA_H][CAMERA_W] 类型 ,必须格式转换
回复 支持 反对

使用道具 举报

发表于 2013-5-7 11:20:32 | 显示全部楼层
嗯嗯,是的,谢谢
回复 支持 反对

使用道具 举报

发表于 2013-5-27 12:36:15 | 显示全部楼层
我测这个函数用了1.7ms
回复 支持 反对

使用道具 举报

发表于 2013-5-27 13:13:26 | 显示全部楼层
feeling_kill 发表于 2013-5-27 12:36
我测这个函数用了1.7ms

分辨率多大?
回复 支持 反对

使用道具 举报

发表于 2013-5-27 13:26:41 | 显示全部楼层
小学童鞋 发表于 2013-5-27 13:13
分辨率多大?

   160*120
回复 支持 反对

使用道具 举报

发表于 2013-5-27 13:52:59 | 显示全部楼层
feeling_kill 发表于 2013-5-27 13:26
160*120

有必要用 120 行那么多吗?我觉得 60行都够用了
回复 支持 反对

使用道具 举报

发表于 2014-1-13 22:07:10 | 显示全部楼层
强烈支持,非常感谢哥们
回复 支持 反对

使用道具 举报

发表于 2014-3-12 23:41:03 | 显示全部楼层
无线发送钱需要解压图像么  还是在调试器那边再解压
回复 支持 反对

使用道具 举报

发表于 2014-3-12 23:42:26 | 显示全部楼层
zlshang 发表于 2014-3-12 23:41
无线发送钱需要解压图像么  还是在调试器那边再解压

肯定是发送完再解压啊,无线发送速度比解压慢多了,所以发送的数据量越少越好
回复 支持 反对

使用道具 举报

发表于 2014-3-13 01:03:57 | 显示全部楼层
韦嘉淑 发表于 2014-3-12 23:42
肯定是发送完再解压啊,无线发送速度比解压慢多了,所以发送的数据量越少越好

可是在接收端的代码里面也没看见有解压的函数的  难道不解压也可以显示在LCD上么??
回复 支持 反对

使用道具 举报

发表于 2014-3-13 01:05:57 | 显示全部楼层
zlshang 发表于 2014-3-13 01:03
可是在接收端的代码里面也没看见有解压的函数的  难道不解压也可以显示在LCD上么??

山外哥有专门的函数来显示压缩的图像,直接调用就行,其实是解压和显示放在一起。
回复 支持 反对

使用道具 举报

发表于 2014-3-13 10:55:26 | 显示全部楼层
阙云亭 发表于 2014-3-13 01:05
山外哥有专门的函数来显示压缩的图像,直接调用就行,其实是解压和显示放在一起。

那我终于明白了    果然研究代码很透彻   
回复 支持 反对

使用道具 举报

发表于 2014-3-13 14:34:23 | 显示全部楼层
无线接收端 加入加压函数后LCD  照样可以显示出来  但是上位机显示不出来  是什么问题
/******************** 发送图像到上位机 ***********************/
        img_extract(img, imgbuff, CAMERA_SIZE);          //解压为灰度图像,方便发送到上位机显
       sendimg(img, CAMERA_W * CAMERA_H);                    //发送到上位机
回复 支持 反对

使用道具 举报

发表于 2014-3-13 14:36:23 | 显示全部楼层
zlshang 发表于 2014-3-13 14:34
无线接收端 加入加压函数后LCD  照样可以显示出来  但是上位机显示不出来  是什么问题
/**************** ...

发送图像到上位机,是通过串口的哦,有没有配置有串口?例如printf函数端口设置好了没有,波特率这类的。
回复 支持 反对

使用道具 举报

发表于 2014-3-13 16:16:08 | 显示全部楼层
阙云亭 发表于 2014-3-13 14:36
发送图像到上位机,是通过串口的哦,有没有配置有串口?例如printf函数端口设置好了没有,波特率这类的。

我没用无线的时候  可以同过上位机来显示   但是一加上无限的时候就显示不出来了  
#if 1
        /******************** 发送图像到上位机 ***********************/
        img_extract(img, imgbuff, CAMERA_SIZE);          //解压为灰度图像,方便发送到上位机显
       sendimg(img, CAMERA_W * CAMERA_H);                    //发送到上位机      
#endif
我只加入这句 在无限后
回复 支持 反对

使用道具 举报

发表于 2014-4-13 12:53:09 | 显示全部楼层
uint8 img1[CAMERA_W][CAMERA_H];
img_extract(img1, imgbuff, CAMERA_SIZE);          //解压为灰度图像,方便发送到上位机显
山外哥,为什么这样写会出现错误呢
回复 支持 反对

使用道具 举报

发表于 2014-4-18 14:51:54 | 显示全部楼层
山外メ雲ジ 发表于 2013-5-4 11:02
我的只是把压缩的数据解压为非压缩模式

山外鹰眼默认是 一个字节 8个像素,需要解压才能用。

是不是我做,分析赛道,也要解压,,,,
回复 支持 反对

使用道具 举报

发表于 2014-4-30 17:07:18 | 显示全部楼层
求指教
img_extract(img_buf,(u8 *) img_bin_buff, H*W/8);        //解压为灰度图像,方便发送到上位机显
与img_extract(img, imgbuff,CAMERA_SIZE);
不同,
回复 支持 反对

使用道具 举报

发表于 2014-4-30 17:21:28 | 显示全部楼层
img_extract(img_buf,(uint8 *)imgbuff, CAMERA_H*CAMERA_W/8);
void img_extract(uint8 *dst, uint8 *src, uint32 srclen)


Error[Pe167]: argument of type "uint8 (*)[80]" is incompatible with parameter of type "uint8 *" C:\Documents and Settings\来宾账户\桌面\DMA_鹰眼摄像头OV7725串口显示\App\main.c 54
Error[Pe247]: function "img_extract" has already been defined (at line 87) C:\Documents and Settings\来宾账户\桌面\DMA_鹰眼摄像头OV7725串口显示\App\main.c 108
Error while running C/C++ Compiler
不懂了,,求解
回复 支持 反对

使用道具 举报

发表于 2014-5-1 20:27:27 | 显示全部楼层
经过串口打印,发现输出的都是255,
为什么,求赐教
强烈支持,非常感谢哥们
回复 支持 反对

使用道具 举报

发表于 2014-5-4 16:32:13 | 显示全部楼层
我的输出也是255,求山外哥指导指导。
比如说我定义一个数组uint8 IMGERZHI[CAMERA_H][CAMERA_W]
存储接受图像的数组  uint8 imgbuff[CAMERA_SIZE]
然后img_extract(IMGERZHI,imgbuff, CAMERA_SIZE)报错
img_extract((uint8 *)IMGERZHI,imgbuff, CAMERA_SIZE)
这样就不报错了
但是输出不是0就是255     
山外哥教教我怎么修改。。。。。
回复 支持 反对

使用道具 举报

发表于 2014-11-24 17:31:45 | 显示全部楼层
CAN 发表于 2014-11-24 17:30
请问我只需要把  uint8 img[CAMERA_W*CAMERA_H];  这个一维数组写成uint8 img[CAMERA_W][CAMERA_H]; 这样的 ...

就这么简单,调用时记得类型转换就好,楼主帖有说。
来自安卓客户端来自安卓客户端
回复 支持 反对

使用道具 举报

发表于 2014-11-24 17:40:02 | 显示全部楼层
微粒子 发表于 2014-11-24 17:31
就这么简单,调用时记得类型转换就好,楼主帖有说。

好的,酷酷的
回复 支持 反对

使用道具 举报

发表于 2014-12-5 23:50:18 | 显示全部楼层
destiny 发表于 2014-5-4 16:32
我的输出也是255,求山外哥指导指导。
比如说我定义一个数组uint8 IMGERZHI[CAMERA_H][CAMERA_W]
存储接 ...

在解压的时候,  经过    uint8 colour[2] = {255, 0}; //0 和 1 分别对应的颜色   ,   把  黑和白  改成了这样, 为了,在做提取中线的时候,阙值吧,不知道,你现在还会看到吗?  我说的对吧
回复 支持 反对

使用道具 举报

发表于 2015-1-23 18:39:03 | 显示全部楼层
要记得用YY调试助手  资料贴里有的
回复 支持 反对

使用道具 举报

发表于 2015-3-11 14:16:53 | 显示全部楼层
如果我要提取黑线可以直接用 u8 img_buf[H][W];   //二维数组??
比如  for(i=35;i>25;i--)       //只扫描近处10行的图像数据
        {
            for(j=40;j>0;j--)  //从中间向左边扫描,寻找黑点
            {
              if((img[i][j]+img[i][j-1]+img[i][j-2])>2)
   

这样可以吗??
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-3-11 14:28:43 | 显示全部楼层
涛家柒柒 发表于 2015-3-11 14:16
如果我要提取黑线可以直接用 u8 img_buf[H][W];   //二维数组??
比如  for(i=35;i>25;i--)       //只扫 ...

是的
来自安卓客户端来自安卓客户端
回复 支持 反对

使用道具 举报

发表于 2015-3-11 14:38:09 | 显示全部楼层

还有问题山外哥,我用把255改成1吗??

回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-3-11 16:51:04 | 显示全部楼层
涛家柒柒 发表于 2015-3-11 14:38
还有问题山外哥,我用把255改成1吗??

自己的算法要求决定的。

我们是为了方便灰度显示而设置成255
来自安卓客户端来自安卓客户端
回复 支持 反对

使用道具 举报

发表于 2015-3-11 18:20:20 | 显示全部楼层
山外哥,能不能发一份oled显示赛道的程序,我调了一天都不行- -附上我的代码传进来的是imgbuff的地址
  1. void Eighty_Sixty_Display(uint8 *img)
  2. {
  3.   //uint8 *tempimg = (uint8 *)img;
  4.    uint8 tempimg[80][60];
  5.    img_extract((uint8 *)img,(uint8 *) tempimg, 80*60/8);        //解压为灰度图像,方便发送到上位机显
  6.    uint8 i=0, j=0;
  7.    for(i=0; i<=6; i++)//7次循环完成56*80的图像区
  8.    {
  9.   LCD_Set_Pos(0,i);
  10.   for(j=0; j<80; j++)//一次循环完成一个8*60的图像去
  11.   {
  12.             uint8 x = tempimg[i*8][j]
  13.                     +tempimg[i*8+1][j]*2
  14.                             +tempimg[i*8+2][j]*4
  15.                                     +tempimg[i*8+3][j]*8
  16.                                             +tempimg[i*8+4][j]*16
  17.                                                     +tempimg[i*8+5][j]*32
  18.                                                             +tempimg[i*8+6][j]*64
  19.                                                                     +tempimg[i*8+7][j]*128;//将竖着的8个像素合并成一个字节
  20.             LCD_WrDat(x);
  21.   }
  22.     }
  23. //上面的一段程序完成了56行像素的显示,同理,下面显示剩下4行
  24.     LCD_Set_Pos(0,7);
  25.     for(j=0; j<80; j++)
  26.     {
  27.   uint8 x = tempimg[56][j]
  28.      +tempimg[57][j]*2
  29.       +tempimg[58][j]*4
  30.         +tempimg[59][j]*8;
  31.   LCD_WrDat(x);
  32.     }
  33. }

回复 支持 反对

使用道具 举报

发表于 2015-3-22 23:14:37 | 显示全部楼层
二维数组存在哪?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-3-23 14:18:49 | 显示全部楼层
关关关 发表于 2015-3-22 23:14
二维数组存在哪?

自己定位的
来自安卓客户端来自安卓客户端
回复 支持 反对

使用道具 举报

发表于 2015-3-23 15:11:06 | 显示全部楼层
山外メ雲ジ 发表于 2015-3-23 14:18
自己定位的

OK
来自安卓客户端来自安卓客户端
回复 支持 反对

使用道具 举报

发表于 2015-3-24 23:06:31 | 显示全部楼层

搞定,
回复 支持 反对

使用道具 举报

发表于 2015-3-25 23:22:55 | 显示全部楼层
用山外调试器和YY,转过去的都是一维数组
回复 支持 反对

使用道具 举报

发表于 2015-3-25 23:30:53 | 显示全部楼层
关关关 发表于 1427296975
用山外调试器和YY,转过去的都是一维数组
一维二维都是可以通过类型转换来转的
来自PC客户端 来自PC客户端
回复 支持 反对

使用道具 举报

发表于 2015-3-26 00:47:10 | 显示全部楼层
仰逸致 发表于 2015-3-25 23:30
一维二维都是可以通过类型转换来转的

嗯发送二维是不是也行
来自安卓客户端来自安卓客户端
回复 支持 反对

使用道具 举报

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

本版积分规则

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