之前学习OpenCV时是从于老师的书本教材开始的,所以一直使用的接串口就全是其于C的,但越使用越觉得C接口不其方便,再者使用C++应当是大的趋势所向,所以,又只好对相应的C++接口进行学习和使用,真心烦燥! 浪费了一些时间不说,关键是c++接口中的一些函数的使用和要求,与C的有些出入,按之前C的方法去使用,有时会出些莫名的问题,解决起来老费劲!
之前的笔记也记,只不过是,不是记在所看文档上,就是记录在Word里,现在起打算把这些经验和记录放在这里,希望能与路过的朋友多多交流,共同提高,呵呵。
今天就讲讲reduce() 和 findContours()的使用陷阱。
首先介绍一下我所用的系统情况:VS2010+OpenCV2.3.1。在建立系统时选择了基于MFC的单文档类型,由于可能要将exe放到没装OpenCV的电脑上运行,选择了静态链接DLL,而这,竟然对使用函数findContours()埋下的祸根!
一,findContours()的使用陷阱
第一次使用函数findContours(),默认的方法,参照手册定义输入输出参数的类型,如法炮制地进行调用,结果竟然一运行完findContours()函数所在的程序块时就出现了如下问题:
http://code.opencv.org/issues里面有相应的解决办法,但都写得比较简略和抽象,估计是因为全是大牛,大体都是些编译器、动态库等方面的参数调整,俺等码农看了之后依然无从下手。 后来找到一中文简易版本的解决方法(http://giveuptech.com/post/opencv-findcontours-runtime-error-solution),说是“修改当前程序的vc运行库配置,问题解决。具体方法是:项目-属性-配置属性-C/C++-代码生成-运行库,将其改为“多线程调试(/MTd)”。”但仍然没有解决我的问题!
在共享DLL中使用MFC ;同时,项目--属性--配置属性--C/C++--代码生成--运行库--选择
多线程DLL(/MD)。
PS:再反复调整项目配置的时候顺手试了一下,项目--属性--配置属性--C/C++--常规--多处理器编译--选择
是(/MP),果然能快不少,呵呵,原来我之前一直在无形地浪费着i5!
二,reduce() 的使用陷阱。
函数原型:void cv::reduce(InputArray _src, OutputArray _dst, int dim, int op, int dtype=-1)
对dtype采用默认值方式使用函数reduce(),出现了点异常问题,然后追加try-catch,发现输入输出的数据类型不匹配,于是就结合着reduce() 原代码做进一步分析,先是尝试着将输出创建为各种指定的格式,不行!
原因在于对下面这条语句没有理解好:
if( dtype < 0 )
dtype = _dst.fixedType() ? _dst.type() : stype;
上网、上Q,折腾许久,终于想到了要把
dtype指定一个初值! 由于输入的数据类型是8U,对于求和操作CV_REDUCE_SUM,那么输出是32S就可以,对应的
dtype=CV_32S 就行,此时输出的矩阵也就只需要定义一下就行,不必再进行其它操作。例如:
Mat matIn=imread(''lena.jpg",0);
Mat matOut;
reduce(matIn, matOut, 1, CV_REDUCE_SUM, CV_32S);
以下为函数reduce()
源码,方便对照学习。
void cv::reduce(InputArray _src, OutputArray _dst, int dim, int op, int dtype) { Mat src = _src.getMat(); CV_Assert( src.dims <= 2 ); int op0 = op; int stype = src.type(), sdepth = src.depth(), cn = src.channels(); if( dtype < 0 ) dtype = _dst.fixedType() ? _dst.type() : stype; int ddepth = CV_MAT_DEPTH(dtype); _dst.create(dim == 0 ? 1 : src.rows, dim == 0 ? src.cols : 1, CV_MAKETYPE(dtype >= 0 ? dtype : stype, cn)); Mat dst = _dst.getMat(), temp = dst; CV_Assert( op == CV_REDUCE_SUM || op == CV_REDUCE_MAX || op == CV_REDUCE_MIN || op == CV_REDUCE_AVG ); CV_Assert( src.channels() == dst.channels() ); if( op == CV_REDUCE_AVG ) { op = CV_REDUCE_SUM; if( sdepth < CV_32S && ddepth < CV_32S ) { temp.create(dst.rows, dst.cols, CV_32SC(cn)); ddepth = CV_32S; } } ReduceFunc func = 0; if( dim == 0 ) { if( op == CV_REDUCE_SUM ) { if(sdepth == CV_8U && ddepth == CV_32S) func = reduceR_<uchar,int,OpAdd<int> >; else if(sdepth == CV_8U && ddepth == CV_32F) func = reduceR_<uchar,float,OpAdd<int> >; else if(sdepth == CV_8U && ddepth == CV_64F) func = reduceR_<uchar,double,OpAdd<int> >; else if(sdepth == CV_16U && ddepth == CV_32F) func = reduceR_<ushort,float,OpAdd<float> >; else if(sdepth == CV_16U && ddepth == CV_64F) func = reduceR_<ushort,double,OpAdd<double> >; else if(sdepth == CV_16S && ddepth == CV_32F) func = reduceR_<short,float,OpAdd<float> >; else if(sdepth == CV_16S && ddepth == CV_64F) func = reduceR_<short,double,OpAdd<double> >; else if(sdepth == CV_32F && ddepth == CV_32F) func = reduceR_<float,float,OpAdd<float> >; else if(sdepth == CV_32F && ddepth == CV_64F) func = reduceR_<float,double,OpAdd<double> >; else if(sdepth == CV_64F && ddepth == CV_64F) func = reduceR_<double,double,OpAdd<double> >; } else if(op == CV_REDUCE_MAX) { if(sdepth == CV_8U && ddepth == CV_8U) func = reduceR_<uchar, uchar, OpMax<uchar> >; else if(sdepth == CV_16U && ddepth == CV_16U) func = reduceR_<ushort, ushort, OpMax<ushort> >; else if(sdepth == CV_16S && ddepth == CV_16S) func = reduceR_<short, short, OpMax<short> >; else if(sdepth == CV_32F && ddepth == CV_32F) func = reduceR_<float, float, OpMax<float> >; else if(sdepth == CV_64F && ddepth == CV_64F) func = reduceR_<double, double, OpMax<double> >; } else if(op == CV_REDUCE_MIN) { if(sdepth == CV_8U && ddepth == CV_8U) func = reduceR_<uchar, uchar, OpMin<uchar> >; else if(sdepth == CV_16U && ddepth == CV_16U) func = reduceR_<ushort, ushort, OpMin<ushort> >; else if(sdepth == CV_16S && ddepth == CV_16S) func = reduceR_<short, short, OpMin<short> >; else if(sdepth == CV_32F && ddepth == CV_32F) func = reduceR_<float, float, OpMin<float> >; else if(sdepth == CV_64F && ddepth == CV_64F) func = reduceR_<double, double, OpMin<double> >; } } else { if(op == CV_REDUCE_SUM) { if(sdepth == CV_8U && ddepth == CV_32S) func = reduceC_<uchar,int,OpAdd<int> >; else if(sdepth == CV_8U && ddepth == CV_32F) func = reduceC_<uchar,float,OpAdd<int> >; else if(sdepth == CV_8U && ddepth == CV_64F) func = reduceC_<uchar,double,OpAdd<int> >; else if(sdepth == CV_16U && ddepth == CV_32F) func = reduceC_<ushort,float,OpAdd<float> >; else if(sdepth == CV_16U && ddepth == CV_64F) func = reduceC_<ushort,double,OpAdd<double> >; else if(sdepth == CV_16S && ddepth == CV_32F) func = reduceC_<short,float,OpAdd<float> >; else if(sdepth == CV_16S && ddepth == CV_64F) func = reduceC_<short,double,OpAdd<double> >; else if(sdepth == CV_32F && ddepth == CV_32F) func = reduceC_<float,float,OpAdd<float> >; else if(sdepth == CV_32F && ddepth == CV_64F) func = reduceC_<float,double,OpAdd<double> >; else if(sdepth == CV_64F && ddepth == CV_64F) func = reduceC_<double,double,OpAdd<double> >; } else if(op == CV_REDUCE_MAX) { if(sdepth == CV_8U && ddepth == CV_8U) func = reduceC_<uchar, uchar, OpMax<uchar> >; else if(sdepth == CV_16U && ddepth == CV_16U) func = reduceC_<ushort, ushort, OpMax<ushort> >; else if(sdepth == CV_16S && ddepth == CV_16S) func = reduceC_<short, short, OpMax<short> >; else if(sdepth == CV_32F && ddepth == CV_32F) func = reduceC_<float, float, OpMax<float> >; else if(sdepth == CV_64F && ddepth == CV_64F) func = reduceC_<double, double, OpMax<double> >; } else if(op == CV_REDUCE_MIN) { if(sdepth == CV_8U && ddepth == CV_8U) func = reduceC_<uchar, uchar, OpMin<uchar> >; else if(sdepth == CV_16U && ddepth == CV_16U) func = reduceC_<ushort, ushort, OpMin<ushort> >; else if(sdepth == CV_16S && ddepth == CV_16S) func = reduceC_<short, short, OpMin<short> >; else if(sdepth == CV_32F && ddepth == CV_32F) func = reduceC_<float, float, OpMin<float> >; else if(sdepth == CV_64F && ddepth == CV_64F) func = reduceC_<double, double, OpMin<double> >; } } if( !func ) CV_Error( CV_StsUnsupportedFormat, "Unsupported combination of input and output array formats" ); func( src, temp ); if( op0 == CV_REDUCE_AVG ) temp.convertTo(dst, dst.type(), 1./(dim == 0 ? src.rows : src.cols)); }
相关推荐
8个JS的reduce使用实例和reduce操作方式 reduce方法是一个数组的迭代方法,和map、filter不同,reduce方法可缓存一个变量,迭代时我们可以操作这个变量,然后返回它。 这是我大白话的解释,可能还是不容易理解,...
《Ranking and Semi-supervised Classification on Large Scale Graphs Using Map-Reduce》原文及译文
使用Spark算子map、reduce相结合求平均值
reduce()函数也是Python内置的一个高阶函数。reduce()函数接收的参数和 map()类似,一个函数 f,一个list,但行为和 map()不同,今天我们就来详细探讨下
Hadoop Map-Reduce数据分析
为啥要把es6 中 reduce 单独拿出来说呢,因为这个功能实在太骚,值得如此。 reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。reduce() 方法接受四个参数:初始值...
目录 fold(reduce)使用for...of使用while循环更像fold的实现unfold数组实现生成器实现unfold实现总结 fold(reduce) 使用for...of使用while循环更像fold的实现 使用for...of 使用while循环 更像fold的...
下载后可以直接放到js文件中使用和输出。reduce详解和多种用法,包括求和、代替reverse 降序、代替map和filter、代替some和every、数组分割、数据过滤、数组去重、数组最大值和最小值、数组成员个数统计
Python 函数式编程和高阶函数 03高阶函数reduce的使用.mp4
Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以...
近期发布的最新版,由于官网集成的绘图程序过旧更新了当前的最新版并且集成了VS编译的版本(非mingw编译).本程序是绿色软件自解压就可以...解压后文件夹下的'\reduce\bin\winreduce.exe'就是程序文件,打开该文件即可使用
js代码-reduce的使用场景
Map-Reduce原理体系架构和工作机制,eclipse与Hadoop集群连接
google三大核心技术之一,map reduce的论文
在使用tensorflow时常常会使用到tf.reduce_*这类的函数,在此对一些常见的函数进行汇总 1.tf.reduce_sum tf.reduce_sum(input_tensor , axis = None , keep_dims = False , name = None , reduction_indices = ...
人脸识别,车辆识别,一人一档,一车一档 hadoop map reduce hbase
cuda cuda_使用cuda并行加速实现之reduce
Map/Reduce介绍。一些基本基础介绍。
Map reduce的执行原理。MapReduce是一种分布式计算模型,是Google提出的,主要用于搜索领域,解决海量数据的计算问题。