[Opencv Study Notes]: traps for using reduce () and findcontours ()

Source: Internet
Author: User
Tags vc runtime

Before learning opencv, it started from the teacher's books and materials. Therefore, the serial port that has been used is all about C, but the more I use it, the more I feel that the C interface is not convenient, in addition, the use of C ++ should be a big trend, so we have to learn and use the corresponding C ++ interface, it is really annoying! It is a waste of time. The key is the use and requirements of some functions in the C ++ interface, which is different from that in C and used in the previous C method, sometimes there may be some inexplicable problems, so it is difficult to solve them!

The previous notes are recorded, but not in the document you read, or in the word. Now I plan to put these experiences and records here, I hope I can communicate with friends who pass by and improve together.

Today we will talk about the use traps of reduce () and findcontours.

First, introduce the system I used: vs2010 + opencv2.3.1. The single file type based on MFC is selected when the system is created. Because you may need to put the EXE file on a computer without opencv, you have selected static link DLL, the root cause for using the findcontours () function!

 

I. Use traps of findcontours ()

The first time you use the findcontours () function, the default method, refer to the Manual to define the type of input and output parameters, such as the method to call, the result is a complete findcontours () the following problem occurs when the block where the function is located:

When you press F5, the following error messages are displayed:
Error message for running EXE directly
I switched back to the sample study and compared it for half a day. No errors or omissions were found. Why did I turn to Baidu for help ?! Is it so unstable to upgrade such a commonly used function? No! Although
Bytes. Later find a simple version of the solution (http://giveuptech.com/post/opencv-findcontours-runtime-error-solution), said "modify the current program VC Runtime Library configuration, the problem is solved. The specific method is: Project-properties-configuration properties-C/C ++-code generation-Runtime Library, and change it to "multi-thread debugging (/MTD )"." But it still does not solve my problem! Fortunately, I have joined two super-large opencv groups, with many enthusiastic experts in it. This time, my problem is solved by the help of low-key de covers, geeks, and others. Thank you! When a DLL is statically linked to the C Runtime Library, a heap is created relative to the DLL ), if you use the shared method to link to the C Runtime Library, the heap memory of the application is used. In debug mode, _ crtisvalidheappointer () ensures that the input address is in the local heap memory. Therefore, there is a reason to believe that there may be a problem with static links. So, I will immediately try to select: Project -- properties -- configuration properties -- General -- Use of MFC --
Use MFC in shared DLLAt the same time, the project -- properties -- configuration properties -- C/C ++ -- code generation -- Runtime Library -- select
Multi-threaded DLL (/MD). Then, F5 runs. No exception exists! Excited ing ....... but as an easy-to-learn coders, of course, you still need to check its performance in the release scenario. The results, results, and results are also normal! Great !!! But its EXE file is much larger than that in debug mode. So far, the sensitive issue of findcontours () to the compilation environment has been solved, even though it has been busy for a long time, but still happy, haha, ^ _ ^

PS: I tried again and again to adjust the project configuration. Project -- properties -- configuration properties -- C/C ++ -- General -- multi-processor Compilation -- select
Yes (/MP), It could be much faster, huh, I used to waste I5 all the time!

 

2. Use traps of reduce.

Function prototype: void CV: reduce (inputarray _ SRC, outputarray _ DST, int dim, int op, int dtype =-1)

Use the reduce () function as the default value for dtype. If a vertex exception occurs, append try-catch and find that the input and output data types do not match, the reduce () function is used () for further analysis of the original code, first try to create the output as a variety of specified formats, no!
The reason is that the following statement is not well understood:

If (dtype <0)
Dtype = _ DST. fixedtype ()? _ DST. Type (): stype;

After a long time of surfing the Internet and surfing Q, I finally thought
Dtype specifies an initial value! Because the input data type is 8u, for the sum operation cv_reduce_sum, the output is 32 S, corresponding
Dtype = cv_32s. In this case, the output matrix only needs to be defined and no other operations are required. For example:

Mat matin1_imread(''lena.jpg ", 0 );

Mat matout;

Reduce (matin, matout, 1, cv_reduce_sum, cv_32s );

 

The following is the function reduce ()
Source code for easy comparison and learning.

 

 

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

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.