| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414 |
- // This file is part of OpenCV project.
- // It is subject to the license terms in the LICENSE file found in the top-level directory
- // of this distribution and at http://opencv.org/license.html.
- #include "test_precomp.hpp"
- #include "ref_reduce_arg.impl.hpp"
- #include <algorithm>
- namespace opencv_test { namespace {
- const int ARITHM_NTESTS = 1000;
- const int ARITHM_RNG_SEED = -1;
- const int ARITHM_MAX_CHANNELS = 4;
- const int ARITHM_MAX_NDIMS = 4;
- const int ARITHM_MAX_SIZE_LOG = 10;
- struct BaseElemWiseOp
- {
- enum
- {
- FIX_ALPHA=1, FIX_BETA=2, FIX_GAMMA=4, REAL_GAMMA=8,
- SUPPORT_MASK=16, SCALAR_OUTPUT=32, SUPPORT_MULTICHANNELMASK=64,
- MIXED_TYPE=128
- };
- BaseElemWiseOp(int _ninputs, int _flags, double _alpha, double _beta,
- Scalar _gamma=Scalar::all(0), int _context=1)
- : ninputs(_ninputs), flags(_flags), alpha(_alpha), beta(_beta), gamma(_gamma), context(_context) {}
- BaseElemWiseOp() { flags = 0; alpha = beta = 0; gamma = Scalar::all(0); ninputs = 0; context = 1; }
- virtual ~BaseElemWiseOp() {}
- virtual void op(const vector<Mat>&, Mat&, const Mat&) {}
- virtual void refop(const vector<Mat>&, Mat&, const Mat&) {}
- virtual void getValueRange(int depth, double& minval, double& maxval)
- {
- minval = depth < CV_32S ? cvtest::getMinVal(depth) : depth == CV_32S ? -1000000 : -1000.;
- maxval = depth < CV_32S ? cvtest::getMaxVal(depth) : depth == CV_32S ? 1000000 : 1000.;
- }
- virtual void getRandomSize(RNG& rng, vector<int>& size)
- {
- cvtest::randomSize(rng, 2, ARITHM_MAX_NDIMS, ARITHM_MAX_SIZE_LOG, size);
- }
- virtual int getRandomType(RNG& rng)
- {
- return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL_BUT_8S, 1,
- ninputs > 1 ? ARITHM_MAX_CHANNELS : 4);
- }
- virtual double getMaxErr(int depth) { return depth < CV_32F ? 1 : depth == CV_32F ? 1e-5 : 1e-12; }
- virtual void generateScalars(int depth, RNG& rng)
- {
- const double m = 3.;
- if( !(flags & FIX_ALPHA) )
- {
- alpha = exp(rng.uniform(-0.5, 0.1)*m*2*CV_LOG2);
- alpha *= rng.uniform(0, 2) ? 1 : -1;
- }
- if( !(flags & FIX_BETA) )
- {
- beta = exp(rng.uniform(-0.5, 0.1)*m*2*CV_LOG2);
- beta *= rng.uniform(0, 2) ? 1 : -1;
- }
- if( !(flags & FIX_GAMMA) )
- {
- for( int i = 0; i < 4; i++ )
- {
- gamma[i] = exp(rng.uniform(-1, 6)*m*CV_LOG2);
- gamma[i] *= rng.uniform(0, 2) ? 1 : -1;
- }
- if( flags & REAL_GAMMA )
- gamma = Scalar::all(gamma[0]);
- }
- if( depth == CV_32F )
- {
- Mat fl, db;
- db = Mat(1, 1, CV_64F, &alpha);
- db.convertTo(fl, CV_32F);
- fl.convertTo(db, CV_64F);
- db = Mat(1, 1, CV_64F, &beta);
- db.convertTo(fl, CV_32F);
- fl.convertTo(db, CV_64F);
- db = Mat(1, 4, CV_64F, &gamma[0]);
- db.convertTo(fl, CV_32F);
- fl.convertTo(db, CV_64F);
- }
- }
- int ninputs;
- int flags;
- double alpha;
- double beta;
- Scalar gamma;
- int context;
- };
- struct BaseAddOp : public BaseElemWiseOp
- {
- BaseAddOp(int _ninputs, int _flags, double _alpha, double _beta, Scalar _gamma=Scalar::all(0))
- : BaseElemWiseOp(_ninputs, _flags, _alpha, _beta, _gamma) {}
- void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
- {
- int dstType = (flags & MIXED_TYPE) ? dst.type() : src[0].type();
- if( !mask.empty() )
- {
- Mat temp;
- cvtest::add(src[0], alpha, src.size() > 1 ? src[1] : Mat(), beta, gamma, temp, dstType);
- cvtest::copy(temp, dst, mask);
- }
- else
- cvtest::add(src[0], alpha, src.size() > 1 ? src[1] : Mat(), beta, gamma, dst, dstType);
- }
- };
- struct AddOp : public BaseAddOp
- {
- AddOp() : BaseAddOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK, 1, 1, Scalar::all(0)) {}
- void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
- {
- int dtype = (flags & MIXED_TYPE) ? dst.type() : -1;
- cv::add(src[0], src[1], dst, mask, dtype);
- }
- };
- struct SubOp : public BaseAddOp
- {
- SubOp() : BaseAddOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK, 1, -1, Scalar::all(0)) {}
- void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
- {
- int dtype = (flags & MIXED_TYPE) ? dst.type() : -1;
- cv::subtract(src[0], src[1], dst, mask, dtype);
- }
- };
- struct AddSOp : public BaseAddOp
- {
- AddSOp() : BaseAddOp(1, FIX_ALPHA+FIX_BETA+SUPPORT_MASK, 1, 0, Scalar::all(0)) {}
- void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
- {
- int dtype = (flags & MIXED_TYPE) ? dst.type() : -1;
- cv::add(src[0], gamma, dst, mask, dtype);
- }
- };
- struct SubRSOp : public BaseAddOp
- {
- SubRSOp() : BaseAddOp(1, FIX_ALPHA+FIX_BETA+SUPPORT_MASK, -1, 0, Scalar::all(0)) {}
- void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
- {
- int dtype = (flags & MIXED_TYPE) ? dst.type() : -1;
- cv::subtract(gamma, src[0], dst, mask, dtype);
- }
- };
- struct ScaleAddOp : public BaseAddOp
- {
- ScaleAddOp() : BaseAddOp(2, FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- cv::scaleAdd(src[0], alpha, src[1], dst);
- }
- double getMaxErr(int depth)
- {
- return depth < CV_32F ? 1 : depth == CV_32F ? 3e-5 : 1e-12;
- }
- };
- struct AddWeightedOp : public BaseAddOp
- {
- AddWeightedOp() : BaseAddOp(2, REAL_GAMMA, 1, 1, Scalar::all(0)) {}
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- int dtype = (flags & MIXED_TYPE) ? dst.type() : -1;
- cv::addWeighted(src[0], alpha, src[1], beta, gamma[0], dst, dtype);
- }
- };
- struct MulOp : public BaseElemWiseOp
- {
- MulOp() : BaseElemWiseOp(2, FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
- void getValueRange(int depth, double& minval, double& maxval)
- {
- minval = depth < CV_32S ? cvtest::getMinVal(depth) : depth == CV_32S ? -1000000 : -1000.;
- maxval = depth < CV_32S ? cvtest::getMaxVal(depth) : depth == CV_32S ? 1000000 : 1000.;
- minval = std::max(minval, -30000.);
- maxval = std::min(maxval, 30000.);
- }
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- int dtype = (flags & MIXED_TYPE) ? dst.type() : -1;
- cv::multiply(src[0], src[1], dst, alpha, dtype);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- int dtype = (flags & MIXED_TYPE) ? dst.type() : -1;
- cvtest::multiply(src[0], src[1], dst, alpha, dtype);
- }
- };
- struct MulSOp : public BaseElemWiseOp
- {
- MulSOp() : BaseElemWiseOp(1, FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
- void getValueRange(int depth, double& minval, double& maxval)
- {
- minval = depth < CV_32S ? cvtest::getMinVal(depth) : depth == CV_32S ? -1000000 : -1000.;
- maxval = depth < CV_32S ? cvtest::getMaxVal(depth) : depth == CV_32S ? 1000000 : 1000.;
- minval = std::max(minval, -30000.);
- maxval = std::min(maxval, 30000.);
- }
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- int dtype = (flags & MIXED_TYPE) ? dst.type() : -1;
- cv::multiply(src[0], alpha, dst, /* scale */ 1.0, dtype);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- int dtype = (flags & MIXED_TYPE) ? dst.type() : -1;
- cvtest::multiply(Mat(), src[0], dst, alpha, dtype);
- }
- };
- struct DivOp : public BaseElemWiseOp
- {
- DivOp() : BaseElemWiseOp(2, FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- int dtype = (flags & MIXED_TYPE) ? dst.type() : -1;
- cv::divide(src[0], src[1], dst, alpha, dtype);
- if (flags & MIXED_TYPE)
- {
- // div by zero result is implementation-defined
- // since it may involve conversions to/from intermediate format
- Mat zeroMask = src[1] == 0;
- dst.setTo(0, zeroMask);
- }
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- int dtype = (flags & MIXED_TYPE) ? dst.type() : -1;
- cvtest::divide(src[0], src[1], dst, alpha, dtype);
- }
- };
- struct RecipOp : public BaseElemWiseOp
- {
- RecipOp() : BaseElemWiseOp(1, FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- int dtype = (flags & MIXED_TYPE) ? dst.type() : -1;
- cv::divide(alpha, src[0], dst, dtype);
- if (flags & MIXED_TYPE)
- {
- // div by zero result is implementation-defined
- // since it may involve conversions to/from intermediate format
- Mat zeroMask = src[0] == 0;
- dst.setTo(0, zeroMask);
- }
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- int dtype = (flags & MIXED_TYPE) ? dst.type() : -1;
- cvtest::divide(Mat(), src[0], dst, alpha, dtype);
- }
- };
- struct AbsDiffOp : public BaseAddOp
- {
- AbsDiffOp() : BaseAddOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, -1, Scalar::all(0)) {}
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- absdiff(src[0], src[1], dst);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- cvtest::add(src[0], 1, src[1], -1, Scalar::all(0), dst, src[0].type(), true);
- }
- };
- struct AbsDiffSOp : public BaseAddOp
- {
- AbsDiffSOp() : BaseAddOp(1, FIX_ALPHA+FIX_BETA, 1, 0, Scalar::all(0)) {}
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- absdiff(src[0], gamma, dst);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- cvtest::add(src[0], 1, Mat(), 0, -gamma, dst, src[0].type(), true);
- }
- };
- struct LogicOp : public BaseElemWiseOp
- {
- LogicOp(char _opcode) : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK, 1, 1, Scalar::all(0)), opcode(_opcode) {}
- void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
- {
- if( opcode == '&' )
- cv::bitwise_and(src[0], src[1], dst, mask);
- else if( opcode == '|' )
- cv::bitwise_or(src[0], src[1], dst, mask);
- else
- cv::bitwise_xor(src[0], src[1], dst, mask);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
- {
- Mat temp;
- if( !mask.empty() )
- {
- cvtest::logicOp(src[0], src[1], temp, opcode);
- cvtest::copy(temp, dst, mask);
- }
- else
- cvtest::logicOp(src[0], src[1], dst, opcode);
- }
- double getMaxErr(int)
- {
- return 0;
- }
- char opcode;
- };
- struct LogicSOp : public BaseElemWiseOp
- {
- LogicSOp(char _opcode)
- : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+(_opcode != '~' ? SUPPORT_MASK : 0), 1, 1, Scalar::all(0)), opcode(_opcode) {}
- void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
- {
- if( opcode == '&' )
- cv::bitwise_and(src[0], gamma, dst, mask);
- else if( opcode == '|' )
- cv::bitwise_or(src[0], gamma, dst, mask);
- else if( opcode == '^' )
- cv::bitwise_xor(src[0], gamma, dst, mask);
- else
- cv::bitwise_not(src[0], dst);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
- {
- Mat temp;
- if( !mask.empty() )
- {
- cvtest::logicOp(src[0], gamma, temp, opcode);
- cvtest::copy(temp, dst, mask);
- }
- else
- cvtest::logicOp(src[0], gamma, dst, opcode);
- }
- double getMaxErr(int)
- {
- return 0;
- }
- char opcode;
- };
- struct MinOp : public BaseElemWiseOp
- {
- MinOp() : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- cv::min(src[0], src[1], dst);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- cvtest::min(src[0], src[1], dst);
- }
- double getMaxErr(int)
- {
- return 0;
- }
- };
- struct MaxOp : public BaseElemWiseOp
- {
- MaxOp() : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- cv::max(src[0], src[1], dst);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- cvtest::max(src[0], src[1], dst);
- }
- double getMaxErr(int)
- {
- return 0;
- }
- };
- struct MinSOp : public BaseElemWiseOp
- {
- MinSOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)) {}
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- cv::min(src[0], gamma[0], dst);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- cvtest::min(src[0], gamma[0], dst);
- }
- double getMaxErr(int)
- {
- return 0;
- }
- };
- struct MaxSOp : public BaseElemWiseOp
- {
- MaxSOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)) {}
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- cv::max(src[0], gamma[0], dst);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- cvtest::max(src[0], gamma[0], dst);
- }
- double getMaxErr(int)
- {
- return 0;
- }
- };
- struct CmpOp : public BaseElemWiseOp
- {
- CmpOp() : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) { cmpop = 0; }
- void generateScalars(int depth, RNG& rng)
- {
- BaseElemWiseOp::generateScalars(depth, rng);
- cmpop = rng.uniform(0, 6);
- }
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- cv::compare(src[0], src[1], dst, cmpop);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- cvtest::compare(src[0], src[1], dst, cmpop);
- }
- int getRandomType(RNG& rng)
- {
- return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL_BUT_8S, 1, 1);
- }
- double getMaxErr(int)
- {
- return 0;
- }
- int cmpop;
- };
- struct CmpSOp : public BaseElemWiseOp
- {
- CmpSOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)) { cmpop = 0; }
- void generateScalars(int depth, RNG& rng)
- {
- BaseElemWiseOp::generateScalars(depth, rng);
- cmpop = rng.uniform(0, 6);
- if( depth < CV_32F )
- gamma[0] = cvRound(gamma[0]);
- }
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- cv::compare(src[0], gamma[0], dst, cmpop);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- cvtest::compare(src[0], gamma[0], dst, cmpop);
- }
- int getRandomType(RNG& rng)
- {
- return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL_BUT_8S, 1, 1);
- }
- double getMaxErr(int)
- {
- return 0;
- }
- int cmpop;
- };
- struct CopyOp : public BaseElemWiseOp
- {
- CopyOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SUPPORT_MULTICHANNELMASK, 1, 1, Scalar::all(0)) { }
- void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
- {
- src[0].copyTo(dst, mask);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
- {
- cvtest::copy(src[0], dst, mask);
- }
- int getRandomType(RNG& rng)
- {
- return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL_16F, 1, ARITHM_MAX_CHANNELS);
- }
- double getMaxErr(int)
- {
- return 0;
- }
- };
- struct SetOp : public BaseElemWiseOp
- {
- SetOp() : BaseElemWiseOp(0, FIX_ALPHA+FIX_BETA+SUPPORT_MASK+SUPPORT_MULTICHANNELMASK, 1, 1, Scalar::all(0)) {}
- void op(const vector<Mat>&, Mat& dst, const Mat& mask)
- {
- dst.setTo(gamma, mask);
- }
- void refop(const vector<Mat>&, Mat& dst, const Mat& mask)
- {
- cvtest::set(dst, gamma, mask);
- }
- int getRandomType(RNG& rng)
- {
- return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL_16F, 1, ARITHM_MAX_CHANNELS);
- }
- double getMaxErr(int)
- {
- return 0;
- }
- };
- template<typename _Tp, typename _WTp> static void
- inRangeS_(const _Tp* src, const _WTp* a, const _WTp* b, uchar* dst, size_t total, int cn)
- {
- size_t i;
- int c;
- for( i = 0; i < total; i++ )
- {
- _Tp val = src[i*cn];
- dst[i] = (a[0] <= val && val <= b[0]) ? uchar(255) : 0;
- }
- for( c = 1; c < cn; c++ )
- {
- for( i = 0; i < total; i++ )
- {
- _Tp val = src[i*cn + c];
- dst[i] = a[c] <= val && val <= b[c] ? dst[i] : 0;
- }
- }
- }
- template<typename _Tp> static void inRange_(const _Tp* src, const _Tp* a, const _Tp* b, uchar* dst, size_t total, int cn)
- {
- size_t i;
- int c;
- for( i = 0; i < total; i++ )
- {
- _Tp val = src[i*cn];
- dst[i] = a[i*cn] <= val && val <= b[i*cn] ? 255 : 0;
- }
- for( c = 1; c < cn; c++ )
- {
- for( i = 0; i < total; i++ )
- {
- _Tp val = src[i*cn + c];
- dst[i] = a[i*cn + c] <= val && val <= b[i*cn + c] ? dst[i] : 0;
- }
- }
- }
- namespace reference {
- static void inRange(const Mat& src, const Mat& lb, const Mat& rb, Mat& dst)
- {
- CV_Assert( src.type() == lb.type() && src.type() == rb.type() &&
- src.size == lb.size && src.size == rb.size );
- dst.create( src.dims, &src.size[0], CV_8U );
- const Mat *arrays[]={&src, &lb, &rb, &dst, 0};
- Mat planes[4];
- NAryMatIterator it(arrays, planes);
- size_t total = planes[0].total();
- size_t i, nplanes = it.nplanes;
- int depth = src.depth(), cn = src.channels();
- for( i = 0; i < nplanes; i++, ++it )
- {
- const uchar* sptr = planes[0].ptr();
- const uchar* aptr = planes[1].ptr();
- const uchar* bptr = planes[2].ptr();
- uchar* dptr = planes[3].ptr();
- switch( depth )
- {
- case CV_8U:
- inRange_((const uchar*)sptr, (const uchar*)aptr, (const uchar*)bptr, dptr, total, cn);
- break;
- case CV_8S:
- inRange_((const schar*)sptr, (const schar*)aptr, (const schar*)bptr, dptr, total, cn);
- break;
- case CV_16U:
- inRange_((const ushort*)sptr, (const ushort*)aptr, (const ushort*)bptr, dptr, total, cn);
- break;
- case CV_16S:
- inRange_((const short*)sptr, (const short*)aptr, (const short*)bptr, dptr, total, cn);
- break;
- case CV_32S:
- inRange_((const int*)sptr, (const int*)aptr, (const int*)bptr, dptr, total, cn);
- break;
- case CV_32F:
- inRange_((const float*)sptr, (const float*)aptr, (const float*)bptr, dptr, total, cn);
- break;
- case CV_64F:
- inRange_((const double*)sptr, (const double*)aptr, (const double*)bptr, dptr, total, cn);
- break;
- default:
- CV_Error(cv::Error::StsUnsupportedFormat, "");
- }
- }
- }
- static void inRangeS(const Mat& src, const Scalar& lb, const Scalar& rb, Mat& dst)
- {
- dst.create( src.dims, &src.size[0], CV_8U );
- const Mat *arrays[]={&src, &dst, 0};
- Mat planes[2];
- NAryMatIterator it(arrays, planes);
- size_t total = planes[0].total();
- size_t i, nplanes = it.nplanes;
- int depth = src.depth(), cn = src.channels();
- union { double d[4]; float f[4]; int i[4];} lbuf, rbuf;
- int wtype = CV_MAKETYPE(depth <= CV_32S ? CV_32S : depth, cn);
- scalarToRawData(lb, lbuf.d, wtype, cn);
- scalarToRawData(rb, rbuf.d, wtype, cn);
- for( i = 0; i < nplanes; i++, ++it )
- {
- const uchar* sptr = planes[0].ptr();
- uchar* dptr = planes[1].ptr();
- switch( depth )
- {
- case CV_8U:
- inRangeS_((const uchar*)sptr, lbuf.i, rbuf.i, dptr, total, cn);
- break;
- case CV_8S:
- inRangeS_((const schar*)sptr, lbuf.i, rbuf.i, dptr, total, cn);
- break;
- case CV_16U:
- inRangeS_((const ushort*)sptr, lbuf.i, rbuf.i, dptr, total, cn);
- break;
- case CV_16S:
- inRangeS_((const short*)sptr, lbuf.i, rbuf.i, dptr, total, cn);
- break;
- case CV_32S:
- inRangeS_((const int*)sptr, lbuf.i, rbuf.i, dptr, total, cn);
- break;
- case CV_32F:
- inRangeS_((const float*)sptr, lbuf.f, rbuf.f, dptr, total, cn);
- break;
- case CV_64F:
- inRangeS_((const double*)sptr, lbuf.d, rbuf.d, dptr, total, cn);
- break;
- default:
- CV_Error(cv::Error::StsUnsupportedFormat, "");
- }
- }
- }
- } // namespace
- CVTEST_GUARD_SYMBOL(inRange)
- struct InRangeSOp : public BaseElemWiseOp
- {
- InRangeSOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA, 1, 1, Scalar::all(0)) {}
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- cv::inRange(src[0], gamma, gamma1, dst);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- reference::inRangeS(src[0], gamma, gamma1, dst);
- }
- double getMaxErr(int)
- {
- return 0;
- }
- void generateScalars(int depth, RNG& rng)
- {
- BaseElemWiseOp::generateScalars(depth, rng);
- Scalar temp = gamma;
- BaseElemWiseOp::generateScalars(depth, rng);
- for( int i = 0; i < 4; i++ )
- {
- gamma1[i] = std::max(gamma[i], temp[i]);
- gamma[i] = std::min(gamma[i], temp[i]);
- }
- }
- Scalar gamma1;
- };
- struct InRangeOp : public BaseElemWiseOp
- {
- InRangeOp() : BaseElemWiseOp(3, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- Mat lb, rb;
- cvtest::min(src[1], src[2], lb);
- cvtest::max(src[1], src[2], rb);
- cv::inRange(src[0], lb, rb, dst);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- Mat lb, rb;
- cvtest::min(src[1], src[2], lb);
- cvtest::max(src[1], src[2], rb);
- reference::inRange(src[0], lb, rb, dst);
- }
- double getMaxErr(int)
- {
- return 0;
- }
- };
- struct ConvertScaleOp : public BaseElemWiseOp
- {
- ConvertScaleOp() : BaseElemWiseOp(1, FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)), ddepth(0) { }
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- src[0].convertTo(dst, ddepth, alpha, gamma[0]);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- cvtest::convert(src[0], dst, CV_MAKETYPE(ddepth, src[0].channels()), alpha, gamma[0]);
- }
- int getRandomType(RNG& rng)
- {
- int srctype = cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL, 1, ARITHM_MAX_CHANNELS);
- ddepth = cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL, 1, 1);
- return srctype;
- }
- double getMaxErr(int)
- {
- return ddepth <= CV_32S ? 2 : ddepth < CV_64F ? 1e-3 : 1e-12;
- }
- void generateScalars(int depth, RNG& rng)
- {
- if( rng.uniform(0, 2) )
- BaseElemWiseOp::generateScalars(depth, rng);
- else
- {
- alpha = 1;
- gamma = Scalar::all(0);
- }
- }
- int ddepth;
- };
- struct ConvertScaleFp16Op : public BaseElemWiseOp
- {
- ConvertScaleFp16Op() : BaseElemWiseOp(1, FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)), nextRange(0) { }
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- Mat m;
- convertFp16(src[0], m);
- convertFp16(m, dst);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- cvtest::copy(src[0], dst);
- }
- int getRandomType(RNG&)
- {
- // 0: FP32 -> FP16 -> FP32
- // 1: FP16 -> FP32 -> FP16
- int srctype = (nextRange & 1) == 0 ? CV_32F : CV_16S;
- return srctype;
- }
- void getValueRange(int, double& minval, double& maxval)
- {
- // 0: FP32 -> FP16 -> FP32
- // 1: FP16 -> FP32 -> FP16
- if( (nextRange & 1) == 0 )
- {
- // largest integer number that fp16 can express exactly
- maxval = 2048.f;
- minval = -maxval;
- }
- else
- {
- // 0: positive number range
- // 1: negative number range
- if( (nextRange & 2) == 0 )
- {
- minval = 0; // 0x0000 +0
- maxval = 31744; // 0x7C00 +Inf
- }
- else
- {
- minval = -32768; // 0x8000 -0
- maxval = -1024; // 0xFC00 -Inf
- }
- }
- }
- double getMaxErr(int)
- {
- return 0.5f;
- }
- void generateScalars(int, RNG& rng)
- {
- nextRange = rng.next();
- }
- int nextRange;
- };
- struct ConvertScaleAbsOp : public BaseElemWiseOp
- {
- ConvertScaleAbsOp() : BaseElemWiseOp(1, FIX_BETA+REAL_GAMMA, 1, 1, Scalar::all(0)) {}
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- cv::convertScaleAbs(src[0], dst, alpha, gamma[0]);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- cvtest::add(src[0], alpha, Mat(), 0, Scalar::all(gamma[0]), dst, CV_8UC(src[0].channels()), true);
- }
- int getRandomType(RNG& rng)
- {
- return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL, 1,
- ninputs > 1 ? ARITHM_MAX_CHANNELS : 4);
- }
- double getMaxErr(int)
- {
- return 1;
- }
- void generateScalars(int depth, RNG& rng)
- {
- if( rng.uniform(0, 2) )
- BaseElemWiseOp::generateScalars(depth, rng);
- else
- {
- alpha = 1;
- gamma = Scalar::all(0);
- }
- }
- };
- namespace reference {
- // does not support inplace operation
- static void flip(const Mat& src, Mat& dst, int flipcode)
- {
- CV_Assert(src.dims == 2);
- dst.create(src.size(), src.type());
- int i, j, k, esz = (int)src.elemSize(), width = src.cols*esz;
- for( i = 0; i < dst.rows; i++ )
- {
- const uchar* sptr = src.ptr(flipcode == 1 ? i : dst.rows - i - 1);
- uchar* dptr = dst.ptr(i);
- if( flipcode == 0 )
- memcpy(dptr, sptr, width);
- else
- {
- for( j = 0; j < width; j += esz )
- for( k = 0; k < esz; k++ )
- dptr[j + k] = sptr[width - j - esz + k];
- }
- }
- }
- static void flip_inplace(Mat& dst, int flipcode)
- {
- Mat m;
- m.create(dst.size(), dst.type());
- reference::flip(dst, m, flipcode);
- memcpy(dst.ptr<uchar>(), m.ptr<uchar>(), dst.total() * dst.elemSize());
- }
- static void rotate(const Mat& src, Mat& dst, int rotateMode)
- {
- Mat tmp;
- switch (rotateMode)
- {
- case ROTATE_90_CLOCKWISE:
- cvtest::transpose(src, tmp);
- reference::flip(tmp, dst, 1);
- break;
- case ROTATE_180:
- reference::flip(src, dst, -1);
- break;
- case ROTATE_90_COUNTERCLOCKWISE:
- cvtest::transpose(src, tmp);
- reference::flip(tmp, dst, 0);
- break;
- default:
- break;
- }
- }
- static void setIdentity(Mat& dst, const Scalar& s)
- {
- CV_Assert( dst.dims == 2 && dst.channels() <= 4 );
- double buf[4];
- scalarToRawData(s, buf, dst.type(), 0);
- int i, k, esz = (int)dst.elemSize(), width = dst.cols*esz;
- for( i = 0; i < dst.rows; i++ )
- {
- uchar* dptr = dst.ptr(i);
- memset( dptr, 0, width );
- if( i < dst.cols )
- for( k = 0; k < esz; k++ )
- dptr[i*esz + k] = ((uchar*)buf)[k];
- }
- }
- } // namespace
- struct FlipOp : public BaseElemWiseOp
- {
- FlipOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) { flipcode = 0; }
- void getRandomSize(RNG& rng, vector<int>& size)
- {
- cvtest::randomSize(rng, 2, 2, ARITHM_MAX_SIZE_LOG, size);
- }
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- cv::flip(src[0], dst, flipcode);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- reference::flip(src[0], dst, flipcode);
- }
- void generateScalars(int, RNG& rng)
- {
- flipcode = rng.uniform(0, 3) - 1;
- }
- double getMaxErr(int)
- {
- return 0;
- }
- int flipcode;
- };
- struct FlipInplaceOp : public BaseElemWiseOp
- {
- FlipInplaceOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) { flipcode = 0; }
- void getRandomSize(RNG& rng, vector<int>& size)
- {
- cvtest::randomSize(rng, 2, 2, ARITHM_MAX_SIZE_LOG, size);
- }
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- dst.create(src[0].size(), src[0].type());
- memcpy(dst.ptr<uchar>(), src[0].ptr<uchar>(), src[0].total() * src[0].elemSize());
- cv::flip(dst, dst, flipcode);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- dst.create(src[0].size(), src[0].type());
- memcpy(dst.ptr<uchar>(), src[0].ptr<uchar>(), src[0].total() * src[0].elemSize());
- reference::flip_inplace(dst, flipcode);
- }
- void generateScalars(int, RNG& rng)
- {
- flipcode = rng.uniform(0, 3) - 1;
- }
- double getMaxErr(int)
- {
- return 0;
- }
- int flipcode;
- };
- struct RotateOp : public BaseElemWiseOp
- {
- RotateOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) { rotatecode = 0; }
- void getRandomSize(RNG& rng, vector<int>& size)
- {
- cvtest::randomSize(rng, 2, 2, ARITHM_MAX_SIZE_LOG, size);
- }
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- cv::rotate(src[0], dst, rotatecode);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- reference::rotate(src[0], dst, rotatecode);
- }
- void generateScalars(int, RNG& rng)
- {
- rotatecode = rng.uniform(0, 3);
- }
- double getMaxErr(int)
- {
- return 0;
- }
- int rotatecode;
- };
- struct TransposeOp : public BaseElemWiseOp
- {
- TransposeOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
- void getRandomSize(RNG& rng, vector<int>& size)
- {
- cvtest::randomSize(rng, 2, 2, ARITHM_MAX_SIZE_LOG, size);
- }
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- cv::transpose(src[0], dst);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- cvtest::transpose(src[0], dst);
- }
- double getMaxErr(int)
- {
- return 0;
- }
- };
- struct SetIdentityOp : public BaseElemWiseOp
- {
- SetIdentityOp() : BaseElemWiseOp(0, FIX_ALPHA+FIX_BETA, 1, 1, Scalar::all(0)) {}
- void getRandomSize(RNG& rng, vector<int>& size)
- {
- cvtest::randomSize(rng, 2, 2, ARITHM_MAX_SIZE_LOG, size);
- }
- void op(const vector<Mat>&, Mat& dst, const Mat&)
- {
- cv::setIdentity(dst, gamma);
- }
- void refop(const vector<Mat>&, Mat& dst, const Mat&)
- {
- reference::setIdentity(dst, gamma);
- }
- double getMaxErr(int)
- {
- return 0;
- }
- };
- struct SetZeroOp : public BaseElemWiseOp
- {
- SetZeroOp() : BaseElemWiseOp(0, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
- void op(const vector<Mat>&, Mat& dst, const Mat&)
- {
- dst = Scalar::all(0);
- }
- void refop(const vector<Mat>&, Mat& dst, const Mat&)
- {
- cvtest::set(dst, Scalar::all(0));
- }
- double getMaxErr(int)
- {
- return 0;
- }
- };
- namespace reference {
- static void exp(const Mat& src, Mat& dst)
- {
- dst.create( src.dims, &src.size[0], src.type() );
- const Mat *arrays[]={&src, &dst, 0};
- Mat planes[2];
- NAryMatIterator it(arrays, planes);
- size_t j, total = planes[0].total()*src.channels();
- size_t i, nplanes = it.nplanes;
- int depth = src.depth();
- for( i = 0; i < nplanes; i++, ++it )
- {
- const uchar* sptr = planes[0].ptr();
- uchar* dptr = planes[1].ptr();
- if( depth == CV_32F )
- {
- for( j = 0; j < total; j++ )
- ((float*)dptr)[j] = std::exp(((const float*)sptr)[j]);
- }
- else if( depth == CV_64F )
- {
- for( j = 0; j < total; j++ )
- ((double*)dptr)[j] = std::exp(((const double*)sptr)[j]);
- }
- }
- }
- static void log(const Mat& src, Mat& dst)
- {
- dst.create( src.dims, &src.size[0], src.type() );
- const Mat *arrays[]={&src, &dst, 0};
- Mat planes[2];
- NAryMatIterator it(arrays, planes);
- size_t j, total = planes[0].total()*src.channels();
- size_t i, nplanes = it.nplanes;
- int depth = src.depth();
- for( i = 0; i < nplanes; i++, ++it )
- {
- const uchar* sptr = planes[0].ptr();
- uchar* dptr = planes[1].ptr();
- if( depth == CV_32F )
- {
- for( j = 0; j < total; j++ )
- ((float*)dptr)[j] = (float)std::log(fabs(((const float*)sptr)[j]));
- }
- else if( depth == CV_64F )
- {
- for( j = 0; j < total; j++ )
- ((double*)dptr)[j] = std::log(fabs(((const double*)sptr)[j]));
- }
- }
- }
- } // namespace
- struct ExpOp : public BaseElemWiseOp
- {
- ExpOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
- int getRandomType(RNG& rng)
- {
- return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_FLT, 1, ARITHM_MAX_CHANNELS);
- }
- void getValueRange(int depth, double& minval, double& maxval)
- {
- maxval = depth == CV_32F ? 80 : 700;
- minval = -maxval;
- }
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- cv::exp(src[0], dst);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- reference::exp(src[0], dst);
- }
- double getMaxErr(int depth)
- {
- return depth == CV_32F ? 1e-5 : 1e-12;
- }
- };
- struct LogOp : public BaseElemWiseOp
- {
- LogOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}
- int getRandomType(RNG& rng)
- {
- return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_FLT, 1, ARITHM_MAX_CHANNELS);
- }
- void getValueRange(int depth, double& minval, double& maxval)
- {
- maxval = depth == CV_32F ? 50 : 100;
- minval = -maxval;
- }
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- Mat temp;
- reference::exp(src[0], temp);
- cv::log(temp, dst);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- Mat temp;
- reference::exp(src[0], temp);
- reference::log(temp, dst);
- }
- double getMaxErr(int depth)
- {
- return depth == CV_32F ? 1e-5 : 1e-12;
- }
- };
- namespace reference {
- static void cartToPolar(const Mat& mx, const Mat& my, Mat& mmag, Mat& mangle, bool angleInDegrees)
- {
- CV_Assert( (mx.type() == CV_32F || mx.type() == CV_64F) &&
- mx.type() == my.type() && mx.size == my.size );
- mmag.create( mx.dims, &mx.size[0], mx.type() );
- mangle.create( mx.dims, &mx.size[0], mx.type() );
- const Mat *arrays[]={&mx, &my, &mmag, &mangle, 0};
- Mat planes[4];
- NAryMatIterator it(arrays, planes);
- size_t j, total = planes[0].total();
- size_t i, nplanes = it.nplanes;
- int depth = mx.depth();
- double scale = angleInDegrees ? 180/CV_PI : 1;
- for( i = 0; i < nplanes; i++, ++it )
- {
- if( depth == CV_32F )
- {
- const float* xptr = planes[0].ptr<float>();
- const float* yptr = planes[1].ptr<float>();
- float* mptr = planes[2].ptr<float>();
- float* aptr = planes[3].ptr<float>();
- for( j = 0; j < total; j++ )
- {
- mptr[j] = std::sqrt(xptr[j]*xptr[j] + yptr[j]*yptr[j]);
- double a = atan2((double)yptr[j], (double)xptr[j]);
- if( a < 0 ) a += CV_PI*2;
- aptr[j] = (float)(a*scale);
- }
- }
- else
- {
- const double* xptr = planes[0].ptr<double>();
- const double* yptr = planes[1].ptr<double>();
- double* mptr = planes[2].ptr<double>();
- double* aptr = planes[3].ptr<double>();
- for( j = 0; j < total; j++ )
- {
- mptr[j] = std::sqrt(xptr[j]*xptr[j] + yptr[j]*yptr[j]);
- double a = atan2(yptr[j], xptr[j]);
- if( a < 0 ) a += CV_PI*2;
- aptr[j] = a*scale;
- }
- }
- }
- }
- } // namespace
- struct CartToPolarToCartOp : public BaseElemWiseOp
- {
- CartToPolarToCartOp() : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0))
- {
- context = 3;
- angleInDegrees = true;
- }
- int getRandomType(RNG& rng)
- {
- return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_FLT, 1, 1);
- }
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- Mat mag, angle, x, y;
- cv::cartToPolar(src[0], src[1], mag, angle, angleInDegrees);
- cv::polarToCart(mag, angle, x, y, angleInDegrees);
- Mat msrc[] = {mag, angle, x, y};
- int pairs[] = {0, 0, 1, 1, 2, 2, 3, 3};
- dst.create(src[0].dims, src[0].size, CV_MAKETYPE(src[0].depth(), 4));
- cv::mixChannels(msrc, 4, &dst, 1, pairs, 4);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- Mat mag, angle;
- reference::cartToPolar(src[0], src[1], mag, angle, angleInDegrees);
- Mat msrc[] = {mag, angle, src[0], src[1]};
- int pairs[] = {0, 0, 1, 1, 2, 2, 3, 3};
- dst.create(src[0].dims, src[0].size, CV_MAKETYPE(src[0].depth(), 4));
- cv::mixChannels(msrc, 4, &dst, 1, pairs, 4);
- }
- void generateScalars(int, RNG& rng)
- {
- angleInDegrees = rng.uniform(0, 2) != 0;
- }
- double getMaxErr(int)
- {
- return 1e-3;
- }
- bool angleInDegrees;
- };
- struct MeanOp : public BaseElemWiseOp
- {
- MeanOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SCALAR_OUTPUT, 1, 1, Scalar::all(0))
- {
- context = 3;
- }
- void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
- {
- dst.create(1, 1, CV_64FC4);
- dst.at<Scalar>(0,0) = cv::mean(src[0], mask);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
- {
- dst.create(1, 1, CV_64FC4);
- dst.at<Scalar>(0,0) = cvtest::mean(src[0], mask);
- }
- double getMaxErr(int)
- {
- return 1e-5;
- }
- };
- struct SumOp : public BaseElemWiseOp
- {
- SumOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SCALAR_OUTPUT, 1, 1, Scalar::all(0))
- {
- context = 3;
- }
- void op(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- dst.create(1, 1, CV_64FC4);
- dst.at<Scalar>(0,0) = cv::sum(src[0]);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&)
- {
- dst.create(1, 1, CV_64FC4);
- dst.at<Scalar>(0,0) = cvtest::mean(src[0])*(double)src[0].total();
- }
- double getMaxErr(int)
- {
- return 1e-5;
- }
- };
- struct CountNonZeroOp : public BaseElemWiseOp
- {
- CountNonZeroOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SCALAR_OUTPUT+SUPPORT_MASK, 1, 1, Scalar::all(0))
- {}
- int getRandomType(RNG& rng)
- {
- return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL, 1, 1);
- }
- void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
- {
- Mat temp;
- src[0].copyTo(temp);
- if( !mask.empty() )
- temp.setTo(Scalar::all(0), mask);
- dst.create(1, 1, CV_32S);
- dst.at<int>(0,0) = cv::countNonZero(temp);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
- {
- Mat temp;
- cvtest::compare(src[0], 0, temp, CMP_NE);
- if( !mask.empty() )
- cvtest::set(temp, Scalar::all(0), mask);
- dst.create(1, 1, CV_32S);
- dst.at<int>(0,0) = saturate_cast<int>(cvtest::mean(temp)[0]/255*temp.total());
- }
- double getMaxErr(int)
- {
- return 0;
- }
- };
- struct MeanStdDevOp : public BaseElemWiseOp
- {
- Scalar sqmeanRef;
- int cn;
- MeanStdDevOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SCALAR_OUTPUT, 1, 1, Scalar::all(0))
- {
- cn = 0;
- context = 7;
- }
- void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
- {
- dst.create(1, 2, CV_64FC4);
- cv::meanStdDev(src[0], dst.at<Scalar>(0,0), dst.at<Scalar>(0,1), mask);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
- {
- Mat temp;
- cvtest::convert(src[0], temp, CV_64F);
- cvtest::multiply(temp, temp, temp);
- Scalar mean = cvtest::mean(src[0], mask);
- Scalar sqmean = cvtest::mean(temp, mask);
- sqmeanRef = sqmean;
- cn = temp.channels();
- for( int c = 0; c < 4; c++ )
- sqmean[c] = std::sqrt(std::max(sqmean[c] - mean[c]*mean[c], 0.));
- dst.create(1, 2, CV_64FC4);
- dst.at<Scalar>(0,0) = mean;
- dst.at<Scalar>(0,1) = sqmean;
- }
- double getMaxErr(int)
- {
- CV_Assert(cn > 0);
- double err = sqmeanRef[0];
- for(int i = 1; i < cn; ++i)
- err = std::max(err, sqmeanRef[i]);
- return 3e-7 * err;
- }
- };
- struct NormOp : public BaseElemWiseOp
- {
- NormOp() : BaseElemWiseOp(2, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SCALAR_OUTPUT, 1, 1, Scalar::all(0))
- {
- context = 1;
- normType = 0;
- }
- int getRandomType(RNG& rng)
- {
- int type = cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL_BUT_8S, 1, 4);
- for(;;)
- {
- normType = rng.uniform(1, 8);
- if( normType == NORM_INF || normType == NORM_L1 ||
- normType == NORM_L2 || normType == NORM_L2SQR ||
- normType == NORM_HAMMING || normType == NORM_HAMMING2 )
- break;
- }
- if( normType == NORM_HAMMING || normType == NORM_HAMMING2 )
- {
- type = CV_8U;
- }
- return type;
- }
- void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
- {
- dst.create(1, 2, CV_64FC1);
- dst.at<double>(0,0) = cv::norm(src[0], normType, mask);
- dst.at<double>(0,1) = cv::norm(src[0], src[1], normType, mask);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
- {
- dst.create(1, 2, CV_64FC1);
- dst.at<double>(0,0) = cvtest::norm(src[0], normType, mask);
- dst.at<double>(0,1) = cvtest::norm(src[0], src[1], normType, mask);
- }
- void generateScalars(int, RNG& /*rng*/)
- {
- }
- double getMaxErr(int)
- {
- return 1e-6;
- }
- int normType;
- };
- struct MinMaxLocOp : public BaseElemWiseOp
- {
- MinMaxLocOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SCALAR_OUTPUT, 1, 1, Scalar::all(0))
- {
- context = ARITHM_MAX_NDIMS*2 + 2;
- }
- int getRandomType(RNG& rng)
- {
- return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL_BUT_8S, 1, 1);
- }
- void saveOutput(const vector<int>& minidx, const vector<int>& maxidx,
- double minval, double maxval, Mat& dst)
- {
- int i, ndims = (int)minidx.size();
- dst.create(1, ndims*2 + 2, CV_64FC1);
- for( i = 0; i < ndims; i++ )
- {
- dst.at<double>(0,i) = minidx[i];
- dst.at<double>(0,i+ndims) = maxidx[i];
- }
- dst.at<double>(0,ndims*2) = minval;
- dst.at<double>(0,ndims*2+1) = maxval;
- }
- void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
- {
- int ndims = src[0].dims;
- vector<int> minidx(ndims), maxidx(ndims);
- double minval=0, maxval=0;
- cv::minMaxIdx(src[0], &minval, &maxval, &minidx[0], &maxidx[0], mask);
- saveOutput(minidx, maxidx, minval, maxval, dst);
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat& mask)
- {
- int ndims=src[0].dims;
- vector<int> minidx(ndims), maxidx(ndims);
- double minval=0, maxval=0;
- cvtest::minMaxLoc(src[0], &minval, &maxval, &minidx, &maxidx, mask);
- saveOutput(minidx, maxidx, minval, maxval, dst);
- }
- double getMaxErr(int)
- {
- return 0;
- }
- };
- struct reduceArgMinMaxOp : public BaseElemWiseOp
- {
- reduceArgMinMaxOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)),
- isLast(false), isMax(false), axis(0)
- {
- context = ARITHM_MAX_NDIMS*2 + 2;
- }
- int getRandomType(RNG& rng) override
- {
- return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL_BUT_8S, 1, 1);
- }
- void getRandomSize(RNG& rng, vector<int>& size) override
- {
- cvtest::randomSize(rng, 2, ARITHM_MAX_NDIMS, 6, size);
- }
- void generateScalars(int depth, RNG& rng) override
- {
- BaseElemWiseOp::generateScalars(depth, rng);
- isLast = (randInt(rng) % 2 == 0);
- isMax = (randInt(rng) % 2 == 0);
- axis = randInt(rng);
- }
- int getAxis(const Mat& src) const
- {
- int dims = src.dims;
- return static_cast<int>(axis % (2 * dims)) - dims; // [-dims; dims - 1]
- }
- void op(const vector<Mat>& src, Mat& dst, const Mat&) override
- {
- const Mat& inp = src[0];
- const int axis_ = getAxis(inp);
- if (isMax)
- {
- cv::reduceArgMax(inp, dst, axis_, isLast);
- }
- else
- {
- cv::reduceArgMin(inp, dst, axis_, isLast);
- }
- }
- void refop(const vector<Mat>& src, Mat& dst, const Mat&) override
- {
- const Mat& inp = src[0];
- const int axis_ = getAxis(inp);
- if (!isLast && !isMax)
- {
- cvtest::MinMaxReducer<std::less>::reduce(inp, dst, axis_);
- }
- else if (!isLast && isMax)
- {
- cvtest::MinMaxReducer<std::greater>::reduce(inp, dst, axis_);
- }
- else if (isLast && !isMax)
- {
- cvtest::MinMaxReducer<std::less_equal>::reduce(inp, dst, axis_);
- }
- else
- {
- cvtest::MinMaxReducer<std::greater_equal>::reduce(inp, dst, axis_);
- }
- }
- bool isLast;
- bool isMax;
- uint32_t axis;
- };
- typedef Ptr<BaseElemWiseOp> ElemWiseOpPtr;
- class ElemWiseTest : public ::testing::TestWithParam<ElemWiseOpPtr> {};
- TEST_P(ElemWiseTest, accuracy)
- {
- ElemWiseOpPtr op = GetParam();
- int testIdx = 0;
- RNG rng((uint64)ARITHM_RNG_SEED);
- for( testIdx = 0; testIdx < ARITHM_NTESTS; testIdx++ )
- {
- vector<int> size;
- op->getRandomSize(rng, size);
- int type = op->getRandomType(rng);
- int depth = CV_MAT_DEPTH(type);
- bool haveMask = ((op->flags & BaseElemWiseOp::SUPPORT_MASK) != 0
- || (op->flags & BaseElemWiseOp::SUPPORT_MULTICHANNELMASK) != 0) && rng.uniform(0, 4) == 0;
- double minval=0, maxval=0;
- op->getValueRange(depth, minval, maxval);
- int i, ninputs = op->ninputs;
- vector<Mat> src(ninputs);
- for( i = 0; i < ninputs; i++ )
- src[i] = cvtest::randomMat(rng, size, type, minval, maxval, true);
- Mat dst0, dst, mask;
- if( haveMask ) {
- bool multiChannelMask = (op->flags & BaseElemWiseOp::SUPPORT_MULTICHANNELMASK) != 0
- && rng.uniform(0, 2) == 0;
- int masktype = CV_8UC(multiChannelMask ? CV_MAT_CN(type) : 1);
- mask = cvtest::randomMat(rng, size, masktype, 0, 2, true);
- }
- if( (haveMask || ninputs == 0) && !(op->flags & BaseElemWiseOp::SCALAR_OUTPUT))
- {
- dst0 = cvtest::randomMat(rng, size, type, minval, maxval, false);
- dst = cvtest::randomMat(rng, size, type, minval, maxval, true);
- cvtest::copy(dst, dst0);
- }
- op->generateScalars(depth, rng);
- op->refop(src, dst0, mask);
- op->op(src, dst, mask);
- double maxErr = op->getMaxErr(depth);
- ASSERT_PRED_FORMAT2(cvtest::MatComparator(maxErr, op->context), dst0, dst) << "\nsrc[0] ~ " <<
- cvtest::MatInfo(!src.empty() ? src[0] : Mat()) << "\ntestCase #" << testIdx << "\n";
- }
- }
- INSTANTIATE_TEST_CASE_P(Core_Copy, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new CopyOp)));
- INSTANTIATE_TEST_CASE_P(Core_Set, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new SetOp)));
- INSTANTIATE_TEST_CASE_P(Core_SetZero, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new SetZeroOp)));
- INSTANTIATE_TEST_CASE_P(Core_ConvertScale, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new ConvertScaleOp)));
- INSTANTIATE_TEST_CASE_P(Core_ConvertScaleFp16, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new ConvertScaleFp16Op)));
- INSTANTIATE_TEST_CASE_P(Core_ConvertScaleAbs, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new ConvertScaleAbsOp)));
- INSTANTIATE_TEST_CASE_P(Core_Add, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new AddOp)));
- INSTANTIATE_TEST_CASE_P(Core_Sub, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new SubOp)));
- INSTANTIATE_TEST_CASE_P(Core_AddS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new AddSOp)));
- INSTANTIATE_TEST_CASE_P(Core_SubRS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new SubRSOp)));
- INSTANTIATE_TEST_CASE_P(Core_ScaleAdd, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new ScaleAddOp)));
- INSTANTIATE_TEST_CASE_P(Core_AddWeighted, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new AddWeightedOp)));
- INSTANTIATE_TEST_CASE_P(Core_AbsDiff, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new AbsDiffOp)));
- INSTANTIATE_TEST_CASE_P(Core_AbsDiffS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new AbsDiffSOp)));
- INSTANTIATE_TEST_CASE_P(Core_And, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new LogicOp('&'))));
- INSTANTIATE_TEST_CASE_P(Core_AndS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new LogicSOp('&'))));
- INSTANTIATE_TEST_CASE_P(Core_Or, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new LogicOp('|'))));
- INSTANTIATE_TEST_CASE_P(Core_OrS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new LogicSOp('|'))));
- INSTANTIATE_TEST_CASE_P(Core_Xor, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new LogicOp('^'))));
- INSTANTIATE_TEST_CASE_P(Core_XorS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new LogicSOp('^'))));
- INSTANTIATE_TEST_CASE_P(Core_Not, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new LogicSOp('~'))));
- INSTANTIATE_TEST_CASE_P(Core_Max, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new MaxOp)));
- INSTANTIATE_TEST_CASE_P(Core_MaxS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new MaxSOp)));
- INSTANTIATE_TEST_CASE_P(Core_Min, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new MinOp)));
- INSTANTIATE_TEST_CASE_P(Core_MinS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new MinSOp)));
- INSTANTIATE_TEST_CASE_P(Core_Mul, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new MulOp)));
- INSTANTIATE_TEST_CASE_P(Core_Div, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new DivOp)));
- INSTANTIATE_TEST_CASE_P(Core_Recip, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new RecipOp)));
- INSTANTIATE_TEST_CASE_P(Core_Cmp, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new CmpOp)));
- INSTANTIATE_TEST_CASE_P(Core_CmpS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new CmpSOp)));
- INSTANTIATE_TEST_CASE_P(Core_InRangeS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new InRangeSOp)));
- INSTANTIATE_TEST_CASE_P(Core_InRange, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new InRangeOp)));
- INSTANTIATE_TEST_CASE_P(Core_Flip, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new FlipOp)));
- INSTANTIATE_TEST_CASE_P(Core_FlipInplace, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new FlipInplaceOp)));
- INSTANTIATE_TEST_CASE_P(Core_Rotate, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new RotateOp)));
- INSTANTIATE_TEST_CASE_P(Core_Transpose, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new TransposeOp)));
- INSTANTIATE_TEST_CASE_P(Core_SetIdentity, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new SetIdentityOp)));
- INSTANTIATE_TEST_CASE_P(Core_Exp, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new ExpOp)));
- INSTANTIATE_TEST_CASE_P(Core_Log, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new LogOp)));
- INSTANTIATE_TEST_CASE_P(Core_CountNonZero, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new CountNonZeroOp)));
- INSTANTIATE_TEST_CASE_P(Core_Mean, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new MeanOp)));
- INSTANTIATE_TEST_CASE_P(Core_MeanStdDev, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new MeanStdDevOp)));
- INSTANTIATE_TEST_CASE_P(Core_Sum, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new SumOp)));
- INSTANTIATE_TEST_CASE_P(Core_Norm, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new NormOp)));
- INSTANTIATE_TEST_CASE_P(Core_MinMaxLoc, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new MinMaxLocOp)));
- INSTANTIATE_TEST_CASE_P(Core_reduceArgMinMax, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new reduceArgMinMaxOp)));
- INSTANTIATE_TEST_CASE_P(Core_CartToPolarToCart, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new CartToPolarToCartOp)));
- // Mixed Type Arithmetic Operations
- typedef std::tuple<ElemWiseOpPtr, std::tuple<cvtest::MatDepth, cvtest::MatDepth>, int> SomeType;
- class ArithmMixedTest : public ::testing::TestWithParam<SomeType> {};
- TEST_P(ArithmMixedTest, accuracy)
- {
- auto p = GetParam();
- ElemWiseOpPtr op = std::get<0>(p);
- int srcDepth = std::get<0>(std::get<1>(p));
- int dstDepth = std::get<1>(std::get<1>(p));
- int channels = std::get<2>(p);
- int srcType = CV_MAKETYPE(srcDepth, channels);
- int dstType = CV_MAKETYPE(dstDepth, channels);
- op->flags |= BaseElemWiseOp::MIXED_TYPE;
- int testIdx = 0;
- RNG rng((uint64)ARITHM_RNG_SEED);
- for( testIdx = 0; testIdx < ARITHM_NTESTS; testIdx++ )
- {
- vector<int> size;
- op->getRandomSize(rng, size);
- bool haveMask = ((op->flags & BaseElemWiseOp::SUPPORT_MASK) != 0) && rng.uniform(0, 4) == 0;
- double minval=0, maxval=0;
- op->getValueRange(srcDepth, minval, maxval);
- int ninputs = op->ninputs;
- vector<Mat> src(ninputs);
- for(int i = 0; i < ninputs; i++ )
- src[i] = cvtest::randomMat(rng, size, srcType, minval, maxval, true);
- Mat dst0, dst, mask;
- if( haveMask )
- {
- mask = cvtest::randomMat(rng, size, CV_8UC1, 0, 2, true);
- }
- dst0 = cvtest::randomMat(rng, size, dstType, minval, maxval, false);
- dst = cvtest::randomMat(rng, size, dstType, minval, maxval, true);
- cvtest::copy(dst, dst0);
- op->generateScalars(dstDepth, rng);
- op->refop(src, dst0, mask);
- op->op(src, dst, mask);
- double maxErr = op->getMaxErr(dstDepth);
- ASSERT_PRED_FORMAT2(cvtest::MatComparator(maxErr, op->context), dst0, dst) << "\nsrc[0] ~ " <<
- cvtest::MatInfo(!src.empty() ? src[0] : Mat()) << "\ntestCase #" << testIdx << "\n";
- }
- }
- INSTANTIATE_TEST_CASE_P(Core_AddMixed, ArithmMixedTest,
- ::testing::Combine(::testing::Values(ElemWiseOpPtr(new AddOp)),
- ::testing::Values(std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8U, CV_16U},
- std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8S, CV_16S},
- std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8U, CV_32F},
- std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8S, CV_32F}),
- ::testing::Values(1, 3, 4)));
- INSTANTIATE_TEST_CASE_P(Core_AddScalarMixed, ArithmMixedTest,
- ::testing::Combine(::testing::Values(ElemWiseOpPtr(new AddSOp)),
- ::testing::Values(std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8U, CV_16U},
- std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8S, CV_16S},
- std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8U, CV_32F},
- std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8S, CV_32F}),
- ::testing::Values(1, 3, 4)));
- INSTANTIATE_TEST_CASE_P(Core_AddWeightedMixed, ArithmMixedTest,
- ::testing::Combine(::testing::Values(ElemWiseOpPtr(new AddWeightedOp)),
- ::testing::Values(std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8U, CV_16U},
- std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8S, CV_16S},
- std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8U, CV_32F},
- std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8S, CV_32F}),
- ::testing::Values(1, 3, 4)));
- INSTANTIATE_TEST_CASE_P(Core_SubMixed, ArithmMixedTest,
- ::testing::Combine(::testing::Values(ElemWiseOpPtr(new SubOp)),
- ::testing::Values(std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8U, CV_16U},
- std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8S, CV_16S},
- std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8U, CV_32F},
- std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8S, CV_32F}),
- ::testing::Values(1, 3, 4)));
- INSTANTIATE_TEST_CASE_P(Core_SubScalarMinusArgMixed, ArithmMixedTest,
- ::testing::Combine(::testing::Values(ElemWiseOpPtr(new SubRSOp)),
- ::testing::Values(std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8U, CV_16U},
- std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8S, CV_16S},
- std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8U, CV_32F},
- std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8S, CV_32F}),
- ::testing::Values(1, 3, 4)));
- INSTANTIATE_TEST_CASE_P(Core_MulMixed, ArithmMixedTest,
- ::testing::Combine(::testing::Values(ElemWiseOpPtr(new MulOp)),
- ::testing::Values(std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8U, CV_16U},
- std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8S, CV_16S},
- std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8U, CV_32F},
- std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8S, CV_32F}),
- ::testing::Values(1, 3, 4)));
- INSTANTIATE_TEST_CASE_P(Core_MulScalarMixed, ArithmMixedTest,
- ::testing::Combine(::testing::Values(ElemWiseOpPtr(new MulSOp)),
- ::testing::Values(std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8U, CV_16U},
- std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8S, CV_16S},
- std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8U, CV_32F},
- std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8S, CV_32F}),
- ::testing::Values(1, 3, 4)));
- INSTANTIATE_TEST_CASE_P(Core_DivMixed, ArithmMixedTest,
- ::testing::Combine(::testing::Values(ElemWiseOpPtr(new DivOp)),
- ::testing::Values(std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8U, CV_16U},
- std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8S, CV_16S},
- std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8U, CV_32F},
- std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8S, CV_32F}),
- ::testing::Values(1, 3, 4)));
- INSTANTIATE_TEST_CASE_P(Core_RecipMixed, ArithmMixedTest,
- ::testing::Combine(::testing::Values(ElemWiseOpPtr(new RecipOp)),
- ::testing::Values(std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8U, CV_16U},
- std::tuple<cvtest::MatDepth, cvtest::MatDepth>{CV_8S, CV_32F}),
- ::testing::Values(1, 3, 4)));
- TEST(Core_ArithmMask, uninitialized)
- {
- RNG& rng = theRNG();
- const int MAX_DIM=3;
- int sizes[MAX_DIM];
- for( int iter = 0; iter < 100; iter++ )
- {
- int dims = rng.uniform(1, MAX_DIM+1);
- int depth = rng.uniform(CV_8U, CV_64F+1);
- int cn = rng.uniform(1, 6);
- int type = CV_MAKETYPE(depth, cn);
- int op = rng.uniform(0, depth < CV_32F ? 5 : 2); // don't run binary operations between floating-point values
- int depth1 = op <= 1 ? CV_64F : depth;
- for (int k = 0; k < MAX_DIM; k++)
- {
- sizes[k] = k < dims ? rng.uniform(1, 30) : 0;
- }
- SCOPED_TRACE(cv::format("iter=%d dims=%d depth=%d cn=%d type=%d op=%d depth1=%d dims=[%d; %d; %d]",
- iter, dims, depth, cn, type, op, depth1, sizes[0], sizes[1], sizes[2]));
- Mat a(dims, sizes, type), a1;
- Mat b(dims, sizes, type), b1;
- Mat mask(dims, sizes, CV_8U);
- Mat mask1;
- Mat c, d;
- rng.fill(a, RNG::UNIFORM, 0, 100);
- rng.fill(b, RNG::UNIFORM, 0, 100);
- // [-2,2) range means that the each generated random number
- // will be one of -2, -1, 0, 1. Saturated to [0,255], it will become
- // 0, 0, 0, 1 => the mask will be filled by ~25%.
- rng.fill(mask, RNG::UNIFORM, -2, 2);
- a.convertTo(a1, depth1);
- b.convertTo(b1, depth1);
- // invert the mask
- cv::compare(mask, 0, mask1, CMP_EQ);
- a1.setTo(0, mask1);
- b1.setTo(0, mask1);
- if( op == 0 )
- {
- cv::add(a, b, c, mask);
- cv::add(a1, b1, d);
- }
- else if( op == 1 )
- {
- cv::subtract(a, b, c, mask);
- cv::subtract(a1, b1, d);
- }
- else if( op == 2 )
- {
- cv::bitwise_and(a, b, c, mask);
- cv::bitwise_and(a1, b1, d);
- }
- else if( op == 3 )
- {
- cv::bitwise_or(a, b, c, mask);
- cv::bitwise_or(a1, b1, d);
- }
- else if( op == 4 )
- {
- cv::bitwise_xor(a, b, c, mask);
- cv::bitwise_xor(a1, b1, d);
- }
- Mat d1;
- d.convertTo(d1, depth);
- EXPECT_LE(cvtest::norm(c, d1, CV_C), DBL_EPSILON);
- }
- Mat_<uchar> tmpSrc(100,100);
- tmpSrc = 124;
- Mat_<uchar> tmpMask(100,100);
- tmpMask = 255;
- Mat_<uchar> tmpDst(100,100);
- tmpDst = 2;
- tmpSrc.copyTo(tmpDst,tmpMask);
- }
- TEST(Multiply, FloatingPointRounding)
- {
- cv::Mat src(1, 1, CV_8UC1, cv::Scalar::all(110)), dst;
- cv::Scalar s(147.286359696927, 1, 1 ,1);
- cv::multiply(src, s, dst, 1, CV_16U);
- // with CV_32F this produce result 16202
- ASSERT_EQ(dst.at<ushort>(0,0), 16201);
- }
- TEST(Core_Add, AddToColumnWhen3Rows)
- {
- cv::Mat m1 = (cv::Mat_<double>(3, 2) << 1, 2, 3, 4, 5, 6);
- m1.col(1) += 10;
- cv::Mat m2 = (cv::Mat_<double>(3, 2) << 1, 12, 3, 14, 5, 16);
- ASSERT_EQ(0, countNonZero(m1 - m2));
- }
- TEST(Core_Add, AddToColumnWhen4Rows)
- {
- cv::Mat m1 = (cv::Mat_<double>(4, 2) << 1, 2, 3, 4, 5, 6, 7, 8);
- m1.col(1) += 10;
- cv::Mat m2 = (cv::Mat_<double>(4, 2) << 1, 12, 3, 14, 5, 16, 7, 18);
- ASSERT_EQ(0, countNonZero(m1 - m2));
- }
- TEST(Core_round, CvRound)
- {
- ASSERT_EQ(2, cvRound(2.0));
- ASSERT_EQ(2, cvRound(2.1));
- ASSERT_EQ(-2, cvRound(-2.1));
- ASSERT_EQ(3, cvRound(2.8));
- ASSERT_EQ(-3, cvRound(-2.8));
- ASSERT_EQ(2, cvRound(2.5));
- ASSERT_EQ(4, cvRound(3.5));
- ASSERT_EQ(-2, cvRound(-2.5));
- ASSERT_EQ(-4, cvRound(-3.5));
- }
- typedef testing::TestWithParam<Size> Mul1;
- TEST_P(Mul1, One)
- {
- Size size = GetParam();
- cv::Mat src(size, CV_32FC1, cv::Scalar::all(2)), dst,
- ref_dst(size, CV_32FC1, cv::Scalar::all(6));
- cv::multiply(3, src, dst);
- ASSERT_EQ(0, cvtest::norm(dst, ref_dst, cv::NORM_INF));
- }
- INSTANTIATE_TEST_CASE_P(Arithm, Mul1, testing::Values(Size(2, 2), Size(1, 1)));
- class SubtractOutputMatNotEmpty : public testing::TestWithParam< tuple<cv::Size, perf::MatType, perf::MatDepth, bool> >
- {
- public:
- cv::Size size;
- int src_type;
- int dst_depth;
- bool fixed;
- void SetUp()
- {
- size = get<0>(GetParam());
- src_type = get<1>(GetParam());
- dst_depth = get<2>(GetParam());
- fixed = get<3>(GetParam());
- }
- };
- TEST_P(SubtractOutputMatNotEmpty, Mat_Mat)
- {
- cv::Mat src1(size, src_type, cv::Scalar::all(16));
- cv::Mat src2(size, src_type, cv::Scalar::all(16));
- cv::Mat dst;
- if (!fixed)
- {
- cv::subtract(src1, src2, dst, cv::noArray(), dst_depth);
- }
- else
- {
- const cv::Mat fixed_dst(size, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src1.channels()));
- cv::subtract(src1, src2, fixed_dst, cv::noArray(), dst_depth);
- dst = fixed_dst;
- dst_depth = fixed_dst.depth();
- }
- ASSERT_FALSE(dst.empty());
- ASSERT_EQ(src1.size(), dst.size());
- ASSERT_EQ(dst_depth > 0 ? dst_depth : src1.depth(), dst.depth());
- ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
- }
- TEST_P(SubtractOutputMatNotEmpty, Mat_Mat_WithMask)
- {
- cv::Mat src1(size, src_type, cv::Scalar::all(16));
- cv::Mat src2(size, src_type, cv::Scalar::all(16));
- cv::Mat mask(size, CV_8UC1, cv::Scalar::all(255));
- cv::Mat dst;
- if (!fixed)
- {
- cv::subtract(src1, src2, dst, mask, dst_depth);
- }
- else
- {
- const cv::Mat fixed_dst(size, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src1.channels()));
- cv::subtract(src1, src2, fixed_dst, mask, dst_depth);
- dst = fixed_dst;
- dst_depth = fixed_dst.depth();
- }
- ASSERT_FALSE(dst.empty());
- ASSERT_EQ(src1.size(), dst.size());
- ASSERT_EQ(dst_depth > 0 ? dst_depth : src1.depth(), dst.depth());
- ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
- }
- TEST_P(SubtractOutputMatNotEmpty, Mat_Mat_Expr)
- {
- cv::Mat src1(size, src_type, cv::Scalar::all(16));
- cv::Mat src2(size, src_type, cv::Scalar::all(16));
- cv::Mat dst = src1 - src2;
- ASSERT_FALSE(dst.empty());
- ASSERT_EQ(src1.size(), dst.size());
- ASSERT_EQ(src1.depth(), dst.depth());
- ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
- }
- TEST_P(SubtractOutputMatNotEmpty, Mat_Scalar)
- {
- cv::Mat src(size, src_type, cv::Scalar::all(16));
- cv::Mat dst;
- if (!fixed)
- {
- cv::subtract(src, cv::Scalar::all(16), dst, cv::noArray(), dst_depth);
- }
- else
- {
- const cv::Mat fixed_dst(size, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src.channels()));
- cv::subtract(src, cv::Scalar::all(16), fixed_dst, cv::noArray(), dst_depth);
- dst = fixed_dst;
- dst_depth = fixed_dst.depth();
- }
- ASSERT_FALSE(dst.empty());
- ASSERT_EQ(src.size(), dst.size());
- ASSERT_EQ(dst_depth > 0 ? dst_depth : src.depth(), dst.depth());
- ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
- }
- TEST_P(SubtractOutputMatNotEmpty, Mat_Scalar_WithMask)
- {
- cv::Mat src(size, src_type, cv::Scalar::all(16));
- cv::Mat mask(size, CV_8UC1, cv::Scalar::all(255));
- cv::Mat dst;
- if (!fixed)
- {
- cv::subtract(src, cv::Scalar::all(16), dst, mask, dst_depth);
- }
- else
- {
- const cv::Mat fixed_dst(size, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src.channels()));
- cv::subtract(src, cv::Scalar::all(16), fixed_dst, mask, dst_depth);
- dst = fixed_dst;
- dst_depth = fixed_dst.depth();
- }
- ASSERT_FALSE(dst.empty());
- ASSERT_EQ(src.size(), dst.size());
- ASSERT_EQ(dst_depth > 0 ? dst_depth : src.depth(), dst.depth());
- ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
- }
- TEST_P(SubtractOutputMatNotEmpty, Scalar_Mat)
- {
- cv::Mat src(size, src_type, cv::Scalar::all(16));
- cv::Mat dst;
- if (!fixed)
- {
- cv::subtract(cv::Scalar::all(16), src, dst, cv::noArray(), dst_depth);
- }
- else
- {
- const cv::Mat fixed_dst(size, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src.channels()));
- cv::subtract(cv::Scalar::all(16), src, fixed_dst, cv::noArray(), dst_depth);
- dst = fixed_dst;
- dst_depth = fixed_dst.depth();
- }
- ASSERT_FALSE(dst.empty());
- ASSERT_EQ(src.size(), dst.size());
- ASSERT_EQ(dst_depth > 0 ? dst_depth : src.depth(), dst.depth());
- ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
- }
- TEST_P(SubtractOutputMatNotEmpty, Scalar_Mat_WithMask)
- {
- cv::Mat src(size, src_type, cv::Scalar::all(16));
- cv::Mat mask(size, CV_8UC1, cv::Scalar::all(255));
- cv::Mat dst;
- if (!fixed)
- {
- cv::subtract(cv::Scalar::all(16), src, dst, mask, dst_depth);
- }
- else
- {
- const cv::Mat fixed_dst(size, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src.channels()));
- cv::subtract(cv::Scalar::all(16), src, fixed_dst, mask, dst_depth);
- dst = fixed_dst;
- dst_depth = fixed_dst.depth();
- }
- ASSERT_FALSE(dst.empty());
- ASSERT_EQ(src.size(), dst.size());
- ASSERT_EQ(dst_depth > 0 ? dst_depth : src.depth(), dst.depth());
- ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
- }
- TEST_P(SubtractOutputMatNotEmpty, Mat_Mat_3d)
- {
- int dims[] = {5, size.height, size.width};
- cv::Mat src1(3, dims, src_type, cv::Scalar::all(16));
- cv::Mat src2(3, dims, src_type, cv::Scalar::all(16));
- cv::Mat dst;
- if (!fixed)
- {
- cv::subtract(src1, src2, dst, cv::noArray(), dst_depth);
- }
- else
- {
- const cv::Mat fixed_dst(3, dims, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src1.channels()));
- cv::subtract(src1, src2, fixed_dst, cv::noArray(), dst_depth);
- dst = fixed_dst;
- dst_depth = fixed_dst.depth();
- }
- ASSERT_FALSE(dst.empty());
- ASSERT_EQ(src1.dims, dst.dims);
- ASSERT_EQ(src1.size, dst.size);
- ASSERT_EQ(dst_depth > 0 ? dst_depth : src1.depth(), dst.depth());
- ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
- }
- INSTANTIATE_TEST_CASE_P(Arithm, SubtractOutputMatNotEmpty, testing::Combine(
- testing::Values(cv::Size(16, 16), cv::Size(13, 13), cv::Size(16, 13), cv::Size(13, 16)),
- testing::Values(perf::MatType(CV_8UC1), CV_8UC3, CV_8UC4, CV_16SC1, CV_16SC3),
- testing::Values(-1, CV_16S, CV_32S, CV_32F),
- testing::Bool()));
- TEST(Core_FindNonZero, regression)
- {
- Mat img(10, 10, CV_8U, Scalar::all(0));
- vector<Point> pts, pts2(5);
- findNonZero(img, pts);
- findNonZero(img, pts2);
- ASSERT_TRUE(pts.empty() && pts2.empty());
- RNG rng((uint64)-1);
- size_t nz = 0;
- for( int i = 0; i < 10; i++ )
- {
- int idx = rng.uniform(0, img.rows*img.cols);
- if( !img.data[idx] ) nz++;
- img.data[idx] = (uchar)rng.uniform(1, 256);
- }
- findNonZero(img, pts);
- ASSERT_TRUE(pts.size() == nz);
- img.convertTo( img, CV_8S );
- pts.clear();
- findNonZero(img, pts);
- ASSERT_TRUE(pts.size() == nz);
- img.convertTo( img, CV_16U );
- pts.resize(pts.size()*2);
- findNonZero(img, pts);
- ASSERT_TRUE(pts.size() == nz);
- img.convertTo( img, CV_16S );
- pts.resize(pts.size()*3);
- findNonZero(img, pts);
- ASSERT_TRUE(pts.size() == nz);
- img.convertTo( img, CV_32S );
- pts.resize(pts.size()*4);
- findNonZero(img, pts);
- ASSERT_TRUE(pts.size() == nz);
- img.convertTo( img, CV_32F );
- pts.resize(pts.size()*5);
- findNonZero(img, pts);
- ASSERT_TRUE(pts.size() == nz);
- img.convertTo( img, CV_64F );
- pts.clear();
- findNonZero(img, pts);
- ASSERT_TRUE(pts.size() == nz);
- }
- TEST(Core_BoolVector, support)
- {
- std::vector<bool> test;
- int i, n = 205;
- int nz = 0;
- test.resize(n);
- for( i = 0; i < n; i++ )
- {
- test[i] = theRNG().uniform(0, 2) != 0;
- nz += (int)test[i];
- }
- ASSERT_EQ( nz, countNonZero(test) );
- ASSERT_FLOAT_EQ((float)nz/n, (float)(cv::mean(test)[0]));
- }
- TEST(MinMaxLoc, Mat_UcharMax_Without_Loc)
- {
- Mat_<uchar> mat(50, 50);
- uchar iMaxVal = std::numeric_limits<uchar>::max();
- mat.setTo(iMaxVal);
- double min, max;
- Point minLoc, maxLoc;
- minMaxLoc(mat, &min, &max, &minLoc, &maxLoc, Mat());
- ASSERT_EQ(iMaxVal, min);
- ASSERT_EQ(iMaxVal, max);
- ASSERT_EQ(Point(0, 0), minLoc);
- ASSERT_EQ(Point(0, 0), maxLoc);
- }
- TEST(MinMaxLoc, Mat_IntMax_Without_Mask)
- {
- Mat_<int> mat(50, 50);
- int iMaxVal = std::numeric_limits<int>::max();
- mat.setTo(iMaxVal);
- double min, max;
- Point minLoc, maxLoc;
- minMaxLoc(mat, &min, &max, &minLoc, &maxLoc, Mat());
- ASSERT_EQ(iMaxVal, min);
- ASSERT_EQ(iMaxVal, max);
- ASSERT_EQ(Point(0, 0), minLoc);
- ASSERT_EQ(Point(0, 0), maxLoc);
- }
- TEST(Normalize, regression_5876_inplace_change_type)
- {
- double initial_values[] = {1, 2, 5, 4, 3};
- float result_values[] = {0, 0.25, 1, 0.75, 0.5};
- Mat m(Size(5, 1), CV_64FC1, initial_values);
- Mat result(Size(5, 1), CV_32FC1, result_values);
- normalize(m, m, 1, 0, NORM_MINMAX, CV_32F);
- EXPECT_EQ(0, cvtest::norm(m, result, NORM_INF));
- }
- TEST(Normalize, regression_6125)
- {
- float initial_values[] = {
- 1888, 1692, 369, 263, 199,
- 280, 326, 129, 143, 126,
- 233, 221, 130, 126, 150,
- 249, 575, 574, 63, 12
- };
- Mat src(Size(20, 1), CV_32F, initial_values);
- float min = 0., max = 400.;
- normalize(src, src, 0, 400, NORM_MINMAX, CV_32F);
- for(int i = 0; i < 20; i++)
- {
- EXPECT_GE(src.at<float>(i), min) << "Value should be >= 0";
- EXPECT_LE(src.at<float>(i), max) << "Value should be <= 400";
- }
- }
- TEST(MinMaxLoc, regression_4955_nans)
- {
- cv::Mat one_mat(2, 2, CV_32F, cv::Scalar(1));
- cv::minMaxLoc(one_mat, NULL, NULL, NULL, NULL);
- cv::Mat nan_mat(2, 2, CV_32F, cv::Scalar(std::numeric_limits<float>::quiet_NaN()));
- cv::minMaxLoc(nan_mat, NULL, NULL, NULL, NULL);
- }
- TEST(Subtract, scalarc1_matc3)
- {
- int scalar = 255;
- cv::Mat srcImage(5, 5, CV_8UC3, cv::Scalar::all(5)), destImage;
- cv::subtract(scalar, srcImage, destImage);
- ASSERT_EQ(0, cv::norm(cv::Mat(5, 5, CV_8UC3, cv::Scalar::all(250)), destImage, cv::NORM_INF));
- }
- TEST(Subtract, scalarc4_matc4)
- {
- cv::Scalar sc(255, 255, 255, 255);
- cv::Mat srcImage(5, 5, CV_8UC4, cv::Scalar::all(5)), destImage;
- cv::subtract(sc, srcImage, destImage);
- ASSERT_EQ(0, cv::norm(cv::Mat(5, 5, CV_8UC4, cv::Scalar::all(250)), destImage, cv::NORM_INF));
- }
- TEST(Compare, empty)
- {
- cv::Mat temp, dst1, dst2;
- EXPECT_NO_THROW(cv::compare(temp, temp, dst1, cv::CMP_EQ));
- EXPECT_TRUE(dst1.empty());
- EXPECT_THROW(dst2 = temp > 5, cv::Exception);
- }
- TEST(Compare, regression_8999)
- {
- Mat_<double> A(4,1); A << 1, 3, 2, 4;
- Mat_<double> B(1,1); B << 2;
- Mat C;
- EXPECT_THROW(cv::compare(A, B, C, CMP_LT), cv::Exception);
- }
- TEST(Compare, regression_16F_do_not_crash)
- {
- cv::Mat mat1(2, 2, CV_16F, cv::Scalar(1));
- cv::Mat mat2(2, 2, CV_16F, cv::Scalar(2));
- cv::Mat dst;
- EXPECT_THROW(cv::compare(mat1, mat2, dst, cv::CMP_EQ), cv::Exception);
- }
- TEST(Core_minMaxIdx, regression_9207_1)
- {
- const int rows = 4;
- const int cols = 3;
- uchar mask_[rows*cols] = {
- 255, 255, 255,
- 255, 0, 255,
- 0, 255, 255,
- 0, 0, 255
- };
- uchar src_[rows*cols] = {
- 1, 1, 1,
- 1, 1, 1,
- 2, 1, 1,
- 2, 2, 1
- };
- Mat mask(Size(cols, rows), CV_8UC1, mask_);
- Mat src(Size(cols, rows), CV_8UC1, src_);
- double minVal = -0.0, maxVal = -0.0;
- int minIdx[2] = { -2, -2 }, maxIdx[2] = { -2, -2 };
- cv::minMaxIdx(src, &minVal, &maxVal, minIdx, maxIdx, mask);
- EXPECT_EQ(0, minIdx[0]);
- EXPECT_EQ(0, minIdx[1]);
- EXPECT_EQ(0, maxIdx[0]);
- EXPECT_EQ(0, maxIdx[1]);
- }
- class TransposeND : public testing::TestWithParam< tuple<std::vector<int>, perf::MatType> >
- {
- public:
- std::vector<int> m_shape;
- int m_type;
- void SetUp()
- {
- std::tie(m_shape, m_type) = GetParam();
- }
- };
- TEST_P(TransposeND, basic)
- {
- Mat inp(m_shape, m_type);
- randu(inp, 0, 255);
- std::vector<int> order(m_shape.size());
- std::iota(order.begin(), order.end(), 0);
- auto transposer = [&order] (const std::vector<int>& id)
- {
- std::vector<int> ret(id.size());
- for (size_t i = 0; i < id.size(); ++i)
- {
- ret[i] = id[order[i]];
- }
- return ret;
- };
- auto advancer = [&inp] (std::vector<int>& id)
- {
- for (int j = static_cast<int>(id.size() - 1); j >= 0; --j)
- {
- ++id[j];
- if (id[j] != inp.size[j])
- {
- break;
- }
- id[j] = 0;
- }
- };
- do
- {
- Mat out;
- cv::transposeND(inp, order, out);
- std::vector<int> id(order.size());
- for (size_t i = 0; i < inp.total(); ++i)
- {
- auto new_id = transposer(id);
- switch (inp.type())
- {
- case CV_8UC1:
- ASSERT_EQ(inp.at<uint8_t>(id.data()), out.at<uint8_t>(new_id.data()));
- break;
- case CV_32FC1:
- ASSERT_EQ(inp.at<float>(id.data()), out.at<float>(new_id.data()));
- break;
- default:
- FAIL() << "Unsupported type: " << inp.type();
- }
- advancer(id);
- }
- } while (std::next_permutation(order.begin(), order.end()));
- }
- INSTANTIATE_TEST_CASE_P(Arithm, TransposeND, testing::Combine(
- testing::Values(std::vector<int>{2, 3, 4}, std::vector<int>{5, 10}),
- testing::Values(perf::MatType(CV_8UC1), CV_32FC1)
- ));
- class FlipND : public testing::TestWithParam< tuple<std::vector<int>, perf::MatType> >
- {
- public:
- std::vector<int> m_shape;
- int m_type;
- void SetUp()
- {
- std::tie(m_shape, m_type) = GetParam();
- }
- };
- TEST_P(FlipND, basic)
- {
- Mat inp(m_shape, m_type);
- randu(inp, 0, 255);
- int ndim = static_cast<int>(m_shape.size());
- std::vector<int> axes(ndim*2); // [-shape, shape)
- std::iota(axes.begin(), axes.end(), -ndim);
- auto get_flipped_indices = [&inp, ndim] (size_t total, std::vector<int>& indices, int axis)
- {
- const int* shape = inp.size.p;
- size_t t = total, idx;
- for (int i = ndim - 1; i >= 0; --i)
- {
- idx = t / shape[i];
- indices[i] = int(t - idx * shape[i]);
- t = idx;
- }
- int _axis = (axis + ndim) % ndim;
- std::vector<int> flipped_indices = indices;
- flipped_indices[_axis] = shape[_axis] - 1 - indices[_axis];
- return flipped_indices;
- };
- for (size_t i = 0; i < axes.size(); ++i)
- {
- int axis = axes[i];
- Mat out;
- cv::flipND(inp, out, axis);
- // check values
- std::vector<int> indices(ndim, 0);
- for (size_t j = 0; j < inp.total(); ++j)
- {
- auto flipped_indices = get_flipped_indices(j, indices, axis);
- switch (inp.type())
- {
- case CV_8UC1:
- ASSERT_EQ(inp.at<uint8_t>(indices.data()), out.at<uint8_t>(flipped_indices.data()));
- break;
- case CV_32FC1:
- ASSERT_EQ(inp.at<float>(indices.data()), out.at<float>(flipped_indices.data()));
- break;
- default:
- FAIL() << "Unsupported type: " << inp.type();
- }
- }
- }
- }
- INSTANTIATE_TEST_CASE_P(Arithm, FlipND, testing::Combine(
- testing::Values(std::vector<int>{5, 10}, std::vector<int>{2, 3, 4}),
- testing::Values(perf::MatType(CV_8UC1), CV_32FC1)
- ));
- TEST(BroadcastTo, basic) {
- std::vector<int> shape_src{2, 1};
- std::vector<int> data_src{1, 2};
- Mat src(static_cast<int>(shape_src.size()), shape_src.data(), CV_32SC1, data_src.data());
- auto get_index = [](const std::vector<int>& shape, size_t cnt) {
- std::vector<int> index(shape.size());
- size_t t = cnt;
- for (int i = static_cast<int>(shape.size() - 1); i >= 0; --i) {
- size_t idx = t / shape[i];
- index[i] = static_cast<int>(t - idx * shape[i]);
- t = idx;
- }
- return index;
- };
- auto fn_verify = [&get_index](const Mat& ref, const Mat& res) {
- // check type
- EXPECT_EQ(ref.type(), res.type());
- // check shape
- EXPECT_EQ(ref.dims, res.dims);
- for (int i = 0; i < ref.dims; ++i) {
- EXPECT_EQ(ref.size[i], res.size[i]);
- }
- // check value
- std::vector<int> shape{ref.size.p, ref.size.p + ref.dims};
- for (size_t i = 0; i < ref.total(); ++i) {
- auto index = get_index(shape, i);
- switch (ref.type()) {
- case CV_32SC1: {
- ASSERT_EQ(ref.at<int>(index.data()), res.at<int>(index.data()));
- } break;
- case CV_8UC1: {
- ASSERT_EQ(ref.at<uint8_t>(index.data()), res.at<uint8_t>(index.data()));
- } break;
- case CV_32FC1: {
- ASSERT_EQ(ref.at<float>(index.data()), res.at<float>(index.data()));
- } break;
- default: FAIL() << "Unsupported type: " << ref.type();
- }
- }
- };
- {
- std::vector<int> shape{4, 2, 3};
- std::vector<int> data_ref{
- 1, 1, 1, // [0, 0, :]
- 2, 2, 2, // [0, 1, :]
- 1, 1, 1, // [1, 0, :]
- 2, 2, 2, // [1, 1, :]
- 1, 1, 1, // [2, 0, :]
- 2, 2, 2, // [2, 1, :]
- 1, 1, 1, // [3, 0, :]
- 2, 2, 2 // [3, 1, :]
- };
- Mat ref(static_cast<int>(shape.size()), shape.data(), src.type(), data_ref.data());
- Mat dst;
- broadcast(src, shape, dst);
- fn_verify(ref, dst);
- }
- {
- Mat _src;
- src.convertTo(_src, CV_8U);
- std::vector<int> shape{4, 2, 3};
- std::vector<uint8_t> data_ref{
- 1, 1, 1, // [0, 0, :]
- 2, 2, 2, // [0, 1, :]
- 1, 1, 1, // [1, 0, :]
- 2, 2, 2, // [1, 1, :]
- 1, 1, 1, // [2, 0, :]
- 2, 2, 2, // [2, 1, :]
- 1, 1, 1, // [3, 0, :]
- 2, 2, 2 // [3, 1, :]
- };
- Mat ref(static_cast<int>(shape.size()), shape.data(), _src.type(), data_ref.data());
- Mat dst;
- broadcast(_src, shape, dst);
- fn_verify(ref, dst);
- }
- {
- Mat _src;
- src.convertTo(_src, CV_32F);
- std::vector<int> shape{1, 1, 2, 1}; // {2, 1}
- std::vector<float> data_ref{
- 1.f, // [0, 0, 0, 0]
- 2.f, // [0, 0, 1, 0]
- };
- Mat ref(static_cast<int>(shape.size()), shape.data(), _src.type(), data_ref.data());
- Mat dst;
- broadcast(_src, shape, dst);
- fn_verify(ref, dst);
- }
- {
- std::vector<int> _shape_src{2, 3, 4};
- std::vector<float> _data_src{
- 1.f, 2.f, 3.f, 4.f, // [0, 0, :]
- 2.f, 3.f, 4.f, 5.f, // [0, 1, :]
- 3.f, 4.f, 5.f, 6.f, // [0, 2, :]
- 4.f, 5.f, 6.f, 7.f, // [1, 0, :]
- 5.f, 6.f, 7.f, 8.f, // [1, 1, :]
- 6.f, 7.f, 8.f, 9.f, // [1, 2, :]
- };
- Mat _src(static_cast<int>(_shape_src.size()), _shape_src.data(), CV_32FC1, _data_src.data());
- std::vector<int> shape{2, 1, 2, 3, 4};
- std::vector<float> data_ref{
- 1.f, 2.f, 3.f, 4.f, // [0, 0, 0, 0, :]
- 2.f, 3.f, 4.f, 5.f, // [0, 0, 0, 1, :]
- 3.f, 4.f, 5.f, 6.f, // [0, 0, 0, 2, :]
- 4.f, 5.f, 6.f, 7.f, // [0, 0, 1, 0, :]
- 5.f, 6.f, 7.f, 8.f, // [0, 0, 1, 1, :]
- 6.f, 7.f, 8.f, 9.f, // [0, 0, 1, 2, :]
- 1.f, 2.f, 3.f, 4.f, // [1, 0, 0, 0, :]
- 2.f, 3.f, 4.f, 5.f, // [1, 0, 0, 1, :]
- 3.f, 4.f, 5.f, 6.f, // [1, 0, 0, 2, :]
- 4.f, 5.f, 6.f, 7.f, // [1, 0, 1, 0, :]
- 5.f, 6.f, 7.f, 8.f, // [1, 0, 1, 1, :]
- 6.f, 7.f, 8.f, 9.f, // [1, 0, 1, 2, :]
- };
- Mat ref(static_cast<int>(shape.size()), shape.data(), _src.type(), data_ref.data());
- Mat dst;
- broadcast(_src, shape, dst);
- fn_verify(ref, dst);
- }
- }
- TEST(Core_minMaxIdx, regression_9207_2)
- {
- const int rows = 13;
- const int cols = 15;
- uchar mask_[rows*cols] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
- 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
- 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255,
- 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255, 255,
- 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 0,
- 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 0,
- 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 255, 255, 0,
- 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255, 0,
- 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
- uchar src_[15*13] = {
- 5, 5, 5, 5, 5, 6, 5, 2, 0, 4, 6, 6, 4, 1, 0,
- 6, 5, 4, 4, 5, 6, 6, 5, 2, 0, 4, 6, 5, 2, 0,
- 3, 2, 1, 1, 2, 4, 6, 6, 4, 2, 3, 4, 4, 2, 0,
- 1, 0, 0, 0, 0, 1, 4, 5, 4, 4, 4, 4, 3, 2, 0,
- 0, 0, 0, 0, 0, 0, 2, 3, 4, 4, 4, 3, 2, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 3, 2, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 3, 3, 1, 0, 1,
- 0, 0, 0, 0, 0, 0, 1, 4, 5, 6, 5, 4, 3, 2, 0,
- 1, 0, 0, 0, 0, 0, 3, 5, 5, 4, 3, 4, 4, 3, 0,
- 2, 0, 0, 0, 0, 2, 5, 6, 5, 2, 2, 5, 4, 3, 0
- };
- Mat mask(Size(cols, rows), CV_8UC1, mask_);
- Mat src(Size(cols, rows), CV_8UC1, src_);
- double minVal = -0.0, maxVal = -0.0;
- int minIdx[2] = { -2, -2 }, maxIdx[2] = { -2, -2 };
- cv::minMaxIdx(src, &minVal, &maxVal, minIdx, maxIdx, mask);
- EXPECT_EQ(0, minIdx[0]);
- EXPECT_EQ(14, minIdx[1]);
- EXPECT_EQ(0, maxIdx[0]);
- EXPECT_EQ(14, maxIdx[1]);
- }
- TEST(Core_MinMaxIdx, MatND)
- {
- const int shape[3] = {5,5,3};
- cv::Mat src = cv::Mat(3, shape, CV_8UC1);
- src.setTo(1);
- src.data[1] = 0;
- src.data[5*5*3-2] = 2;
- int minIdx[3];
- int maxIdx[3];
- double minVal, maxVal;
- cv::minMaxIdx(src, &minVal, &maxVal, minIdx, maxIdx);
- EXPECT_EQ(0, minVal);
- EXPECT_EQ(2, maxVal);
- EXPECT_EQ(0, minIdx[0]);
- EXPECT_EQ(0, minIdx[1]);
- EXPECT_EQ(1, minIdx[2]);
- EXPECT_EQ(4, maxIdx[0]);
- EXPECT_EQ(4, maxIdx[1]);
- EXPECT_EQ(1, maxIdx[2]);
- }
- TEST(Core_Set, regression_11044)
- {
- Mat testFloat(Size(3, 3), CV_32FC1);
- Mat testDouble(Size(3, 3), CV_64FC1);
- testFloat.setTo(1);
- EXPECT_EQ(1, testFloat.at<float>(0,0));
- testFloat.setTo(std::numeric_limits<float>::infinity());
- EXPECT_EQ(std::numeric_limits<float>::infinity(), testFloat.at<float>(0, 0));
- testFloat.setTo(1);
- EXPECT_EQ(1, testFloat.at<float>(0, 0));
- testFloat.setTo(std::numeric_limits<double>::infinity());
- EXPECT_EQ(std::numeric_limits<float>::infinity(), testFloat.at<float>(0, 0));
- testDouble.setTo(1);
- EXPECT_EQ(1, testDouble.at<double>(0, 0));
- testDouble.setTo(std::numeric_limits<float>::infinity());
- EXPECT_EQ(std::numeric_limits<double>::infinity(), testDouble.at<double>(0, 0));
- testDouble.setTo(1);
- EXPECT_EQ(1, testDouble.at<double>(0, 0));
- testDouble.setTo(std::numeric_limits<double>::infinity());
- EXPECT_EQ(std::numeric_limits<double>::infinity(), testDouble.at<double>(0, 0));
- Mat testMask(Size(3, 3), CV_8UC1, Scalar(1));
- testFloat.setTo(1);
- EXPECT_EQ(1, testFloat.at<float>(0, 0));
- testFloat.setTo(std::numeric_limits<float>::infinity(), testMask);
- EXPECT_EQ(std::numeric_limits<float>::infinity(), testFloat.at<float>(0, 0));
- testFloat.setTo(1);
- EXPECT_EQ(1, testFloat.at<float>(0, 0));
- testFloat.setTo(std::numeric_limits<double>::infinity(), testMask);
- EXPECT_EQ(std::numeric_limits<float>::infinity(), testFloat.at<float>(0, 0));
- testDouble.setTo(1);
- EXPECT_EQ(1, testDouble.at<double>(0, 0));
- testDouble.setTo(std::numeric_limits<float>::infinity(), testMask);
- EXPECT_EQ(std::numeric_limits<double>::infinity(), testDouble.at<double>(0, 0));
- testDouble.setTo(1);
- EXPECT_EQ(1, testDouble.at<double>(0, 0));
- testDouble.setTo(std::numeric_limits<double>::infinity(), testMask);
- EXPECT_EQ(std::numeric_limits<double>::infinity(), testDouble.at<double>(0, 0));
- }
- TEST(Core_Norm, IPP_regression_NORM_L1_16UC3_small)
- {
- int cn = 3;
- Size sz(9, 4); // width < 16
- Mat a(sz, CV_MAKE_TYPE(CV_16U, cn), Scalar::all(1));
- Mat b(sz, CV_MAKE_TYPE(CV_16U, cn), Scalar::all(2));
- uchar mask_[9*4] = {
- 255, 255, 255, 0, 255, 255, 0, 255, 0,
- 0, 255, 0, 0, 255, 255, 255, 255, 0,
- 0, 0, 0, 255, 0, 255, 0, 255, 255,
- 0, 0, 255, 0, 255, 255, 255, 0, 255
- };
- Mat mask(sz, CV_8UC1, mask_);
- EXPECT_EQ((double)9*4*cn, cv::norm(a, b, NORM_L1)); // without mask, IPP works well
- EXPECT_EQ((double)20*cn, cv::norm(a, b, NORM_L1, mask));
- }
- TEST(Core_Norm, NORM_L2_8UC4)
- {
- // Tests there is no integer overflow in norm computation for multiple channels.
- const int kSide = 100;
- cv::Mat4b a(kSide, kSide, cv::Scalar(255, 255, 255, 255));
- cv::Mat4b b = cv::Mat4b::zeros(kSide, kSide);
- const double kNorm = 2.*kSide*255.;
- EXPECT_EQ(kNorm, cv::norm(a, b, NORM_L2));
- }
- TEST(Core_ConvertTo, regression_12121)
- {
- {
- Mat src(4, 64, CV_32SC1, Scalar(-1));
- Mat dst;
- src.convertTo(dst, CV_8U);
- EXPECT_EQ(0, dst.at<uchar>(0, 0)) << "src=" << src.at<int>(0, 0);
- }
- {
- Mat src(4, 64, CV_32SC1, Scalar(INT_MIN));
- Mat dst;
- src.convertTo(dst, CV_8U);
- EXPECT_EQ(0, dst.at<uchar>(0, 0)) << "src=" << src.at<int>(0, 0);
- }
- {
- Mat src(4, 64, CV_32SC1, Scalar(INT_MIN + 32767));
- Mat dst;
- src.convertTo(dst, CV_8U);
- EXPECT_EQ(0, dst.at<uchar>(0, 0)) << "src=" << src.at<int>(0, 0);
- }
- {
- Mat src(4, 64, CV_32SC1, Scalar(INT_MIN + 32768));
- Mat dst;
- src.convertTo(dst, CV_8U);
- EXPECT_EQ(0, dst.at<uchar>(0, 0)) << "src=" << src.at<int>(0, 0);
- }
- {
- Mat src(4, 64, CV_32SC1, Scalar(32768));
- Mat dst;
- src.convertTo(dst, CV_8U);
- EXPECT_EQ(255, dst.at<uchar>(0, 0)) << "src=" << src.at<int>(0, 0);
- }
- {
- Mat src(4, 64, CV_32SC1, Scalar(INT_MIN));
- Mat dst;
- src.convertTo(dst, CV_16U);
- EXPECT_EQ(0, dst.at<ushort>(0, 0)) << "src=" << src.at<int>(0, 0);
- }
- {
- Mat src(4, 64, CV_32SC1, Scalar(INT_MIN + 32767));
- Mat dst;
- src.convertTo(dst, CV_16U);
- EXPECT_EQ(0, dst.at<ushort>(0, 0)) << "src=" << src.at<int>(0, 0);
- }
- {
- Mat src(4, 64, CV_32SC1, Scalar(INT_MIN + 32768));
- Mat dst;
- src.convertTo(dst, CV_16U);
- EXPECT_EQ(0, dst.at<ushort>(0, 0)) << "src=" << src.at<int>(0, 0);
- }
- {
- Mat src(4, 64, CV_32SC1, Scalar(65536));
- Mat dst;
- src.convertTo(dst, CV_16U);
- EXPECT_EQ(65535, dst.at<ushort>(0, 0)) << "src=" << src.at<int>(0, 0);
- }
- }
- TEST(Core_MeanStdDev, regression_multichannel)
- {
- {
- uchar buf[] = { 1, 2, 3, 4, 5, 6, 7, 8,
- 3, 4, 5, 6, 7, 8, 9, 10 };
- double ref_buf[] = { 2., 3., 4., 5., 6., 7., 8., 9.,
- 1., 1., 1., 1., 1., 1., 1., 1. };
- Mat src(1, 2, CV_MAKETYPE(CV_8U, 8), buf);
- Mat ref_m(8, 1, CV_64FC1, ref_buf);
- Mat ref_sd(8, 1, CV_64FC1, ref_buf + 8);
- Mat dst_m, dst_sd;
- meanStdDev(src, dst_m, dst_sd);
- EXPECT_EQ(0, cv::norm(dst_m, ref_m, NORM_L1));
- EXPECT_EQ(0, cv::norm(dst_sd, ref_sd, NORM_L1));
- }
- }
- // Related issue : https://github.com/opencv/opencv/issues/26861
- TEST(Core_MeanStdDevTest, LargeImage)
- {
- applyTestTag(CV_TEST_TAG_VERYLONG);
- applyTestTag(CV_TEST_TAG_MEMORY_14GB);
- // (1<<16) * ((1<<15)+10) = ~2.147 billion
- cv::Mat largeImage = cv::Mat::ones((1 << 16), ((1 << 15) + 10), CV_8U);
- cv::Scalar mean, stddev;
- cv::meanStdDev(largeImage, mean, stddev);
- EXPECT_NEAR(mean[0], 1.0, 1e-5);
- EXPECT_NEAR(stddev[0], 0.0, 1e-5);
- }
- template <typename T> static inline
- void testDivideInitData(Mat& src1, Mat& src2)
- {
- CV_StaticAssert(std::numeric_limits<T>::is_integer, "");
- const static T src1_[] = {
- 0, 0, 0, 0,
- 8, 8, 8, 8,
- -8, -8, -8, -8
- };
- Mat(3, 4, traits::Type<T>::value, (void*)src1_).copyTo(src1);
- const static T src2_[] = {
- 1, 2, 0, std::numeric_limits<T>::max(),
- 1, 2, 0, std::numeric_limits<T>::max(),
- 1, 2, 0, std::numeric_limits<T>::max(),
- };
- Mat(3, 4, traits::Type<T>::value, (void*)src2_).copyTo(src2);
- }
- template <typename T> static inline
- void testDivideInitDataFloat(Mat& src1, Mat& src2)
- {
- CV_StaticAssert(!std::numeric_limits<T>::is_integer, "");
- const static T src1_[] = {
- 0, 0, 0, 0,
- 8, 8, 8, 8,
- -8, -8, -8, -8
- };
- Mat(3, 4, traits::Type<T>::value, (void*)src1_).copyTo(src1);
- const static T src2_[] = {
- 1, 2, 0, std::numeric_limits<T>::infinity(),
- 1, 2, 0, std::numeric_limits<T>::infinity(),
- 1, 2, 0, std::numeric_limits<T>::infinity(),
- };
- Mat(3, 4, traits::Type<T>::value, (void*)src2_).copyTo(src2);
- }
- template <> inline void testDivideInitData<float>(Mat& src1, Mat& src2) { testDivideInitDataFloat<float>(src1, src2); }
- template <> inline void testDivideInitData<double>(Mat& src1, Mat& src2) { testDivideInitDataFloat<double>(src1, src2); }
- template <typename T> static inline
- void testDivideChecks(const Mat& dst)
- {
- ASSERT_FALSE(dst.empty());
- CV_StaticAssert(std::numeric_limits<T>::is_integer, "");
- for (int y = 0; y < dst.rows; y++)
- {
- for (int x = 0; x < dst.cols; x++)
- {
- if ((x % 4) == 2)
- {
- EXPECT_EQ(0, dst.at<T>(y, x)) << "dst(" << y << ", " << x << ") = " << dst.at<T>(y, x);
- }
- else
- {
- EXPECT_TRUE(0 == cvIsNaN((double)dst.at<T>(y, x))) << "dst(" << y << ", " << x << ") = " << dst.at<T>(y, x);
- EXPECT_TRUE(0 == cvIsInf((double)dst.at<T>(y, x))) << "dst(" << y << ", " << x << ") = " << dst.at<T>(y, x);
- }
- }
- }
- }
- template <typename T> static inline
- void testDivideChecksFP(const Mat& dst)
- {
- ASSERT_FALSE(dst.empty());
- CV_StaticAssert(!std::numeric_limits<T>::is_integer, "");
- for (int y = 0; y < dst.rows; y++)
- {
- for (int x = 0; x < dst.cols; x++)
- {
- if ((y % 3) == 0 && (x % 4) == 2)
- {
- EXPECT_TRUE(cvIsNaN(dst.at<T>(y, x))) << "dst(" << y << ", " << x << ") = " << dst.at<T>(y, x);
- }
- else if ((x % 4) == 2)
- {
- EXPECT_TRUE(cvIsInf(dst.at<T>(y, x))) << "dst(" << y << ", " << x << ") = " << dst.at<T>(y, x);
- }
- else
- {
- EXPECT_FALSE(cvIsNaN(dst.at<T>(y, x))) << "dst(" << y << ", " << x << ") = " << dst.at<T>(y, x);
- EXPECT_FALSE(cvIsInf(dst.at<T>(y, x))) << "dst(" << y << ", " << x << ") = " << dst.at<T>(y, x);
- }
- }
- }
- }
- template <> inline void testDivideChecks<float>(const Mat& dst) { testDivideChecksFP<float>(dst); }
- template <> inline void testDivideChecks<double>(const Mat& dst) { testDivideChecksFP<double>(dst); }
- template <typename T> static inline
- void testDivide(bool isUMat, double scale, bool largeSize, bool tailProcessing, bool roi)
- {
- Mat src1, src2;
- testDivideInitData<T>(src1, src2);
- ASSERT_FALSE(src1.empty()); ASSERT_FALSE(src2.empty());
- if (largeSize)
- {
- repeat(src1.clone(), 1, 8, src1);
- repeat(src2.clone(), 1, 8, src2);
- }
- if (tailProcessing)
- {
- src1 = src1(Rect(0, 0, src1.cols - 1, src1.rows));
- src2 = src2(Rect(0, 0, src2.cols - 1, src2.rows));
- }
- if (!roi && tailProcessing)
- {
- src1 = src1.clone();
- src2 = src2.clone();
- }
- Mat dst;
- if (!isUMat)
- {
- cv::divide(src1, src2, dst, scale);
- }
- else
- {
- UMat usrc1, usrc2, udst;
- src1.copyTo(usrc1);
- src2.copyTo(usrc2);
- cv::divide(usrc1, usrc2, udst, scale);
- udst.copyTo(dst);
- }
- testDivideChecks<T>(dst);
- if (::testing::Test::HasFailure())
- {
- std::cout << "src1 = " << std::endl << src1 << std::endl;
- std::cout << "src2 = " << std::endl << src2 << std::endl;
- std::cout << "dst = " << std::endl << dst << std::endl;
- }
- }
- typedef tuple<bool, double, bool, bool, bool> DivideRulesParam;
- typedef testing::TestWithParam<DivideRulesParam> Core_DivideRules;
- TEST_P(Core_DivideRules, type_32s)
- {
- DivideRulesParam param = GetParam();
- testDivide<int>(get<0>(param), get<1>(param), get<2>(param), get<3>(param), get<4>(param));
- }
- TEST_P(Core_DivideRules, type_16s)
- {
- DivideRulesParam param = GetParam();
- testDivide<short>(get<0>(param), get<1>(param), get<2>(param), get<3>(param), get<4>(param));
- }
- TEST_P(Core_DivideRules, type_32f)
- {
- DivideRulesParam param = GetParam();
- testDivide<float>(get<0>(param), get<1>(param), get<2>(param), get<3>(param), get<4>(param));
- }
- TEST_P(Core_DivideRules, type_64f)
- {
- DivideRulesParam param = GetParam();
- testDivide<double>(get<0>(param), get<1>(param), get<2>(param), get<3>(param), get<4>(param));
- }
- INSTANTIATE_TEST_CASE_P(/* */, Core_DivideRules, testing::Combine(
- /* isMat */ testing::Values(false),
- /* scale */ testing::Values(1.0, 5.0),
- /* largeSize */ testing::Bool(),
- /* tail */ testing::Bool(),
- /* roi */ testing::Bool()
- ));
- INSTANTIATE_TEST_CASE_P(UMat, Core_DivideRules, testing::Combine(
- /* isMat */ testing::Values(true),
- /* scale */ testing::Values(1.0, 5.0),
- /* largeSize */ testing::Bool(),
- /* tail */ testing::Bool(),
- /* roi */ testing::Bool()
- ));
- TEST(Core_MinMaxIdx, rows_overflow)
- {
- const int N = 65536 + 1;
- const int M = 1;
- {
- setRNGSeed(123);
- Mat m(N, M, CV_32FC1);
- randu(m, -100, 100);
- double minVal = 0, maxVal = 0;
- int minIdx[CV_MAX_DIM] = { 0 }, maxIdx[CV_MAX_DIM] = { 0 };
- cv::minMaxIdx(m, &minVal, &maxVal, minIdx, maxIdx);
- double minVal0 = 0, maxVal0 = 0;
- int minIdx0[CV_MAX_DIM] = { 0 }, maxIdx0[CV_MAX_DIM] = { 0 };
- cv::ipp::setUseIPP(false);
- cv::minMaxIdx(m, &minVal0, &maxVal0, minIdx0, maxIdx0);
- cv::ipp::setUseIPP(true);
- EXPECT_FALSE(fabs(minVal0 - minVal) > 1e-6 || fabs(maxVal0 - maxVal) > 1e-6) << "NxM=" << N << "x" << M <<
- " min=" << minVal0 << " vs " << minVal <<
- " max=" << maxVal0 << " vs " << maxVal;
- }
- }
- TEST(Core_Magnitude, regression_19506)
- {
- for (int N = 1; N <= 64; ++N)
- {
- Mat a(1, N, CV_32FC1, Scalar::all(1e-20));
- Mat res;
- magnitude(a, a, res);
- EXPECT_LE(cvtest::norm(res, NORM_L1), 1e-15) << N;
- }
- }
- PARAM_TEST_CASE(Core_CartPolar_reverse, int, bool)
- {
- int depth;
- bool angleInDegrees;
- virtual void SetUp()
- {
- depth = GET_PARAM(0);
- angleInDegrees = GET_PARAM(1);
- }
- };
- TEST_P(Core_CartPolar_reverse, reverse)
- {
- const int type = CV_MAKETYPE(depth, 1);
- cv::Mat A[2] = {cv::Mat(10, 10, type), cv::Mat(10, 10, type)};
- cv::Mat B[2], C[2];
- cv::UMat uA[2];
- cv::UMat uB[2];
- cv::UMat uC[2];
- for(int i = 0; i < 2; ++i)
- {
- cvtest::randUni(rng, A[i], Scalar::all(-1000), Scalar::all(1000));
- A[i].copyTo(uA[i]);
- }
- // Reverse
- cv::cartToPolar(A[0], A[1], B[0], B[1], angleInDegrees);
- cv::polarToCart(B[0], B[1], C[0], C[1], angleInDegrees);
- EXPECT_MAT_NEAR(A[0], C[0], 2);
- EXPECT_MAT_NEAR(A[1], C[1], 2);
- }
- INSTANTIATE_TEST_CASE_P(Core_CartPolar, Core_CartPolar_reverse,
- testing::Combine(
- testing::Values(CV_32F, CV_64F),
- testing::Values(false, true)
- )
- );
- PARAM_TEST_CASE(Core_CartToPolar_inplace, int, bool)
- {
- int depth;
- bool angleInDegrees;
- virtual void SetUp()
- {
- depth = GET_PARAM(0);
- angleInDegrees = GET_PARAM(1);
- }
- };
- TEST_P(Core_CartToPolar_inplace, inplace)
- {
- const int type = CV_MAKETYPE(depth, 1);
- cv::Mat A[2] = {cv::Mat(10, 10, type), cv::Mat(10, 10, type)};
- cv::Mat B[2], C[2];
- cv::UMat uA[2];
- cv::UMat uB[2];
- cv::UMat uC[2];
- for(int i = 0; i < 2; ++i)
- {
- cvtest::randUni(rng, A[i], Scalar::all(-1000), Scalar::all(1000));
- A[i].copyTo(uA[i]);
- }
- // Inplace x<->mag y<->angle
- for(int i = 0; i < 2; ++i)
- A[i].copyTo(B[i]);
- cv::cartToPolar(A[0], A[1], C[0], C[1], angleInDegrees);
- cv::cartToPolar(B[0], B[1], B[0], B[1], angleInDegrees);
- EXPECT_MAT_NEAR(C[0], B[0], 2);
- EXPECT_MAT_NEAR(C[1], B[1], 2);
- // Inplace x<->angle y<->mag
- for(int i = 0; i < 2; ++i)
- A[i].copyTo(B[i]);
- cv::cartToPolar(A[0], A[1], C[0], C[1], angleInDegrees);
- cv::cartToPolar(B[0], B[1], B[1], B[0], angleInDegrees);
- EXPECT_MAT_NEAR(C[0], B[1], 2);
- EXPECT_MAT_NEAR(C[1], B[0], 2);
- // Inplace OCL x<->mag y<->angle
- for(int i = 0; i < 2; ++i)
- uA[i].copyTo(uB[i]);
- cv::cartToPolar(uA[0], uA[1], uC[0], uC[1], angleInDegrees);
- cv::cartToPolar(uB[0], uB[1], uB[0], uB[1], angleInDegrees);
- EXPECT_MAT_NEAR(uC[0], uB[0], 2);
- EXPECT_MAT_NEAR(uC[1], uB[1], 2);
- // Inplace OCL x<->angle y<->mag
- for(int i = 0; i < 2; ++i)
- uA[i].copyTo(uB[i]);
- cv::cartToPolar(uA[0], uA[1], uC[0], uC[1], angleInDegrees);
- cv::cartToPolar(uB[0], uB[1], uB[1], uB[0], angleInDegrees);
- EXPECT_MAT_NEAR(uC[0], uB[1], 2);
- EXPECT_MAT_NEAR(uC[1], uB[0], 2);
- }
- INSTANTIATE_TEST_CASE_P(Core_CartPolar, Core_CartToPolar_inplace,
- testing::Combine(
- testing::Values(CV_32F, CV_64F),
- testing::Values(false, true)
- )
- );
- PARAM_TEST_CASE(Core_PolarToCart_inplace, int, bool, bool)
- {
- int depth;
- bool angleInDegrees;
- bool implicitMagnitude;
- virtual void SetUp()
- {
- depth = GET_PARAM(0);
- angleInDegrees = GET_PARAM(1);
- implicitMagnitude = GET_PARAM(2);
- }
- };
- TEST_P(Core_PolarToCart_inplace, inplace)
- {
- const int type = CV_MAKETYPE(depth, 1);
- cv::Mat A[2] = {cv::Mat(10, 10, type), cv::Mat(10, 10, type)};
- cv::Mat B[2], C[2];
- cv::UMat uA[2];
- cv::UMat uB[2];
- cv::UMat uC[2];
- for(int i = 0; i < 2; ++i)
- {
- cvtest::randUni(rng, A[i], Scalar::all(-1000), Scalar::all(1000));
- A[i].copyTo(uA[i]);
- }
- // Inplace OCL x<->mag y<->angle
- for(int i = 0; i < 2; ++i)
- A[i].copyTo(B[i]);
- cv::polarToCart(implicitMagnitude ? cv::noArray() : A[0], A[1], C[0], C[1], angleInDegrees);
- cv::polarToCart(implicitMagnitude ? cv::noArray() : B[0], B[1], B[0], B[1], angleInDegrees);
- EXPECT_MAT_NEAR(C[0], B[0], 2);
- EXPECT_MAT_NEAR(C[1], B[1], 2);
- // Inplace OCL x<->angle y<->mag
- for(int i = 0; i < 2; ++i)
- A[i].copyTo(B[i]);
- cv::polarToCart(implicitMagnitude ? cv::noArray() : A[0], A[1], C[0], C[1], angleInDegrees);
- cv::polarToCart(implicitMagnitude ? cv::noArray() : B[0], B[1], B[1], B[0], angleInDegrees);
- EXPECT_MAT_NEAR(C[0], B[1], 2);
- EXPECT_MAT_NEAR(C[1], B[0], 2);
- // Inplace OCL x<->mag y<->angle
- for(int i = 0; i < 2; ++i)
- uA[i].copyTo(uB[i]);
- cv::polarToCart(implicitMagnitude ? cv::noArray() : uA[0], uA[1], uC[0], uC[1], angleInDegrees);
- cv::polarToCart(implicitMagnitude ? cv::noArray() : uB[0], uB[1], uB[0], uB[1], angleInDegrees);
- EXPECT_MAT_NEAR(uC[0], uB[0], 2);
- EXPECT_MAT_NEAR(uC[1], uB[1], 2);
- // Inplace OCL x<->angle y<->mag
- for(int i = 0; i < 2; ++i)
- uA[i].copyTo(uB[i]);
- cv::polarToCart(implicitMagnitude ? cv::noArray() : uA[0], uA[1], uC[0], uC[1], angleInDegrees);
- cv::polarToCart(implicitMagnitude ? cv::noArray() : uB[0], uB[1], uB[1], uB[0], angleInDegrees);
- EXPECT_MAT_NEAR(uC[0], uB[1], 2);
- EXPECT_MAT_NEAR(uC[1], uB[0], 2);
- }
- INSTANTIATE_TEST_CASE_P(Core_CartPolar, Core_PolarToCart_inplace,
- testing::Combine(
- testing::Values(CV_32F, CV_64F),
- testing::Values(false, true),
- testing::Values(true, false)
- )
- );
- CV_ENUM(LutIdxType, CV_8U, CV_8S, CV_16U, CV_16S)
- CV_ENUM(LutMatType, CV_8U, CV_8S, CV_16U, CV_16S, CV_32S, CV_32F, CV_64F, CV_16F)
- struct Core_LUT: public testing::TestWithParam< std::tuple<LutIdxType, LutMatType> >
- {
- template<typename Ti, typename T, int ch, bool same_cn>
- cv::Mat referenceWithType(cv::Mat input, cv::Mat table)
- {
- cv::Mat ref(input.size(), CV_MAKE_TYPE(table.depth(), ch));
- for (int i = 0; i < input.rows; i++)
- {
- for (int j = 0; j < input.cols; j++)
- {
- if(ch == 1)
- {
- ref.at<T>(i, j) = table.at<T>(input.at<Ti>(i, j));
- }
- else
- {
- Vec<T, ch> val;
- for (int k = 0; k < ch; k++)
- {
- if (same_cn)
- {
- val[k] = table.at<Vec<T, ch>>(input.at<Vec<Ti, ch>>(i, j)[k])[k];
- }
- else
- {
- val[k] = table.at<T>(input.at<Vec<Ti, ch>>(i, j)[k]);
- }
- }
- ref.at<Vec<T, ch>>(i, j) = val;
- }
- }
- }
- return ref;
- }
- template<int ch = 1, bool same_cn = false>
- cv::Mat reference(cv::Mat input, cv::Mat table)
- {
- cv::Mat ret = cv::Mat();
- if ((input.depth() == CV_8U) || (input.depth() == CV_8S)) // Index type for LUT operation
- {
- switch(table.depth()) // Value type for LUT operation
- {
- case CV_8U: ret = referenceWithType<uint8_t, uint8_t, ch, same_cn>(input, table); break;
- case CV_8S: ret = referenceWithType<uint8_t, int8_t, ch, same_cn>(input, table); break;
- case CV_16U: ret = referenceWithType<uint8_t, uint16_t, ch, same_cn>(input, table); break;
- case CV_16S: ret = referenceWithType<uint8_t, int16_t, ch, same_cn>(input, table); break;
- case CV_32S: ret = referenceWithType<uint8_t, int32_t, ch, same_cn>(input, table); break;
- case CV_32F: ret = referenceWithType<uint8_t, float, ch, same_cn>(input, table); break;
- case CV_64F: ret = referenceWithType<uint8_t, double, ch, same_cn>(input, table); break;
- case CV_16F: ret = referenceWithType<uint8_t, uint16_t, ch, same_cn>(input, table); break;
- default: ret = cv::Mat(); break;
- }
- }
- else if ((input.depth() == CV_16U) || (input.depth() == CV_16S))
- {
- switch(table.depth()) // Value type for LUT operation
- {
- case CV_8U: ret = referenceWithType<uint16_t, uint8_t, ch, same_cn>(input, table); break;
- case CV_8S: ret = referenceWithType<uint16_t, int8_t, ch, same_cn>(input, table); break;
- case CV_16U: ret = referenceWithType<uint16_t, uint16_t, ch, same_cn>(input, table); break;
- case CV_16S: ret = referenceWithType<uint16_t, int16_t, ch, same_cn>(input, table); break;
- case CV_32S: ret = referenceWithType<uint16_t, int32_t, ch, same_cn>(input, table); break;
- case CV_32F: ret = referenceWithType<uint16_t, float, ch, same_cn>(input, table); break;
- case CV_64F: ret = referenceWithType<uint16_t, double, ch, same_cn>(input, table); break;
- case CV_16F: ret = referenceWithType<uint16_t, uint16_t, ch, same_cn>(input, table); break;
- default: ret = cv::Mat(); break;
- }
- }
- return ret;
- }
- };
- TEST_P(Core_LUT, accuracy)
- {
- int idx_type = get<0>(GetParam());
- int value_type = get<1>(GetParam());
- ASSERT_TRUE((idx_type == CV_8U) || (idx_type == CV_8S) || (idx_type == CV_16U ) || (idx_type == CV_16S));
- const int tableSize = ((idx_type == CV_8U) || (idx_type == CV_8S)) ? 256: 65536;
- cv::Mat input(117, 113, CV_MAKE_TYPE(idx_type, 1));
- randu(input, getMinVal(idx_type), getMaxVal(idx_type));
- cv::Mat table(1, tableSize, CV_MAKE_TYPE(value_type, 1));
- randu(table, getMinVal(value_type), getMaxVal(value_type));
- cv::Mat output;
- ASSERT_NO_THROW(cv::LUT(input, table, output));
- ASSERT_FALSE(output.empty());
- cv::Mat gt = reference(input, table);
- ASSERT_FALSE(gt.empty());
- ASSERT_EQ(0, cv::norm(output, gt, cv::NORM_INF));
- }
- TEST_P(Core_LUT, accuracy_multi)
- {
- int idx_type = get<0>(GetParam());
- int value_type = get<1>(GetParam());
- ASSERT_TRUE((idx_type == CV_8U) || (idx_type == CV_8S) || (idx_type == CV_16U) || (idx_type == CV_16S));
- const int tableSize = ((idx_type == CV_8U) || (idx_type == CV_8S) ) ? 256: 65536;
- cv::Mat input(117, 113, CV_MAKE_TYPE(idx_type, 3));
- randu(input, getMinVal(idx_type), getMaxVal(idx_type));
- cv::Mat table(1, tableSize, CV_MAKE_TYPE(value_type, 1));
- randu(table, getMinVal(value_type), getMaxVal(value_type));
- cv::Mat output;
- ASSERT_NO_THROW(cv::LUT(input, table, output));
- ASSERT_FALSE(output.empty());
- cv::Mat gt = reference<3>(input, table);
- ASSERT_FALSE(gt.empty());
- ASSERT_EQ(0, cv::norm(output, gt, cv::NORM_INF));
- }
- TEST_P(Core_LUT, accuracy_multi2)
- {
- int idx_type = get<0>(GetParam());
- int value_type = get<1>(GetParam());
- ASSERT_TRUE((idx_type == CV_8U) || (idx_type == CV_8S) || (idx_type == CV_16U) || (idx_type == CV_16S));
- const int tableSize = ((idx_type == CV_8U) || (idx_type == CV_8S)) ? 256: 65536;
- cv::Mat input(117, 113, CV_MAKE_TYPE(idx_type, 3));
- randu(input, getMinVal(idx_type), getMaxVal(idx_type));
- cv::Mat table(1, tableSize, CV_MAKE_TYPE(value_type, 3));
- randu(table, getMinVal(value_type), getMaxVal(value_type));
- cv::Mat output;
- ASSERT_NO_THROW(cv::LUT(input, table, output));
- ASSERT_FALSE(output.empty());
- cv::Mat gt = reference<3, true>(input, table);
- ASSERT_FALSE(gt.empty());
- ASSERT_EQ(0, cv::norm(output, gt, cv::NORM_INF));
- }
- INSTANTIATE_TEST_CASE_P(/**/, Core_LUT, testing::Combine( LutIdxType::all(), LutMatType::all()));
- }} // namespace
|