[应用相关] stm32f7系列可以移植opencv 做视频图像处理吗?

[复制链接]
9309|27
 楼主| dingbo95 发表于 2018-11-29 12:43 | 显示全部楼层 |阅读模式
 楼主| dingbo95 发表于 2018-11-29 12:44 | 显示全部楼层
opencv本身移植到767上的可行性可能不大,opencv不提供stm32的平台,但支持Arm、Android    有没有做过的
 楼主| dingbo95 发表于 2018-11-29 12:46 | 显示全部楼层
opencv算法简化移植
本文以简化opencv中的库函数laplacian函数为例,来分析如何在不知道算法原理的情况下,仅仅通过对数据流进行跟踪,来实现算法的移植。
 楼主| dingbo95 发表于 2018-11-29 12:47 | 显示全部楼层
这种用途在实际应用中是十分常见的,很多情况是,就算我们知道了算法的原理,用自己的方法实现起来与opencv原版的函数也有不小的差距。
 楼主| dingbo95 发表于 2018-11-29 12:47 | 显示全部楼层
而opencv原版的代码往往错综复杂,代码的安全性以及执行效率都是非常高的,在分析代码时,往往不能理解每一句的含义。
 楼主| dingbo95 发表于 2018-11-29 12:48 | 显示全部楼层
流程分析
采用调试的方式对算法流程进行跟踪。
一般的算法步骤分为 初始化,执行两步;
在初始化步骤中,需要完成的任务:
1.根据函数的输入参数判断执行不同的算法;
2.根据函数的输入参数初始化局部变量;
3.创建对象;
 楼主| dingbo95 发表于 2018-11-29 12:48 | 显示全部楼层
在执行步骤中完成对输入数据的处理。

算法的初始化步骤很关键,然而在通常的应用中,我们的输入参数只有一种情况,于是可以将初始化步骤中的很多判断省略,只取其中的一种情况。
 楼主| dingbo95 发表于 2018-11-29 12:55 | 显示全部楼层
核心定位

在了解算法的大致执行流程之后,采用的方法是逆向分析,从算法的执行开始入手,分析算法的执行需要哪些条件,哪些参数,各个参数又是怎么来的。
 楼主| dingbo95 发表于 2018-11-29 12:57 | 显示全部楼层
核心执行代码:
  1. void operator()(const uchar** src, uchar* dst, int dststep, int count, int width, int cn)
  2.     {
  3.         KT _delta = delta;
  4.         const Point* pt = &coords[0];
  5.         const KT* kf = (const KT*)&coeffs[0];
  6.         const ST** kp = (const ST**)&ptrs[0];
  7.         int i, k, nz = (int)coords.size();
  8.         CastOp castOp = castOp0;

  9.         width *= cn;
  10.         for( ; count > 0; count--, dst += dststep, src++ )
  11.         {
  12.             DT* D = (DT*)dst;

  13.             for( k = 0; k < nz; k++ )
  14.                 kp[k] = (const ST*)src[pt[k].y] + pt[k].x*cn;

  15.             i = vecOp((const uchar**)kp, dst, width);
  16.             #if CV_ENABLE_UNROLLED
  17.             for( ; i <= width - 4; i += 4 )
  18.             {
  19.                 KT s0 = _delta, s1 = _delta, s2 = _delta, s3 = _delta;

  20.                 for( k = 0; k < nz; k++ )
  21.                 {
  22.                     const ST* sptr = kp[k] + i;
  23.                     KT f = kf[k];
  24.                     s0 += f*sptr[0];
  25.                     s1 += f*sptr[1];
  26.                     s2 += f*sptr[2];
  27.                     s3 += f*sptr[3];
  28.                 }

  29.                 D[i] = castOp(s0); D[i+1] = castOp(s1);
  30.                 D[i+2] = castOp(s2); D[i+3] = castOp(s3);
  31.             }
  32.             #endif
  33.             for( ; i < width; i++ )
  34.             {
  35.                 KT s0 = _delta;
  36.                 for( k = 0; k < nz; k++ )
  37.                     s0 += kf[k]*kp[k][i];
  38.                 D[i] = castOp(s0);
  39.             }
  40.         }
  41.     }

  42.     vector<Point> coords;
  43.     vector<uchar> coeffs;
  44.     vector<uchar*> ptrs;
  45.     KT delta;
  46.     CastOp castOp0;
  47.     VecOp vecOp;
  48. };



 楼主| dingbo95 发表于 2018-11-29 15:24 | 显示全部楼层
在opencv库函数中使用了大量的模板,在移植过程中要替换为具体的数据类型。
回到上一步中:
 楼主| dingbo95 发表于 2018-11-29 15:25 | 显示全部楼层
模板函数的调用为:
  1. if( sdepth == CV_8U && ddepth == CV_32F )
  2.         return Ptr<BaseFilter>(new Filter2D<uchar,
  3.             Cast<float, float>, FilterNoVec>(kernel, anchor, delta));


 楼主| dingbo95 发表于 2018-11-29 15:25 | 显示全部楼层
比对函数的声明:

template<typename ST, class CastOp, class VecOp> struct Filter2D : public BaseFilter
 楼主| dingbo95 发表于 2018-11-29 15:26 | 显示全部楼层
为了能够运行执行函数,需要做哪些准备:
1.输入参数的准备。
2.全局变量的初始化。
3.子函数的实现。
 楼主| dingbo95 发表于 2018-11-29 15:26 | 显示全部楼层
输入参数准备:
uchar ** src_data = new uchar*[yuv_src->height];
    for(int i=0; i<yuv_src->height; i++)
    {
        src_data[i] = (uchar *)yuv_src->vir_addr[0] + i*yuv_src->stride[0];
    }
 楼主| dingbo95 发表于 2018-11-29 15:27 | 显示全部楼层
uchar *dst 为变换后的数据。
dst_data = (uchar *)yuv_dst->vir_addr[0];
dststep为图像内存区域的字节宽度 width*4
 楼主| dingbo95 发表于 2018-11-29 15:27 | 显示全部楼层
全局变量的初始化

coords和coeffs在preprocess2DKernel( _kernel, coords, coeffs );中进行了初始化。
ptrs.resize(coords.size());     //ptr初始化
 楼主| dingbo95 发表于 2018-11-29 15:27 | 显示全部楼层
数据比对

很多时候,虽然运行不会报错,但是得到的结果却不一样,这是因为某些参数的初始化过程中出现问题,需要比对运行数据,找出导致数据不一样的地方。
1.变量比对
运行到同一状态时的所有变量是一致的。
2.内存比对
同一指针指向的内存的数据应是一致的。在vs2010中查看指针指向内存的方法为调试->窗口->内存。
 楼主| dingbo95 发表于 2018-11-29 15:28 | 显示全部楼层
关于深层的OpenCV 还要更多的**来描述
yklstudent 发表于 2018-11-29 18:33 | 显示全部楼层
楼主实现了上传工程啊
stm32jy 发表于 2018-11-29 19:27 | 显示全部楼层
感觉很难啊,我是搞不了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

52

主题

1197

帖子

5

粉丝
快速回复 在线客服 返回列表 返回顶部