commit
3165baa1f1
33 changed files with 3009 additions and 710 deletions
@ -0,0 +1,575 @@ |
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2016, OpenCV Foundation, all rights reserved.
|
||||
//
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "test_precomp.hpp" |
||||
#include "opencv2/calib3d.hpp" |
||||
|
||||
namespace opencv_test { namespace { |
||||
|
||||
class CV_FilterHomographyDecompTest : public cvtest::BaseTest { |
||||
|
||||
public: |
||||
CV_FilterHomographyDecompTest() |
||||
{ |
||||
buildTestDataSet(); |
||||
} |
||||
|
||||
protected: |
||||
void run(int) |
||||
{ |
||||
vector<int> finalSolutions; |
||||
filterHomographyDecompByVisibleRefpoints(_rotations, _normals, _prevRectifiedPoints, _currRectifiedPoints, finalSolutions, _mask); |
||||
|
||||
//there should be at least 2 solution
|
||||
ASSERT_EQ(finalSolutions, _validSolutions); |
||||
} |
||||
|
||||
private: |
||||
|
||||
void buildTestDataSet() |
||||
{ |
||||
double rotationsArray[4][9] = { |
||||
{ |
||||
0.98811084196540500, |
||||
-0.15276633082836735, |
||||
0.017303530150126534, |
||||
0.14161851662094097, |
||||
0.94821044891315664, |
||||
0.28432576443578628, |
||||
-0.059842791884259422, |
||||
-0.27849487021693553, |
||||
0.95857156619751127 |
||||
}, |
||||
{ |
||||
0.98811084196540500, |
||||
-0.15276633082836735, |
||||
0.017303530150126534, |
||||
0.14161851662094097, |
||||
0.94821044891315664, |
||||
0.28432576443578628, |
||||
-0.059842791884259422, |
||||
-0.27849487021693553, |
||||
0.95857156619751127 |
||||
}, |
||||
{ |
||||
0.95471096402077438, |
||||
-0.21080808634428211, |
||||
-0.20996886890771557, |
||||
0.20702063153797226, |
||||
0.97751379914116743, |
||||
-0.040115216641822840, |
||||
0.21370407880090386, |
||||
-0.0051694506925720751, |
||||
0.97688476468997820 |
||||
}, |
||||
{ |
||||
0.95471096402077438, |
||||
-0.21080808634428211, |
||||
-0.20996886890771557, |
||||
0.20702063153797226, |
||||
0.97751379914116743, |
||||
-0.040115216641822840, |
||||
0.21370407880090386, |
||||
-0.0051694506925720751, |
||||
0.97688476468997820 |
||||
} |
||||
}; |
||||
|
||||
double normalsArray[4][3] = { |
||||
{ |
||||
-0.023560516110791116, |
||||
0.085818414407956692, |
||||
0.99603217911325403 |
||||
}, |
||||
{ |
||||
0.023560516110791116, |
||||
-0.085818414407956692, |
||||
-0.99603217911325403 |
||||
}, |
||||
{ |
||||
-0.62483547397726014, |
||||
-0.56011861446691769, |
||||
0.54391889853844289 |
||||
}, |
||||
{ |
||||
0.62483547397726014, |
||||
0.56011861446691769, |
||||
-0.54391889853844289 |
||||
} |
||||
}; |
||||
|
||||
uchar maskArray[514] = |
||||
{ |
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, |
||||
0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, |
||||
1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, |
||||
0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, |
||||
0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, |
||||
1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, |
||||
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, |
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, |
||||
1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, |
||||
0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, |
||||
0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, |
||||
1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, |
||||
1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, |
||||
0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, |
||||
0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, |
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
||||
}; |
||||
|
||||
static const float currRectifiedPointArr[] = |
||||
{ |
||||
-0.565732896f, -0.321162999f, -0.416198403f, -0.299646467f, -0.408354312f, -0.290387660f, |
||||
-0.386555284f, -0.287677139f, -0.348475337f, -0.276208878f, -0.415957332f, -0.266133875f, |
||||
-0.354961902f, -0.257545590f, -0.420189440f, -0.255190015f, -0.379785866f, -0.252570540f, |
||||
-0.144345313f, -0.249134675f, -0.162417486f, -0.223227784f, -0.129876539f, -0.219722182f, |
||||
-0.470801264f, -0.211166814f, 0.0992607549f, -0.209064797f, 0.123508267f, -0.196303099f, |
||||
-0.521849990f, -0.190706849f, -0.513497114f, -0.189186409f, -0.534959674f, -0.185138911f, |
||||
0.121614374f, -0.182721153f, 0.154205695f, -0.183763996f, -0.516449869f, -0.181606859f, |
||||
-0.523427486f, -0.180088669f, 0.149494573f, -0.179563865f, -0.552187204f, -0.172630817f, |
||||
-0.322249800f, -0.172333881f, 0.127574071f, -0.165683150f, 0.159817487f, -0.162389070f, |
||||
-0.578930736f, -0.160272732f, -0.600617707f, -0.155920163f, -0.249115735f, -0.154711768f, |
||||
-0.543279886f, -0.144873798f, -0.529992998f, -0.142433196f, 0.0554505363f, -0.142878756f, |
||||
-0.613355398f, -0.132748783f, 0.190059289f, -0.128930226f, -0.255682647f, -0.127393380f, |
||||
0.0299431719f, -0.125339776f, -0.282943249f, -0.118550651f, -0.0348402821f, -0.115398556f, |
||||
-0.0362741761f, -0.110100254f, -0.319089264f, -0.104354575f, -0.0401916653f, -0.0852083191f, |
||||
-0.372183621f, -0.0812346712f, -0.00707253255f, -0.0810251758f, 0.267345309f, -0.0787685066f, |
||||
0.258760840f, -0.0768160895f, -0.377273679f, -0.0763452053f, -0.0314898677f, -0.0743160769f, |
||||
0.223423928f, -0.0724818707f, 0.00284322398f, -0.0720727518f, 0.232531011f, -0.0682833865f, |
||||
0.282355100f, -0.0655683428f, -0.233353317f, -0.0613981225f, 0.290982842f, -0.0607336313f, |
||||
-0.0994169787f, -0.0376472026f, 0.257561266f, -0.0331368558f, 0.265076399f, -0.0320781991f, |
||||
0.0454338901f, -0.0238198638f, 0.0409987904f, -0.0186991505f, -0.502306283f, -0.0172236171f, |
||||
-0.464807063f, -0.0149533665f, -0.185798749f, -0.00540314987f, 0.182073534f, -0.000651287497f, |
||||
-0.435764432f, 0.00162558386f, -0.181552932f, 0.00792864431f, -0.700565279f, 0.0110246018f, |
||||
-0.144087434f, 0.0120453080f, -0.524990261f, 0.0138590708f, -0.182723984f, 0.0165519360f, |
||||
-0.217308879f, 0.0208590515f, 0.462978750f, 0.0247372910f, 0.0956632495f, 0.0323494300f, |
||||
0.0843820646f, 0.0424364135f, 0.122466311f, 0.0441578403f, -0.162433729f, 0.0528083183f, |
||||
0.0964344442f, 0.0624147579f, -0.271349967f, 0.0727724135f, -0.266336441f, 0.0719895661f, |
||||
0.0675768778f, 0.0848240927f, -0.689944625f, 0.0889045894f, -0.680990934f, 0.0903657600f, |
||||
-0.119472280f, 0.0930491239f, -0.124393739f, 0.0933082998f, -0.323403478f, 0.0937438533f, |
||||
-0.323273063f, 0.0969979763f, -0.352427900f, 0.101048596f, -0.327554941f, 0.104539163f, |
||||
-0.330044419f, 0.114519835f, 0.0235135648f, 0.118004657f, -0.671623945f, 0.130437061f, |
||||
-0.385111898f, 0.142786101f, -0.376281500f, 0.145800456f, -0.0169987213f, 0.148056105f, |
||||
-0.326495141f, 0.152596891f, -0.337120056f, 0.154522225f, -0.336885720f, 0.154304653f, |
||||
0.322089493f, 0.155130088f, -0.0713477954f, 0.163638428f, -0.0208650175f, 0.171433330f, |
||||
-0.380652726f, 0.172022790f, -0.0599780641f, 0.182294667f, 0.244408697f, 0.194245726f, |
||||
-0.101454332f, 0.198159069f, 0.257901788f, 0.200226694f, -0.0775909275f, 0.205242962f, |
||||
0.231870517f, 0.222396746f, -0.546760798f, 0.242291704f, -0.538914979f, 0.243761152f, |
||||
0.206653103f, 0.244874880f, -0.595693469f, 0.264329463f, -0.581023335f, 0.265664101f, |
||||
0.00444878871f, 0.267031074f, -0.573156178f, 0.271591753f, -0.543381274f, 0.271759123f, |
||||
0.00450209389f, 0.271335930f, -0.223618075f, 0.278416723f, 0.161934286f, 0.289435983f, |
||||
-0.199636295f, 0.296817899f, -0.250217140f, 0.299677849f, -0.258231103f, 0.314012855f, |
||||
-0.628315628f, 0.316889286f, 0.320948511f, 0.316358119f, -0.246845752f, 0.320511192f, |
||||
0.0687271580f, 0.321383297f, 0.0784438103f, 0.322898388f, 0.0946765989f, 0.325111747f, |
||||
-0.249674007f, 0.328731328f, -0.244633347f, 0.329467386f, -0.245841011f, 0.334985316f, |
||||
0.118609101f, 0.343532443f, 0.0497615598f, 0.348162144f, -0.221477821f, 0.349263757f, |
||||
0.0759577379f, 0.351840734f, 0.0504637137f, 0.373238713f, 0.0730970055f, 0.376537383f, |
||||
-0.204333842f, 0.381100655f, -0.557245076f, -0.339432925f, -0.402010202f, -0.288829565f, |
||||
-0.350465477f, -0.281259984f, -0.352995187f, -0.264569730f, -0.466762394f, -0.217114508f, |
||||
0.152002022f, -0.217566550f, 0.146226048f, -0.183914393f, 0.0949312001f, -0.177005857f, |
||||
-0.211882949f, -0.175594494f, -0.531562269f, -0.173924312f, -0.0727246776f, -0.167270422f, |
||||
0.0546481088f, -0.140193000f, -0.296819001f, -0.137850702f, -0.261863053f, -0.139540121f, |
||||
0.187967837f, -0.131033540f, 0.322852045f, -0.112108752f, -0.0432251953f, -0.102951847f, |
||||
-0.0453428440f, -0.0914504975f, -0.0182842426f, -0.0918859020f, 0.0140433423f, -0.0904538929f, |
||||
-0.377287626f, -0.0817026496f, 0.266108125f, -0.0797783583f, 0.257961422f, -0.0767710134f, |
||||
-0.495943695f, -0.0683977529f, 0.231466040f, -0.0675206482f, -0.240675926f, -0.0551427566f, |
||||
-0.482824773f, -0.0510699376f, -0.491354793f, -0.0414650664f, -0.0960614979f, -0.0377000235f, |
||||
-0.102409534f, -0.0369749814f, -0.471273214f, -0.0325376652f, -0.483320534f, -0.0174943600f, |
||||
-0.457503378f, -0.0152483145f, -0.178161725f, -0.0153892851f, -0.483233035f, -0.0106405178f, |
||||
-0.472914547f, -0.0105228210f, -0.166542307f, -0.00667150877f, 0.181261331f, -0.00449455017f, |
||||
-0.474292487f, -0.00428914558f, -0.185297221f, -0.00575157674f, -0.494381040f, -0.00278507406f, |
||||
-0.141748473f, -0.00289725070f, -0.487515569f, 0.000758233888f, 0.322646528f, 0.0197495818f, |
||||
0.142943904f, 0.0276249554f, -0.563232243f, 0.0306834858f, -0.555995941f, 0.0367121249f, |
||||
0.114935011f, 0.0496927276f, -0.152954608f, 0.0538645200f, -0.594885707f, 0.0562511310f, |
||||
0.0678326488f, 0.0756176412f, -0.667605639f, 0.0828208700f, -0.354470938f, 0.101424232f, |
||||
0.0228204262f, 0.120382607f, -0.639557123f, 0.124422595f, -0.690505445f, 0.126883239f, |
||||
-0.395509213f, 0.130242139f, -0.00618012529f, 0.139929801f, 0.175945997f, 0.140235618f, |
||||
0.198833048f, 0.167587668f, -0.334679037f, 0.177859858f, 0.236127406f, 0.192743436f, |
||||
0.283146858f, 0.204260647f, -0.0354267135f, 0.206209183f, 0.247388184f, 0.207016930f, |
||||
-0.0422560424f, 0.212493256f, 0.261681855f, 0.215763748f, 0.207528576f, 0.219807997f, |
||||
-0.300219178f, 0.221922547f, 0.206393883f, 0.245171010f, 0.239619836f, 0.244768366f, |
||||
-0.523026288f, 0.250639766f, -0.591975033f, 0.254252791f, 0.246785000f, 0.252878994f, |
||||
0.272995651f, 0.255815417f, 0.00825022161f, 0.265591830f, 0.192723796f, 0.266924977f, |
||||
-0.222951472f, 0.290150762f, -0.545146644f, 0.304910392f, 0.131736591f, 0.319247276f, |
||||
0.319435924f, 0.317917794f, 0.0687546134f, 0.321296155f, -0.255853772f, 0.327258259f, |
||||
0.0948092714f, 0.325284332f, 0.104488030f, 0.327628911f, -0.245483562f, 0.327617317f, |
||||
0.0647632629f, 0.363111496f, -0.382861346f, -0.287226975f, -0.354297429f, -0.278708905f, |
||||
-0.356116027f, -0.262691110f, -0.369049937f, -0.237850189f, -0.146217853f, -0.233530551f, |
||||
0.102752604f, -0.223108903f, 0.137545392f, -0.218163848f, 0.125815898f, -0.216970086f, |
||||
-0.557826996f, -0.194665924f, -0.533946335f, -0.184958249f, 0.0976954028f, -0.173691019f, |
||||
-0.240166873f, -0.160652772f, 0.166464865f, -0.154563308f, -0.0330923162f, -0.125799045f, |
||||
-0.290044904f, -0.118914597f, 0.00350888353f, -0.108661920f, -0.0109116854f, -0.106212743f, |
||||
-0.0298740193f, -0.102953635f, -0.287203342f, -0.0997403413f, -0.269498408f, -0.0981520712f, |
||||
-0.000815737061f, -0.0938294530f, 0.274663270f, -0.0844340026f, -0.371082008f, -0.0805466920f, |
||||
-0.368196100f, -0.0743779093f, 0.00675902702f, -0.0735078678f, 0.226267770f, -0.0744194537f, |
||||
-0.241736412f, -0.0630025938f, -0.408663541f, -0.0564615242f, 0.251640886f, -0.0519632548f, |
||||
0.249993712f, -0.0519672707f, -0.426033378f, -0.0365641154f, -0.467352122f, -0.0305716563f, |
||||
0.251341015f, -0.0268137120f, -0.443456501f, -0.0243669953f, -0.502199471f, -0.0151771074f, |
||||
-0.178487480f, -0.0155749097f, 0.178145915f, -0.00528379623f, -0.492981344f, -0.00174682145f, |
||||
-0.150337398f, 0.000692513015f, -0.457302928f, 0.00352234906f, 0.190587431f, 0.00151424226f, |
||||
-0.482671946f, 0.00682042213f, -0.158589542f, 0.0150188655f, -0.182223722f, 0.0145649035f, |
||||
0.107089065f, 0.0223725326f, 0.135399371f, 0.0275243558f, -0.552838683f, 0.0275048595f, |
||||
-0.432176501f, 0.0248741303f, -0.192510992f, 0.0281074084f, -0.553043425f, 0.0298770685f, |
||||
-0.684887648f, 0.0436144769f, 0.0850105733f, 0.0448755622f, -0.165784389f, 0.0439001285f, |
||||
0.102653719f, 0.0457992665f, 0.114853017f, 0.0504316092f, -0.647432685f, 0.0608204119f, |
||||
0.0828530043f, 0.0608987175f, 0.0894377902f, 0.0742467493f, 0.0702404827f, 0.0767309442f, |
||||
-0.613642335f, 0.0779517740f, -0.670592189f, 0.0849624202f, -0.395209312f, 0.0854151621f, |
||||
0.125186160f, 0.0919951499f, -0.359707922f, 0.102121405f, -0.354259193f, 0.101300709f, |
||||
0.0304000825f, 0.110619470f, -0.677573025f, 0.114422500f, 0.0305799693f, 0.121603437f, |
||||
-0.358950615f, 0.121660560f, -0.718753040f, 0.134569481f, 0.256451160f, 0.141883001f, |
||||
-0.0904129520f, 0.146879435f, -0.0184279438f, 0.148968369f, -0.356992692f, 0.160104826f, |
||||
-0.337676436f, 0.161766291f, 0.201174691f, 0.169025913f, -0.378423393f, 0.170933828f, |
||||
-0.601599216f, 0.174998865f, -0.0902864039f, 0.184311926f, -0.0584819093f, 0.184186250f, |
||||
0.294467270f, 0.182560727f, 0.250262231f, 0.186239958f, -0.326370239f, 0.191697389f, |
||||
-0.0980727375f, 0.196913749f, 0.253085673f, 0.201914877f, -0.0344332159f, 0.205900863f, |
||||
0.255287141f, 0.203029931f, -0.452713937f, 0.205191836f, 0.264822274f, 0.217408702f, |
||||
-0.0290334225f, 0.221684650f, -0.583990574f, 0.237398431f, -0.145020664f, 0.240374506f, |
||||
0.249667659f, 0.254706532f, 0.274279058f, 0.256447285f, -0.282936275f, 0.259140193f, |
||||
0.241211995f, 0.260401577f, -0.590560019f, 0.272659779f, -0.574947417f, 0.272671998f, |
||||
-0.224780366f, 0.279990941f, -0.525540829f, 0.287235677f, -0.247069210f, 0.298608154f, |
||||
-0.201292604f, 0.298156679f, 0.319822490f, 0.317605704f, -0.248013541f, 0.320789784f, |
||||
0.0957527757f, 0.326543272f, 0.105006196f, 0.328469753f, -0.264089525f, 0.332354158f, |
||||
-0.670460403f, 0.339870930f, 0.118318990f, 0.345167071f, 0.0737744719f, 0.353734553f, |
||||
0.0655663237f, 0.361025929f, -0.306805104f, 0.363820761f, 0.0524423867f, 0.371921480f, |
||||
0.0713953897f, 0.375074357f, -0.411387652f, -0.268335998f, -0.357590824f, -0.263346583f, |
||||
-0.407676578f, -0.253785878f, 0.0660323426f, -0.253718942f, -0.157670841f, -0.225629836f, |
||||
0.170453921f, -0.220800355f, -0.475751191f, -0.209005311f, -0.331408232f, -0.203059763f, |
||||
-0.173841938f, -0.199112654f, -0.503261328f, -0.193795130f, -0.532277644f, -0.190292686f, |
||||
-0.0972326621f, -0.191563144f, -0.0692789108f, -0.172031537f, -0.318824291f, -0.169072524f, |
||||
-0.576232314f, -0.162124678f, -0.0839322209f, -0.156304389f, -0.583625376f, -0.142171323f, |
||||
-0.0546422042f, -0.135338858f, 0.0501612425f, -0.132490858f, -0.645011544f, -0.111341864f, |
||||
-0.0925374180f, -0.0483307689f, -0.444242209f, -0.0263337940f, 0.0335495919f, -0.0281750113f, |
||||
0.274629444f, -0.0259516705f, 0.213774025f, -0.0240113474f, -0.194874078f, -0.0151330847f, |
||||
0.175111562f, -0.00868577976f, -0.185011521f, -0.000680683181f, 0.152071685f, 0.0204544198f, |
||||
0.321354061f, 0.0199794695f, -0.192160159f, 0.0275637116f, -0.189656645f, 0.0275667012f, |
||||
0.137452200f, 0.0298070628f, -0.194602579f, 0.0449027494f, -0.647751570f, 0.0625102371f, |
||||
0.124078721f, 0.0639316663f, 0.125849217f, 0.0762147456f, -0.614036798f, 0.0778791085f, |
||||
-0.684063017f, 0.0867959261f, -0.670344174f, 0.0846142769f, -0.127689242f, 0.0883567855f, |
||||
0.123796627f, 0.0907361880f, -0.356352538f, 0.101948388f, -0.388843179f, 0.110183217f, |
||||
0.0316384435f, 0.123791300f, -0.627986908f, 0.146491125f, -0.0747071728f, 0.158135459f, |
||||
-0.0235102437f, 0.168867558f, -0.0903210714f, 0.184088305f, 0.292073458f, 0.183571488f, |
||||
-0.0585953295f, 0.184784085f, -0.0317775607f, 0.218368888f, 0.209752038f, 0.223883361f, |
||||
-0.295424402f, 0.229150623f, -0.144439027f, 0.237902716f, -0.284140587f, 0.262761474f, |
||||
0.289083928f, 0.276900887f, 0.159017235f, 0.300793648f, -0.204925507f, 0.298536539f, |
||||
-0.544958472f, 0.305164427f, -0.261615157f, 0.306550682f, 0.0977220088f, 0.327949613f, |
||||
0.109876208f, 0.337665111f, -0.283918083f, 0.347385526f, 0.0436712503f, 0.350702018f, |
||||
0.114512287f, 0.367949426f, 0.106543839f, 0.375095814f, 0.505324781f, -0.272183985f, |
||||
0.0645913780f, -0.251512915f, -0.457196057f, -0.225893468f, -0.480293810f, -0.222602293f, |
||||
-0.138176888f, -0.209798917f, -0.110901751f, -0.198036820f, -0.196451947f, -0.191723794f, |
||||
-0.537742376f, -0.174413025f, -0.0650562346f, -0.174762890f, -0.567489207f, -0.165461496f, |
||||
0.0879585966f, -0.163023785f, -0.303777844f, -0.142031133f, 0.199195996f, -0.141861767f, |
||||
0.0491657220f, -0.132264882f, -0.497363061f, -0.107934952f, -0.000536393432f, -0.102828167f, |
||||
0.0155952247f, -0.0998895392f, -0.363601953f, -0.0897399634f, -0.224325985f, -0.0719678402f, |
||||
-0.0638299435f, -0.0646244809f, -0.108656809f, -0.0468749776f, -0.0865045264f, -0.0512534790f, |
||||
-0.469339728f, -0.0279338267f, 0.0578282699f, -0.0133374622f, -0.195265710f, -0.0115369316f, |
||||
0.296735317f, -0.0132813146f, 0.0664219409f, 0.0134935537f, 0.126060545f, 0.0333039127f, |
||||
0.139887005f, 0.0334976614f, -0.547339618f, 0.0433730707f, 0.0866046399f, 0.0527233221f, |
||||
0.131943896f, 0.0657638907f, -0.280056775f, 0.0685855150f, 0.0746403933f, 0.0795079395f, |
||||
0.125382811f, 0.0822770745f, -0.648187757f, 0.103887804f, -0.107411072f, 0.107508548f, |
||||
0.0155869983f, 0.108978622f, 0.0189307462f, 0.129617691f, 0.162685350f, 0.127225950f, |
||||
-0.0875291452f, 0.142281070f, 0.319728941f, 0.148827255f, -0.0259547811f, 0.169724479f, |
||||
0.259297132f, 0.190075457f, -0.467013776f, 0.212794706f, -0.315732479f, 0.219243437f, |
||||
-0.111042649f, 0.217940107f, 0.239550352f, 0.222786069f, 0.263966352f, 0.260309041f, |
||||
0.320023954f, -0.222228840f, -0.322707742f, -0.213004455f, -0.224977970f, -0.169595599f, |
||||
-0.605799317f, -0.142425537f, 0.0454332717f, -0.129945949f, 0.205748767f, -0.113405459f, |
||||
0.317985803f, -0.118630089f, 0.497755647f, -0.0962266177f, -0.393495560f, -0.0904672816f, |
||||
0.240035087f, -0.0737613589f, -0.212947786f, -0.0280145984f, 0.0674179196f, 0.0124880793f, |
||||
-0.545862198f, 0.0207057912f, -0.284409463f, 0.0626631007f, -0.107082598f, 0.0854173824f, |
||||
0.0578137375f, 0.0917839557f, 0.145844117f, 0.102937251f, 0.183878779f, 0.119614877f, |
||||
-0.626380265f, 0.140862882f, -0.0325521491f, 0.161834121f, -0.590211987f, 0.167720392f, |
||||
0.289599866f, 0.186565816f, -0.328821093f, 0.187714070f, -0.289086968f, 0.205165654f, |
||||
-0.445392698f, 0.215343162f, 0.173715711f, 0.273563296f, 0.284015119f, 0.270610362f, |
||||
0.0174398609f, 0.283809274f, -0.496335506f, -0.202981815f, 0.0389454551f, -0.166210428f, |
||||
-0.317301393f, -0.156280205f, -0.396320462f, -0.0949599668f, -0.213638976f, -0.0776446015f, |
||||
0.497601509f, -0.0928353444f, -0.260220319f, -0.0718628615f, -0.116495222f, -0.0543703064f, |
||||
-0.118132629f, -0.0156126227f, 0.0242815297f, 0.00629332382f, -0.537928998f, 0.00815516617f, |
||||
0.317720622f, 0.0271231923f, -0.582170665f, 0.0478387438f, -0.536856830f, 0.0466793887f, |
||||
-0.220819592f, 0.0433096550f, -0.246473342f, 0.0572598167f, 0.481240988f, 0.0503845438f, |
||||
-0.102453016f, 0.0649363101f, -0.149955124f, 0.0744054317f, -0.248215869f, 0.0916868672f, |
||||
-0.101221249f, 0.110788561f, -0.437672526f, 0.179065496f, -0.0383506976f, 0.183546484f, |
||||
-0.279600590f, 0.208760634f, 0.182261929f, 0.275244594f, 0.0253023170f, -0.170456246f, |
||||
-0.476852804f, -0.123630777f, -0.0803126246f, -0.0782076195f, -0.133338496f, -0.0659459904f, |
||||
-0.0822777376f, -0.00390591589f, 0.149250969f, 0.104314201f, 0.0418044887f, 0.149009049f, |
||||
-0.438308835f, 0.164682120f |
||||
}; |
||||
|
||||
const Point2f* currRectifiedPointArr_2f = (const Point2f*)currRectifiedPointArr; |
||||
vector<Point2f> currRectifiedPoints(currRectifiedPointArr_2f, |
||||
currRectifiedPointArr_2f + sizeof(currRectifiedPointArr) / sizeof(currRectifiedPointArr[0]) / 2); |
||||
|
||||
_currRectifiedPoints.swap(currRectifiedPoints); |
||||
|
||||
static const float prevRectifiedPointArr[] = { |
||||
-0.599324584f, -0.381164283f, -0.387985110f, -0.385367423f, -0.371437579f, -0.371891201f, |
||||
-0.340867460f, -0.370632380f, -0.289822906f, -0.364118159f, -0.372411519f, -0.335272551f, |
||||
-0.289586753f, -0.335766882f, -0.372335523f, -0.316857219f, -0.321099430f, -0.323233813f, |
||||
0.208661616f, -0.153931335f, -0.559897065f, 0.193362445f, 0.0181128159f, -0.325224668f, |
||||
-0.427504510f, 0.105302416f, 0.487470537f, -0.187071189f, 0.343267351f, -0.339755565f, |
||||
-0.477639943f, -0.204375938f, -0.466626763f, -0.204072326f, 0.340813518f, -0.347292691f, |
||||
0.342682719f, -0.320172101f, 0.383663863f, -0.327343374f, -0.467062414f, -0.193995550f, |
||||
-0.475603998f, -0.189820126f, 0.552475691f, 0.198386014f, -0.508027375f, -0.174297482f, |
||||
-0.211989403f, -0.217261642f, 0.180832058f, -0.127527758f, -0.112721168f, -0.125876635f, |
||||
-0.112387165f, -0.167135969f, -0.562491000f, -0.140186235f, 0.395156831f, -0.298828602f, |
||||
-0.485202312f, -0.135626689f, 0.148358017f, -0.195937276f, -0.248159677f, -0.254669130f, |
||||
-0.568366945f, -0.105187029f, -0.0714842379f, -0.0832463056f, -0.497599572f, -0.205334768f, |
||||
-0.0948727652f, 0.245045587f, 0.160857186f, 0.138075173f, 0.164952606f, -0.195109487f, |
||||
0.165254518f, -0.186554477f, -0.183777973f, -0.124357253f, 0.166813776f, -0.153241888f, |
||||
-0.241765827f, -0.0820638761f, 0.208661616f, -0.153931335f, 0.540147483f, -0.203156039f, |
||||
0.529201686f, -0.199348077f, -0.248159677f, -0.254669130f, 0.180369601f, -0.139303327f, |
||||
0.570952237f, -0.185722873f, 0.221771300f, -0.143187970f, 0.498627752f, -0.183768719f, |
||||
0.561214447f, -0.188666284f, -0.241409421f, -0.253560483f, 0.569648385f, -0.184499770f, |
||||
0.276665628f, -0.0881819800f, 0.533934176f, -0.142226711f, -0.299728751f, -0.330407321f, |
||||
0.270322412f, -0.256552309f, -0.255016476f, -0.0823200271f, -0.378096581f, 0.0264666155f, |
||||
-0.331565350f, 0.0210608803f, 0.0100810500f, -0.0213523544f, -0.248159677f, -0.254669130f, |
||||
0.249623299f, 0.164078355f, 0.0190342199f, -0.00415771967f, 0.604407132f, -0.259350061f, |
||||
0.0660026148f, -0.00787150953f, 0.605921566f, 0.114344336f, 0.0208173525f, 0.00527517078f, |
||||
-0.0200567022f, 0.0183092188f, -0.184784368f, -0.193566754f, -0.0125719802f, -0.344967902f, |
||||
0.343063682f, -0.0121044181f, 0.389022052f, -0.0171062462f, 0.163190305f, 0.200014487f, |
||||
0.362440646f, 0.0120019922f, -0.427743971f, 0.100272447f, -0.0714842379f, -0.0832463056f, |
||||
0.0664352402f, 0.0467514023f, -0.559897065f, 0.193362445f, -0.549086213f, 0.193808615f, |
||||
-0.241472989f, -0.253163874f, -0.241765827f, -0.0820638761f, -0.122216024f, 0.132651567f, |
||||
-0.122216024f, 0.132651567f, 0.515065968f, 0.205271944f, 0.180832058f, -0.127527758f, |
||||
-0.123633556f, 0.154476687f, -0.248159677f, -0.254669130f, 0.0208173525f, 0.00527517078f, |
||||
-0.483276874f, 0.191274792f, -0.167928949f, 0.200682297f, 0.232745290f, -0.211950779f, |
||||
-0.288701504f, -0.334238827f, -0.119621970f, 0.204155236f, -0.119621970f, 0.204155236f, |
||||
0.632996142f, 0.0804972649f, 0.189231426f, 0.164325386f, 0.249623299f, 0.164078355f, |
||||
0.0676716864f, 0.0479496233f, 0.207636267f, 0.184271768f, -0.300510556f, 0.358790994f, |
||||
-0.107678331f, 0.188473806f, 0.565983415f, 0.144723341f, 0.191329703f, 0.213909492f, |
||||
-0.0283227600f, -0.373237878f, -0.184958130f, 0.200373843f, 0.0346363746f, -0.0259889495f, |
||||
-0.112387165f, -0.167135969f, 0.251426309f, 0.210430339f, -0.477397382f, -0.131372169f, |
||||
-0.0667442903f, 0.0997460634f, 0.251426309f, 0.210430339f, -0.317926824f, 0.375238001f, |
||||
-0.0621999837f, 0.280056626f, 0.0443522707f, 0.321513236f, 0.471269101f, 0.260774940f, |
||||
-0.107678331f, 0.188473806f, 0.0208210852f, 0.350526422f, 0.0157474391f, 0.367335707f, |
||||
0.632996142f, 0.0804972649f, 0.646697879f, 0.265504390f, 0.0295150280f, 0.371205181f, |
||||
0.376071006f, 0.313471258f, -0.379525930f, 0.364357829f, -0.00628023129f, -0.0373278372f, |
||||
0.0291138459f, 0.381194293f, 0.0358079821f, 0.381886899f, 0.0344478637f, 0.386993408f, |
||||
0.433862329f, 0.328515977f, 0.359724253f, 0.345606029f, 0.0651357397f, 0.397334814f, |
||||
0.388413996f, 0.344747871f, -0.140228778f, 0.216103494f, 0.389989913f, 0.372472703f, |
||||
0.444995403f, 0.300240308f, -0.606455386f, 0.100793049f, -0.362332910f, -0.371920794f, |
||||
-0.478956074f, 0.234040022f, -0.289441198f, -0.344822973f, -0.0714842379f, -0.0832463056f, |
||||
0.375879139f, -0.374975592f, 0.376526117f, -0.326493502f, 0.313251913f, -0.306372881f, |
||||
-0.0577337518f, 0.0893306211f, -0.483683407f, -0.179540694f, -0.0763650239f, -0.258294433f, |
||||
0.276665628f, -0.0881819800f, -0.167122558f, -0.175508693f, -0.164081737f, 0.176902041f, |
||||
0.276665628f, -0.0881819800f, 0.602967978f, -0.260941893f, 0.158573851f, -0.178748295f, |
||||
0.159815103f, -0.160761341f, 0.194283918f, -0.165657878f, 0.231515527f, -0.172808051f, |
||||
-0.247000366f, 0.277822912f, 0.538969517f, -0.204621449f, 0.531404376f, -0.198565826f, |
||||
-0.388338953f, -0.0433262810f, 0.499413073f, -0.181929186f, -0.237337112f, 0.0934364349f, |
||||
-0.368045300f, -0.0204487685f, -0.374767631f, -0.00678646797f, -0.0667242110f, -0.248651102f, |
||||
-0.248159677f, -0.254669130f, -0.345217139f, -0.00101677026f, -0.353382975f, 0.0210586078f, |
||||
-0.322639942f, 0.0211628731f, 0.0184581745f, -0.0366852731f, 0.0259528626f, -0.0136881955f, |
||||
-0.339446336f, 0.0286702402f, 0.0335014127f, -0.0271516014f, 0.465966076f, 0.0830826238f, |
||||
-0.337860256f, 0.0362124667f, 0.188271523f, -0.146541893f, -0.298272073f, -0.323130161f, |
||||
0.0643569306f, -0.0264105909f, -0.353804410f, 0.0433940105f, 0.618646920f, -0.0855877250f, |
||||
0.411329508f, -0.0414552018f, -0.427743971f, 0.100272447f, -0.247000366f, 0.277822912f, |
||||
0.381912649f, -0.00914942939f, 0.0664352402f, 0.0467514023f, 0.138687640f, -0.114854909f, |
||||
-0.0170480162f, -0.372787565f, -0.535477102f, 0.183755845f, -0.155668780f, 0.144164801f, |
||||
-0.427504510f, 0.105302416f, -0.484430760f, 0.227277100f, -0.361284673f, -0.373513311f, |
||||
-0.316764563f, 0.331503242f, -0.0230990555f, 0.314180285f, 0.101539977f, -0.256640851f, |
||||
-0.210743994f, -0.111771651f, -0.560086846f, 0.151153624f, 0.542884171f, 0.141691014f, |
||||
0.596041858f, 0.144990161f, 0.239398748f, 0.207432285f, 0.557545543f, 0.155783832f, |
||||
0.233033463f, 0.214694947f, 0.572789013f, 0.162068501f, 0.512761712f, 0.176260322f, |
||||
0.287076950f, 0.0868823677f, 0.515065968f, 0.205271944f, 0.552475691f, 0.198386014f, |
||||
-0.301232725f, 0.347804308f, -0.379525930f, 0.364357829f, 0.561403453f, 0.206571117f, |
||||
0.590792358f, 0.206283644f, -0.428855836f, 0.100270294f, 0.300039053f, -0.283949375f, |
||||
0.0481642894f, 0.334260821f, -0.173260480f, -0.167126089f, 0.444995403f, 0.300240308f, |
||||
0.646697879f, 0.265504390f, 0.375487208f, 0.314186513f, 0.0217850581f, 0.381838262f, |
||||
0.404422343f, 0.313856274f, 0.417644382f, 0.314869910f, 0.0358079821f, 0.381886899f, |
||||
0.378262609f, 0.358303785f, -0.336999178f, -0.367679387f, -0.295442462f, -0.365161836f, |
||||
-0.293496192f, -0.342732310f, -0.298767596f, -0.303165644f, -0.0111337993f, -0.342149645f, |
||||
0.310648471f, -0.374146342f, 0.359467417f, -0.373746723f, 0.340779394f, -0.369219989f, |
||||
-0.527450860f, -0.203896046f, -0.490746915f, -0.194764644f, 0.314866364f, -0.300261766f, |
||||
-0.0298556220f, 0.0591949411f, 0.319549739f, 0.0552458987f, 0.163977623f, -0.209844783f, |
||||
-0.149107113f, -0.149005055f, 0.212483421f, -0.191198543f, 0.197611198f, -0.187811792f, |
||||
0.174361721f, -0.179897651f, 0.0387913659f, -0.0366905928f, -0.122265801f, -0.126270071f, |
||||
0.211038783f, -0.172842503f, 0.246728286f, 0.134398326f, -0.0577337518f, 0.0893306211f, |
||||
-0.415295422f, 0.105914228f, -0.292730510f, 0.0379575789f, 0.489636958f, -0.194117576f, |
||||
-0.254337519f, 0.0937413648f, 0.336177140f, 0.305443168f, 0.526942134f, -0.164069965f, |
||||
0.524966419f, -0.165161178f, -0.379173398f, 0.332068861f, -0.340792000f, 0.00105464540f, |
||||
0.525632977f, -0.134992197f, -0.308774501f, 0.00290521770f, -0.375407755f, 0.0294080544f, |
||||
0.0178439785f, -0.0365749858f, -0.255016476f, -0.0823200271f, -0.359951973f, 0.0446678996f, |
||||
0.0564084686f, -0.0197724514f, -0.315141559f, 0.0424463004f, 0.292196661f, 0.279810339f, |
||||
-0.345294952f, 0.0533128195f, 0.0458479226f, -0.00109126628f, 0.0179449394f, 0.00371767790f, |
||||
0.365872562f, -0.0412087664f, 0.403013051f, -0.0416624695f, -0.0714842379f, -0.0832463056f, |
||||
-0.209011748f, 0.133690849f, 0.0122421598f, 0.0230175443f, -0.0577337518f, 0.0893306211f, |
||||
-0.572846889f, 0.141102776f, 0.345340014f, -0.0111671211f, 0.0479373708f, 0.0379454680f, |
||||
0.363291621f, -0.00829032529f, 0.381912649f, -0.00914942939f, -0.521542430f, 0.151489466f, |
||||
0.345966965f, 0.0110620018f, 0.354562849f, 0.0254590791f, 0.334322065f, 0.0310698878f, |
||||
-0.00463629747f, -0.0357710384f, -0.538667142f, 0.185365483f, -0.209011748f, 0.133690849f, |
||||
0.398122877f, 0.0403857268f, -0.160881191f, 0.145009249f, -0.155668780f, 0.144164801f, |
||||
-0.0714842379f, -0.0832463056f, -0.536377013f, 0.221241340f, -0.0632879063f, -0.247039422f, |
||||
-0.155869946f, 0.169341147f, 0.578685045f, -0.223878756f, 0.557447612f, 0.0768704116f, |
||||
-0.188812047f, 0.228197843f, 0.246747240f, 0.136472240f, -0.142677084f, 0.213736445f, |
||||
-0.118143238f, 0.208306640f, -0.388338953f, -0.0433262810f, -0.163515776f, 0.231573820f, |
||||
-0.0738375857f, -0.256104171f, 0.173092276f, 0.191535592f, 0.208548918f, 0.185476139f, |
||||
-0.392410189f, 0.0686017647f, 0.555366814f, 0.130478472f, -0.101943128f, -0.113997340f, |
||||
0.0716935173f, 0.340265751f, 0.561738014f, 0.148283109f, 0.242452115f, 0.205116034f, |
||||
0.561738014f, 0.148283109f, -0.427743971f, 0.100272447f, 0.578137994f, 0.163653031f, |
||||
0.251277626f, 0.223055005f, -0.376505047f, 0.343530416f, -0.0714842379f, -0.0832463056f, |
||||
0.567448437f, 0.207419440f, 0.590792358f, 0.206283644f, 0.578685045f, -0.223878756f, |
||||
0.0635343120f, -0.00499309227f, -0.370767444f, 0.384881169f, -0.485191971f, -0.120962359f, |
||||
0.512761712f, 0.176260322f, -0.375972956f, 0.0288736783f, -0.147176415f, -0.185790271f, |
||||
0.0752977654f, 0.339190871f, 0.646697879f, 0.265504390f, 0.0282997675f, 0.373214334f, |
||||
0.410353780f, 0.316089481f, 0.417644382f, 0.314869910f, 0.0147482762f, 0.389459789f, |
||||
-0.182916895f, -0.140514761f, 0.433515042f, 0.330774426f, 0.388069838f, 0.347381502f, |
||||
0.378925055f, 0.357438952f, 0.247128293f, -0.116897359f, -0.0230906308f, 0.314556211f, |
||||
0.388534039f, 0.370789021f, -0.368050814f, -0.339653373f, -0.292694926f, -0.341653705f, |
||||
-0.353774697f, -0.320387989f, 0.599263310f, -0.264537901f, -0.0213720929f, -0.326088905f, |
||||
-0.571947694f, 0.141147330f, -0.0577337518f, 0.0893306211f, 0.108424753f, -0.267108470f, |
||||
-0.0317604132f, -0.0458168685f, -0.0967136100f, 0.242639020f, -0.486509413f, -0.204596937f, |
||||
0.239178345f, -0.219647482f, 0.108424753f, -0.267108470f, -0.280393064f, -0.283867925f, |
||||
-0.533659995f, -0.151733354f, 0.0880429000f, -0.240412414f, -0.534965396f, -0.124174178f, |
||||
0.142445788f, -0.118948005f, 0.0947291106f, 0.0767719224f, -0.597055852f, -0.0692315027f, |
||||
-0.254337519f, 0.0937413648f, -0.308869720f, 0.00354974205f, -0.409894019f, -0.0694356859f, |
||||
0.556049764f, -0.137727231f, -0.0317604132f, -0.0458168685f, -0.524152219f, 0.239541322f, |
||||
0.108424753f, -0.267108470f, 0.0143662402f, -0.0164190196f, 0.150936082f, 0.128616557f, |
||||
0.618646920f, -0.0855877250f, 0.0122421598f, 0.0230175443f, 0.0122421598f, 0.0230175443f, |
||||
-0.188812047f, 0.228197843f, 0.00441747159f, -0.297387213f, -0.520719767f, 0.152393058f, |
||||
0.392849416f, 0.00738697406f, 0.400074363f, 0.0185570847f, -0.161484867f, -0.192373112f, |
||||
-0.554901838f, 0.190730989f, -0.538667142f, 0.185365483f, -0.0667442903f, 0.0997460634f, |
||||
0.399885803f, 0.0410231315f, -0.159816831f, 0.145826310f, -0.193316415f, 0.161277503f, |
||||
-0.0678345188f, 0.287081748f, -0.383089483f, -0.283330113f, -0.538667142f, 0.185365483f, |
||||
0.245664895f, 0.162005231f, 0.173092276f, 0.191535592f, 0.601281762f, 0.120500855f, |
||||
0.208548918f, 0.185476139f, 0.246893004f, 0.220670119f, 0.516039073f, 0.178782418f, |
||||
-0.254337519f, 0.0937413648f, -0.254337519f, 0.0937413648f, -0.0230990555f, 0.314180285f, |
||||
0.610029638f, 0.227215171f, -0.254337519f, 0.0937413648f, 0.0697976872f, 0.343245506f, |
||||
0.538969517f, -0.204621449f, 0.00916308723f, 0.359826297f, 0.410353780f, 0.316089481f, |
||||
0.423950195f, 0.324112266f, 0.166566655f, 0.145402640f, 0.354594171f, 0.350193948f, |
||||
0.433712035f, 0.356235564f, 0.425307065f, 0.364637494f, 0.166924104f, -0.152513608f, |
||||
0.594130874f, -0.268246830f, -0.0843627378f, -0.0962528363f, 0.108424753f, -0.267108470f, |
||||
0.00760878995f, -0.304247797f, -0.471018314f, -0.178305879f, -0.0817007348f, -0.0933016762f, |
||||
0.232274890f, 0.154553935f, 0.108424753f, -0.267108470f, -0.525787771f, -0.161353886f, |
||||
-0.206048280f, 0.241006181f, -0.178062543f, -0.184703678f, 0.105906568f, 0.268231422f, |
||||
-0.0817007348f, -0.0933016762f, 0.490914792f, 0.276718110f, -0.176861435f, -0.153617889f, |
||||
0.0387795344f, 0.0457828715f, 0.456206828f, -0.250739783f, 0.0982551053f, 0.104225174f, |
||||
0.142445788f, -0.118948005f, 0.108424753f, -0.267108470f, -0.0817007348f, -0.0933016762f, |
||||
-0.340707630f, 0.00498990202f, 0.0947291106f, 0.0767719224f, 0.169802040f, 0.203134149f, |
||||
0.577375948f, -0.125099033f, 0.318376005f, -0.0486588739f, 0.388697982f, -0.0351444185f, |
||||
0.406605273f, -0.0364143848f, 0.274859309f, 0.0776181892f, 0.349759877f, -7.70174083e-05f, |
||||
0.402967423f, 0.00697830878f, 0.105906568f, 0.268231422f, 0.338973522f, 0.0359939188f, |
||||
0.394951165f, 0.0322254188f, -0.503028810f, 0.203627899f, -0.0840740278f, -0.234684706f, |
||||
0.108424753f, -0.267108470f, 0.286642373f, 0.103878126f, -0.0817007348f, -0.0933016762f, |
||||
0.332983583f, -0.0356097035f, 0.628004134f, 0.0766527727f, -0.112659439f, -0.196833044f, |
||||
0.568797410f, 0.136423931f, 0.456206828f, -0.250739783f, -0.254337519f, 0.0937413648f, |
||||
-0.206692874f, -0.210832119f, 0.550912619f, 0.171586066f, 0.581267595f, 0.213235661f, |
||||
0.334484309f, 0.303876013f, -0.469516128f, 0.0883551016f, 0.133899942f, 0.106862970f, |
||||
-0.560961962f, -0.114681393f, -0.0840740278f, -0.234684706f, 0.459386230f, -0.236088052f, |
||||
0.594130874f, -0.268246830f, -0.124856450f, 0.193096936f, -0.469516128f, 0.0883551016f, |
||||
0.514290810f, -0.193822652f, 0.158255994f, 0.233290926f, 0.317973822f, -0.0477817170f, |
||||
-0.0817007348f, -0.0933016762f, -0.0702776462f, -0.0671426803f, 0.440836668f, -0.100193374f, |
||||
0.326240778f, 0.0523138903f, -0.279556662f, -0.283929169f, -0.485202312f, -0.135626689f, |
||||
-0.467358112f, 0.246376559f, 0.232274890f, 0.154553935f, 0.258349210f, -0.269529581f, |
||||
0.600620329f, 0.126268178f, -0.0985416993f, 0.245674044f, -0.279264033f, -0.0990248993f, |
||||
0.108424753f, -0.267108470f, 0.259638488f, -0.100053802f, 0.605106652f, 0.223564968f, |
||||
0.129683495f, -0.100376993f, -0.0953388065f, 0.112722203f, -0.440420747f, -0.0396305211f, |
||||
-0.0181254297f, 0.0439292751f, -0.0878356919f, 0.0847257674f, -0.271582603f, 0.126064256f, |
||||
-0.183777973f, -0.124357253f, 0.431088895f, 0.0680654719f, -0.469516128f, 0.0883551016f, |
||||
-0.445174575f, 0.133306518f, -0.0878356919f, 0.0847257674f, -0.279039949f, 0.0810008645f, |
||||
0.612402737f, -0.0826834291f, -0.454494953f, 0.122878648f, 0.244000912f, -0.264438629f, |
||||
0.142445788f, -0.118948005f, 0.129683495f, -0.100376993f, -0.210078895f, 0.131698489f, |
||||
-0.277847171f, 0.0665081516f, 0.431088895f, 0.0680654719f, 0.252345473f, 0.0688349009f, |
||||
0.133899942f, 0.106862970f, 0.133899942f, 0.106862970f, -0.486509413f, -0.204596937f, |
||||
-0.0940247625f, 0.0698821172f, 0.133899942f, 0.106862970f, -0.440420747f, -0.0396305211f, |
||||
-0.0878356919f, 0.0847257674f, -0.0954068601f, -0.0968973264f, -0.277847171f, 0.0665081516f, |
||||
-0.277847171f, 0.0665081516f, 0.266677618f, 0.111257851f, 0.292424291f, -0.230888903f, |
||||
-0.0954068601f, -0.0968973264f |
||||
}; |
||||
|
||||
const Point2f* prevRectifiedPointArr_2f = (const Point2f*)prevRectifiedPointArr; |
||||
vector<Point2f> prevRectifiedPoints(prevRectifiedPointArr_2f, prevRectifiedPointArr_2f + |
||||
sizeof(prevRectifiedPointArr) / sizeof(prevRectifiedPointArr[0]) / 2); |
||||
|
||||
_prevRectifiedPoints.swap(prevRectifiedPoints); |
||||
|
||||
int validSolutionArr[2] = { 0, 2 }; |
||||
|
||||
vector<int> validSolutions(validSolutionArr, validSolutionArr + |
||||
sizeof(validSolutionArr) / sizeof(validSolutionArr[0])); |
||||
|
||||
_validSolutions.swap(validSolutions); |
||||
|
||||
vector<Mat> rotations; |
||||
vector<Mat> normals; |
||||
|
||||
for (size_t i = 0; i < (sizeof(rotationsArray) / sizeof(*rotationsArray)); i++) { |
||||
Mat tempRotMat = Mat(Matx33d( |
||||
rotationsArray[i][0], |
||||
rotationsArray[i][1], |
||||
rotationsArray[i][2], |
||||
rotationsArray[i][3], |
||||
rotationsArray[i][4], |
||||
rotationsArray[i][5], |
||||
rotationsArray[i][6], |
||||
rotationsArray[i][7], |
||||
rotationsArray[i][8] |
||||
)); |
||||
|
||||
Mat tempNormMat = Mat(Matx31d( |
||||
normalsArray[i][0], |
||||
normalsArray[i][1], |
||||
normalsArray[i][2] |
||||
)); |
||||
|
||||
rotations.push_back(tempRotMat); |
||||
normals.push_back(tempNormMat); |
||||
} |
||||
|
||||
_rotations.swap(rotations); |
||||
_normals.swap(normals); |
||||
|
||||
_mask = Mat(514, 1, CV_8U, maskArray).clone(); |
||||
} |
||||
|
||||
bool isValidResult(const vector<int>& solutions) |
||||
{ |
||||
return (solutions == _validSolutions); |
||||
} |
||||
|
||||
vector<int> _validSolutions; |
||||
vector<Point2f> _prevRectifiedPoints, _currRectifiedPoints; |
||||
Mat _mask; |
||||
vector<Mat> _rotations, _normals; |
||||
}; |
||||
|
||||
TEST(Calib3d_FilterDecomposeHomography, regression) { CV_FilterHomographyDecompTest test; test.safe_run(); } |
||||
|
||||
}} |
@ -0,0 +1,775 @@ |
||||
// 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.
|
||||
//
|
||||
// Copyright (C) 2018, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
#include "precomp.hpp" |
||||
#include "opencv2/objdetect.hpp" |
||||
// #include "opencv2/calib3d.hpp"
|
||||
|
||||
#include <limits> |
||||
#include <cmath> |
||||
#include <iostream> |
||||
|
||||
namespace cv |
||||
{ |
||||
class QRDecode |
||||
{ |
||||
public: |
||||
void init(Mat src, double eps_vertical_ = 0.19, double eps_horizontal_ = 0.09); |
||||
void binarization(); |
||||
bool localization(); |
||||
bool transformation(); |
||||
Mat getBinBarcode() { return bin_barcode; } |
||||
Mat getLocalizationBarcode() { return local_barcode; } |
||||
Mat getTransformationBarcode() { return transform_barcode; } |
||||
std::vector<Point> getTransformationPoints() { return transformation_points; } |
||||
Mat getStraightBarcode() { return straight_barcode; } |
||||
protected: |
||||
std::vector<Vec3d> searchVerticalLines(); |
||||
std::vector<Vec3d> separateHorizontalLines(std::vector<Vec3d> list_lines); |
||||
std::vector<Vec3d> pointClustering(std::vector<Vec3d> list_lines); |
||||
void fixationPoints(std::vector<Point> &local_point, std::vector<double> &local_len); |
||||
Point getTransformationPoint(Point left, Point center, double cos_angle_rotation, |
||||
bool right_rotate = true); |
||||
Point intersectionLines(Point a1, Point a2, Point b1, Point b2); |
||||
std::vector<Point> getQuadrilateral(std::vector<Point> angle_list); |
||||
double getQuadrilateralArea(Point a, Point b, Point c, Point d); |
||||
double getCosVectors(Point a, Point b, Point c); |
||||
|
||||
Mat barcode, bin_barcode, local_barcode, transform_barcode, straight_barcode; |
||||
std::vector<Point> localization_points, transformation_points; |
||||
std::vector<double> localization_length; |
||||
double experimental_area; |
||||
|
||||
double eps_vertical, eps_horizontal; |
||||
std::vector<Vec3d> result; |
||||
std::vector<double> test_lines; |
||||
uint8_t next_pixel, future_pixel; |
||||
double length, weight; |
||||
}; |
||||
|
||||
void QRDecode::init(Mat src, double eps_vertical_, double eps_horizontal_) |
||||
{ |
||||
barcode = src; |
||||
eps_vertical = eps_vertical_; |
||||
eps_horizontal = eps_horizontal_; |
||||
} |
||||
|
||||
void QRDecode::binarization() |
||||
{ |
||||
Mat filter_barcode; |
||||
GaussianBlur(barcode, filter_barcode, Size(3, 3), 0); |
||||
threshold(filter_barcode, bin_barcode, 0, 255, THRESH_BINARY + THRESH_OTSU); |
||||
} |
||||
|
||||
bool QRDecode::localization() |
||||
{ |
||||
cvtColor(bin_barcode, local_barcode, COLOR_GRAY2RGB); |
||||
Point begin, end; |
||||
|
||||
std::vector<Vec3d> list_lines_x = searchVerticalLines(); |
||||
std::vector<Vec3d> list_lines_y = separateHorizontalLines(list_lines_x); |
||||
std::vector<Vec3d> result_point = pointClustering(list_lines_y); |
||||
for (int i = 0; i < 3; i++) |
||||
{ |
||||
localization_points.push_back( |
||||
Point(static_cast<int>(result_point[i][0]), |
||||
static_cast<int>(result_point[i][1] + result_point[i][2]))); |
||||
localization_length.push_back(result_point[i][2]); |
||||
} |
||||
|
||||
fixationPoints(localization_points, localization_length); |
||||
|
||||
|
||||
if (localization_points.size() != 3) { return false; } |
||||
return true; |
||||
|
||||
} |
||||
|
||||
std::vector<Vec3d> QRDecode::searchVerticalLines() |
||||
{ |
||||
result.clear(); |
||||
int temp_length = 0; |
||||
|
||||
for (int x = 0; x < bin_barcode.rows; x++) |
||||
{ |
||||
for (int y = 0; y < bin_barcode.cols; y++) |
||||
{ |
||||
if (bin_barcode.at<uint8_t>(x, y) > 0) { continue; } |
||||
|
||||
// --------------- Search vertical lines --------------- //
|
||||
|
||||
test_lines.clear(); |
||||
future_pixel = 255; |
||||
|
||||
for (int i = x; i < bin_barcode.rows - 1; i++) |
||||
{ |
||||
next_pixel = bin_barcode.at<uint8_t>(i + 1, y); |
||||
temp_length++; |
||||
if (next_pixel == future_pixel) |
||||
{ |
||||
future_pixel = 255 - future_pixel; |
||||
test_lines.push_back(temp_length); |
||||
temp_length = 0; |
||||
if (test_lines.size() == 5) { break; } |
||||
} |
||||
} |
||||
|
||||
// --------------- Compute vertical lines --------------- //
|
||||
|
||||
if (test_lines.size() == 5) |
||||
{ |
||||
length = 0.0; weight = 0.0; |
||||
|
||||
for (size_t i = 0; i < test_lines.size(); i++) { length += test_lines[i]; } |
||||
|
||||
for (size_t i = 0; i < test_lines.size(); i++) |
||||
{ |
||||
if (i == 2) { weight += abs((test_lines[i] / length) - 3.0/7.0); } |
||||
else { weight += abs((test_lines[i] / length) - 1.0/7.0); } |
||||
} |
||||
|
||||
if (weight < eps_vertical) |
||||
{ |
||||
Vec3d line; |
||||
line[0] = x; line[1] = y, line[2] = length; |
||||
result.push_back(line); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
std::vector<Vec3d> QRDecode::separateHorizontalLines(std::vector<Vec3d> list_lines) |
||||
{ |
||||
result.clear(); |
||||
int temp_length = 0; |
||||
int x, y; |
||||
|
||||
for (size_t pnt = 0; pnt < list_lines.size(); pnt++) |
||||
{ |
||||
x = static_cast<int>(list_lines[pnt][0] + list_lines[pnt][2] / 2); |
||||
y = static_cast<int>(list_lines[pnt][1]); |
||||
|
||||
// --------------- Search horizontal up-lines --------------- //
|
||||
test_lines.clear(); |
||||
future_pixel = 255; |
||||
|
||||
for (int j = y; j < bin_barcode.cols - 1; j++) |
||||
{ |
||||
next_pixel = bin_barcode.at<uint8_t>(x, j + 1); |
||||
temp_length++; |
||||
if (next_pixel == future_pixel) |
||||
{ |
||||
future_pixel = 255 - future_pixel; |
||||
test_lines.push_back(temp_length); |
||||
temp_length = 0; |
||||
if (test_lines.size() == 3) { break; } |
||||
} |
||||
} |
||||
|
||||
// --------------- Search horizontal down-lines --------------- //
|
||||
future_pixel = 255; |
||||
|
||||
for (int j = y; j >= 1; j--) |
||||
{ |
||||
next_pixel = bin_barcode.at<uint8_t>(x, j - 1); |
||||
temp_length++; |
||||
if (next_pixel == future_pixel) |
||||
{ |
||||
future_pixel = 255 - future_pixel; |
||||
test_lines.push_back(temp_length); |
||||
temp_length = 0; |
||||
if (test_lines.size() == 6) { break; } |
||||
} |
||||
} |
||||
|
||||
// --------------- Compute horizontal lines --------------- //
|
||||
|
||||
if (test_lines.size() == 6) |
||||
{ |
||||
length = 0.0; weight = 0.0; |
||||
|
||||
for (size_t i = 0; i < test_lines.size(); i++) { length += test_lines[i]; } |
||||
|
||||
for (size_t i = 0; i < test_lines.size(); i++) |
||||
{ |
||||
if (i % 3 == 0) { weight += abs((test_lines[i] / length) - 3.0/14.0); } |
||||
else { weight += abs((test_lines[i] / length) - 1.0/ 7.0); } |
||||
} |
||||
} |
||||
|
||||
if(weight < eps_horizontal) |
||||
{ |
||||
result.push_back(list_lines[pnt]); |
||||
} |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
std::vector<Vec3d> QRDecode::pointClustering(std::vector<Vec3d> list_lines) |
||||
{ |
||||
std::vector<Vec3d> centers; |
||||
std::vector<Point> clusters[3]; |
||||
double weight_clusters[3] = {0.0, 0.0, 0.0}; |
||||
Point basis[3], temp_pnt; |
||||
double temp_norm = 0.0, temp_compute_norm, distance[3]; |
||||
|
||||
basis[0] = Point(static_cast<int>(list_lines[0][1]), static_cast<int>(list_lines[0][0])); |
||||
for (size_t i = 1; i < list_lines.size(); i++) |
||||
{ |
||||
temp_pnt = Point(static_cast<int>(list_lines[i][1]), static_cast<int>(list_lines[i][0])); |
||||
temp_compute_norm = norm(basis[0] - temp_pnt); |
||||
if (temp_norm < temp_compute_norm) |
||||
{ |
||||
basis[1] = temp_pnt; |
||||
temp_norm = temp_compute_norm; |
||||
} |
||||
} |
||||
|
||||
for (size_t i = 1; i < list_lines.size(); i++) |
||||
{ |
||||
temp_pnt = Point(static_cast<int>(list_lines[i][1]), static_cast<int>(list_lines[i][0])); |
||||
temp_compute_norm = norm(basis[0] - temp_pnt) + norm(basis[1] - temp_pnt); |
||||
if (temp_norm < temp_compute_norm) |
||||
{ |
||||
basis[2] = temp_pnt; |
||||
temp_norm = temp_compute_norm; |
||||
} |
||||
} |
||||
|
||||
for (size_t i = 0; i < list_lines.size(); i++) |
||||
{ |
||||
temp_pnt = Point(static_cast<int>(list_lines[i][1]), static_cast<int>(list_lines[i][0])); |
||||
distance[0] = norm(basis[0] - temp_pnt); |
||||
distance[1] = norm(basis[1] - temp_pnt); |
||||
distance[2] = norm(basis[2] - temp_pnt); |
||||
if (distance[0] < distance[1] && distance[0] < distance[2]) |
||||
{ |
||||
clusters[0].push_back(temp_pnt); |
||||
weight_clusters[0] += list_lines[i][2]; |
||||
} |
||||
else if (distance[1] < distance[0] && distance[1] < distance[2]) |
||||
{ |
||||
clusters[1].push_back(temp_pnt); |
||||
weight_clusters[1] += list_lines[i][2]; |
||||
} |
||||
else |
||||
{ |
||||
clusters[2].push_back(temp_pnt); |
||||
weight_clusters[2] += list_lines[i][2]; |
||||
} |
||||
} |
||||
|
||||
for (int i = 0; i < 3; i++) |
||||
{ |
||||
basis[i] = Point(0, 0); |
||||
for (size_t j = 0; j < clusters[i].size(); j++) { basis[i] += clusters[i][j]; } |
||||
basis[i] = basis[i] / static_cast<int>(clusters[i].size()); |
||||
weight = weight_clusters[i] / (2 * clusters[i].size()); |
||||
centers.push_back(Vec3d(basis[i].x, basis[i].y, weight)); |
||||
} |
||||
|
||||
return centers; |
||||
} |
||||
|
||||
void QRDecode::fixationPoints(std::vector<Point> &local_point, std::vector<double> &local_len) |
||||
{ |
||||
double cos_angles[3], norm_triangl[3]; |
||||
|
||||
norm_triangl[0] = norm(local_point[1] - local_point[2]); |
||||
norm_triangl[1] = norm(local_point[0] - local_point[2]); |
||||
norm_triangl[2] = norm(local_point[1] - local_point[0]); |
||||
|
||||
cos_angles[0] = (pow(norm_triangl[1], 2) + pow(norm_triangl[2], 2) - pow(norm_triangl[0], 2)) |
||||
/ (2 * norm_triangl[1] * norm_triangl[2]); |
||||
cos_angles[1] = (pow(norm_triangl[0], 2) + pow(norm_triangl[2], 2) - pow(norm_triangl[1], 2)) |
||||
/ (2 * norm_triangl[0] * norm_triangl[2]); |
||||
cos_angles[2] = (pow(norm_triangl[0], 2) + pow(norm_triangl[1], 2) - pow(norm_triangl[2], 2)) |
||||
/ (2 * norm_triangl[0] * norm_triangl[1]); |
||||
|
||||
int i_min_cos = |
||||
(cos_angles[0] < cos_angles[1] && cos_angles[0] < cos_angles[2]) ? 0 : |
||||
(cos_angles[1] < cos_angles[0] && cos_angles[1] < cos_angles[2]) ? 1 : 2; |
||||
|
||||
Point temp_pnt; |
||||
double tmp_len; |
||||
temp_pnt = local_point[0]; |
||||
tmp_len = local_len[0]; |
||||
local_point[0] = local_point[i_min_cos]; |
||||
local_len[0] = local_len[i_min_cos]; |
||||
local_point[i_min_cos] = temp_pnt; |
||||
local_len[i_min_cos] = tmp_len; |
||||
|
||||
Mat vector_mult(Size(3, 3), CV_32FC1); |
||||
vector_mult.at<float>(0, 0) = 1; |
||||
vector_mult.at<float>(1, 0) = 1; |
||||
vector_mult.at<float>(2, 0) = 1; |
||||
vector_mult.at<float>(0, 1) = static_cast<float>((local_point[1] - local_point[0]).x); |
||||
vector_mult.at<float>(1, 1) = static_cast<float>((local_point[1] - local_point[0]).y); |
||||
vector_mult.at<float>(0, 2) = static_cast<float>((local_point[2] - local_point[0]).x); |
||||
vector_mult.at<float>(1, 2) = static_cast<float>((local_point[2] - local_point[0]).y); |
||||
double res_vect_mult = determinant(vector_mult); |
||||
if (res_vect_mult < 0) |
||||
{ |
||||
temp_pnt = local_point[1]; |
||||
tmp_len = local_len[1]; |
||||
local_point[1] = local_point[2]; |
||||
local_len[1] = local_len[2]; |
||||
local_point[2] = temp_pnt; |
||||
local_len[2] = tmp_len; |
||||
} |
||||
} |
||||
|
||||
bool QRDecode::transformation() |
||||
{ |
||||
cvtColor(bin_barcode, transform_barcode, COLOR_GRAY2RGB); |
||||
if (localization_points.size() != 3) { return false; } |
||||
|
||||
Point red = localization_points[0]; |
||||
Point green = localization_points[1]; |
||||
Point blue = localization_points[2]; |
||||
Point adj_b_r_pnt, adj_r_b_pnt, adj_g_r_pnt, adj_r_g_pnt; |
||||
Point line_r_b_pnt, line_r_g_pnt, norm_r_b_pnt, norm_r_g_pnt; |
||||
adj_b_r_pnt = getTransformationPoint(blue, red, -1); |
||||
adj_r_b_pnt = getTransformationPoint(red, blue, -1); |
||||
adj_g_r_pnt = getTransformationPoint(green, red, -1); |
||||
adj_r_g_pnt = getTransformationPoint(red, green, -1); |
||||
line_r_b_pnt = getTransformationPoint(red, blue, -0.91); |
||||
line_r_g_pnt = getTransformationPoint(red, green, -0.91); |
||||
norm_r_b_pnt = getTransformationPoint(red, blue, 0.0, true); |
||||
norm_r_g_pnt = getTransformationPoint(red, green, 0.0, false); |
||||
|
||||
transformation_points.push_back(intersectionLines( |
||||
adj_r_g_pnt, line_r_g_pnt, adj_r_b_pnt, line_r_b_pnt)); |
||||
transformation_points.push_back(intersectionLines( |
||||
adj_b_r_pnt, norm_r_g_pnt, adj_r_g_pnt, line_r_g_pnt)); |
||||
transformation_points.push_back(intersectionLines( |
||||
norm_r_b_pnt, adj_g_r_pnt, adj_b_r_pnt, norm_r_g_pnt)); |
||||
transformation_points.push_back(intersectionLines( |
||||
norm_r_b_pnt, adj_g_r_pnt, adj_r_b_pnt, line_r_b_pnt)); |
||||
|
||||
experimental_area = getQuadrilateralArea(transformation_points[0], |
||||
transformation_points[1], |
||||
transformation_points[2], |
||||
transformation_points[3]); |
||||
std::vector<Point> quadrilateral = getQuadrilateral(transformation_points); |
||||
transformation_points = quadrilateral; |
||||
|
||||
int max_length_norm = -1; |
||||
size_t transform_size = transformation_points.size(); |
||||
for (size_t i = 0; i < transform_size; i++) |
||||
{ |
||||
int len_norm = static_cast<int>(norm(transformation_points[i % transform_size] - |
||||
transformation_points[(i + 1) % transform_size])); |
||||
if (max_length_norm < len_norm) { max_length_norm = len_norm; } |
||||
} |
||||
|
||||
std::vector<Point> perspective_points; |
||||
perspective_points.push_back(Point(0, 0)); |
||||
perspective_points.push_back(Point(0, max_length_norm)); |
||||
perspective_points.push_back(Point(max_length_norm, max_length_norm)); |
||||
perspective_points.push_back(Point(max_length_norm, 0)); |
||||
|
||||
// warpPerspective(bin_barcode, straight_barcode,
|
||||
// findHomography(transformation_points, perspective_points),
|
||||
// Size(max_length_norm, max_length_norm));
|
||||
return true; |
||||
} |
||||
|
||||
Point QRDecode::getTransformationPoint(Point left, Point center, double cos_angle_rotation, |
||||
bool right_rotate) |
||||
{ |
||||
Point temp_pnt, prev_pnt(0, 0), next_pnt, start_pnt(center); |
||||
double temp_delta, min_delta; |
||||
int steps = 0; |
||||
|
||||
future_pixel = 255; |
||||
while(true) |
||||
{ |
||||
min_delta = std::numeric_limits<double>::max(); |
||||
for (int i = -1; i < 2; i++) |
||||
{ |
||||
for (int j = -1; j < 2; j++) |
||||
{ |
||||
if (i == 0 && j == 0) { continue; } |
||||
temp_pnt = Point(start_pnt.x + i, start_pnt.y + j); |
||||
temp_delta = abs(getCosVectors(left, center, temp_pnt) - cos_angle_rotation); |
||||
if (temp_delta < min_delta && prev_pnt != temp_pnt) |
||||
{ |
||||
next_pnt = temp_pnt; |
||||
min_delta = temp_delta; |
||||
} |
||||
} |
||||
} |
||||
prev_pnt = start_pnt; |
||||
start_pnt = next_pnt; |
||||
next_pixel = bin_barcode.at<uint8_t>(start_pnt.y, start_pnt.x); |
||||
if (next_pixel == future_pixel) |
||||
{ |
||||
future_pixel = 255 - future_pixel; |
||||
steps++; |
||||
if (steps == 3) { break; } |
||||
} |
||||
} |
||||
|
||||
if (cos_angle_rotation == 0.0) |
||||
{ |
||||
Mat vector_mult(Size(3, 3), CV_32FC1); |
||||
vector_mult.at<float>(0, 0) = 1; |
||||
vector_mult.at<float>(1, 0) = 1; |
||||
vector_mult.at<float>(2, 0) = 1; |
||||
vector_mult.at<float>(0, 1) = static_cast<float>((left - center).x); |
||||
vector_mult.at<float>(1, 1) = static_cast<float>((left - center).y); |
||||
vector_mult.at<float>(0, 2) = static_cast<float>((left - start_pnt).x); |
||||
vector_mult.at<float>(1, 2) = static_cast<float>((left - start_pnt).y); |
||||
double res_vect_mult = determinant(vector_mult); |
||||
if (( right_rotate && res_vect_mult < 0) || |
||||
(!right_rotate && res_vect_mult > 0)) |
||||
{ |
||||
start_pnt = getTransformationPoint(start_pnt, center, -1); |
||||
} |
||||
} |
||||
|
||||
return start_pnt; |
||||
} |
||||
|
||||
Point QRDecode::intersectionLines(Point a1, Point a2, Point b1, Point b2) |
||||
{ |
||||
Point result_square_angle( |
||||
static_cast<int>( |
||||
static_cast<double> |
||||
((a1.x * a2.y - a1.y * a2.x) * (b1.x - b2.x) - |
||||
(b1.x * b2.y - b1.y * b2.x) * (a1.x - a2.x)) / |
||||
((a1.x - a2.x) * (b1.y - b2.y) - |
||||
(a1.y - a2.y) * (b1.x - b2.x))), |
||||
static_cast<int>( |
||||
static_cast<double> |
||||
((a1.x * a2.y - a1.y * a2.x) * (b1.y - b2.y) - |
||||
(b1.x * b2.y - b1.y * b2.x) * (a1.y - a2.y)) / |
||||
((a1.x - a2.x) * (b1.y - b2.y) - |
||||
(a1.y - a2.y) * (b1.x - b2.x))) |
||||
); |
||||
return result_square_angle; |
||||
} |
||||
|
||||
std::vector<Point> QRDecode::getQuadrilateral(std::vector<Point> angle_list) |
||||
{ |
||||
size_t angle_size = angle_list.size(); |
||||
uint8_t value, mask_value; |
||||
Mat mask(bin_barcode.rows + 2, bin_barcode.cols + 2, CV_8UC1); |
||||
for (size_t i = 0; i < angle_size; i++) |
||||
{ |
||||
LineIterator line_iter(bin_barcode, angle_list[ i % angle_size], |
||||
angle_list[(i + 1) % angle_size]); |
||||
for(int j = 0; j < line_iter.count; j++, ++line_iter) |
||||
{ |
||||
value = bin_barcode.at<uint8_t>(line_iter.pos()); |
||||
mask_value = mask.at<uint8_t>(line_iter.pos() + Point(1, 1)); |
||||
if (value == 0 && mask_value == 0) |
||||
{ |
||||
floodFill(bin_barcode, mask, line_iter.pos(), 255); |
||||
} |
||||
} |
||||
} |
||||
std::vector<Point> locations; |
||||
Mat mask_roi = mask(Range(1, bin_barcode.rows - 1), |
||||
Range(1, bin_barcode.cols - 1)); |
||||
|
||||
cv::findNonZero(mask_roi, locations); |
||||
|
||||
for (size_t i = 0; i < angle_list.size(); i++) |
||||
{ |
||||
locations.push_back(angle_list[i]); |
||||
} |
||||
|
||||
std::vector< std::vector<Point> > hull(1), approx_hull(1); |
||||
convexHull(Mat(locations), hull[0]); |
||||
int hull_size = static_cast<int>(hull[0].size()); |
||||
|
||||
Point min_pnt; |
||||
|
||||
std::vector<Point> min_abc; |
||||
double min_abs_cos_abc, abs_cos_abc; |
||||
for (int count = 0; count < 4; count++) |
||||
{ |
||||
min_abs_cos_abc = std::numeric_limits<double>::max(); |
||||
for (int i = 0; i < hull_size; i++) |
||||
{ |
||||
Point a = hull[0][ i % hull_size]; |
||||
Point b = hull[0][(i + 1) % hull_size]; |
||||
Point c = hull[0][(i + 2) % hull_size]; |
||||
abs_cos_abc = abs(getCosVectors(a, b, c)); |
||||
|
||||
bool flag_detect = true; |
||||
for (size_t j = 0; j < min_abc.size(); j++) |
||||
{ |
||||
if (min_abc[j] == b) { flag_detect = false; break; } |
||||
} |
||||
|
||||
if (flag_detect && (abs_cos_abc < min_abs_cos_abc)) |
||||
{ |
||||
min_pnt = b; |
||||
min_abs_cos_abc = abs_cos_abc; |
||||
} |
||||
} |
||||
min_abc.push_back(min_pnt); |
||||
} |
||||
|
||||
|
||||
int min_abc_size = static_cast<int>(min_abc.size()); |
||||
std::vector<int> index_min_abc(min_abc_size); |
||||
for (int i = 0; i < min_abc_size; i++) |
||||
{ |
||||
for (int j = 0; j < hull_size; j++) |
||||
{ |
||||
if (hull[0][j] == min_abc[i]) { index_min_abc[i] = j; break; } |
||||
} |
||||
} |
||||
|
||||
std::vector<Point> result_hull_point(angle_size); |
||||
double min_norm, temp_norm; |
||||
for (size_t i = 0; i < angle_size; i++) |
||||
{ |
||||
min_norm = std::numeric_limits<double>::max(); |
||||
Point closest_pnt; |
||||
for (int j = 0; j < min_abc_size; j++) |
||||
{ |
||||
if (min_norm > norm(hull[0][index_min_abc[j]] - angle_list[i])) |
||||
{ |
||||
min_norm = norm(hull[0][index_min_abc[j]] - angle_list[i]); |
||||
closest_pnt = hull[0][index_min_abc[j]]; |
||||
} |
||||
} |
||||
result_hull_point[i] = closest_pnt; |
||||
} |
||||
|
||||
int start_line[2] = {0, 0}, finish_line[2] = {0, 0}, unstable_pnt = 0; |
||||
for (int i = 0; i < hull_size; i++) |
||||
{ |
||||
if (result_hull_point[3] == hull[0][i]) { start_line[0] = i; } |
||||
if (result_hull_point[2] == hull[0][i]) { finish_line[0] = start_line[1] = i; } |
||||
if (result_hull_point[1] == hull[0][i]) { finish_line[1] = i; } |
||||
if (result_hull_point[0] == hull[0][i]) { unstable_pnt = i; } |
||||
} |
||||
|
||||
int index_hull, extra_index_hull, next_index_hull, extra_next_index_hull, count_points; |
||||
Point result_side_begin[4], result_side_end[4]; |
||||
|
||||
min_norm = std::numeric_limits<double>::max(); |
||||
index_hull = start_line[0]; |
||||
count_points = abs(start_line[0] - finish_line[0]); |
||||
do |
||||
{ |
||||
if (count_points > hull_size / 2) { next_index_hull = index_hull + 1; } |
||||
else { next_index_hull = index_hull - 1; } |
||||
|
||||
if (next_index_hull == hull_size) { next_index_hull = 0; } |
||||
if (next_index_hull == -1) { next_index_hull = hull_size - 1; } |
||||
|
||||
Point angle_closest_pnt = norm(hull[0][index_hull] - angle_list[2]) > |
||||
norm(hull[0][index_hull] - angle_list[3]) ? angle_list[3] : angle_list[2]; |
||||
|
||||
Point intrsc_line_hull = |
||||
intersectionLines(hull[0][index_hull], hull[0][next_index_hull], |
||||
angle_list[2], angle_list[3]); |
||||
temp_norm = getCosVectors(hull[0][index_hull], intrsc_line_hull, angle_closest_pnt); |
||||
if (min_norm > temp_norm && |
||||
norm(hull[0][index_hull] - hull[0][next_index_hull]) > |
||||
norm(angle_list[2] - angle_list[3]) / 10) |
||||
{ |
||||
min_norm = temp_norm; |
||||
result_side_begin[0] = hull[0][index_hull]; |
||||
result_side_end[0] = hull[0][next_index_hull]; |
||||
} |
||||
|
||||
|
||||
index_hull = next_index_hull; |
||||
} |
||||
while(index_hull != finish_line[0]); |
||||
|
||||
if (min_norm == std::numeric_limits<double>::max()) |
||||
{ |
||||
result_side_begin[0] = angle_list[2]; |
||||
result_side_end[0] = angle_list[3]; |
||||
} |
||||
|
||||
min_norm = std::numeric_limits<double>::max(); |
||||
index_hull = start_line[1]; |
||||
count_points = abs(start_line[1] - finish_line[1]); |
||||
do |
||||
{ |
||||
if (count_points > hull_size / 2) { next_index_hull = index_hull + 1; } |
||||
else { next_index_hull = index_hull - 1; } |
||||
|
||||
if (next_index_hull == hull_size) { next_index_hull = 0; } |
||||
if (next_index_hull == -1) { next_index_hull = hull_size - 1; } |
||||
|
||||
Point angle_closest_pnt = norm(hull[0][index_hull] - angle_list[1]) > |
||||
norm(hull[0][index_hull] - angle_list[2]) ? angle_list[2] : angle_list[1]; |
||||
|
||||
Point intrsc_line_hull = |
||||
intersectionLines(hull[0][index_hull], hull[0][next_index_hull], |
||||
angle_list[1], angle_list[2]); |
||||
temp_norm = getCosVectors(hull[0][index_hull], intrsc_line_hull, angle_closest_pnt); |
||||
if (min_norm > temp_norm && |
||||
norm(hull[0][index_hull] - hull[0][next_index_hull]) > |
||||
norm(angle_list[1] - angle_list[2]) / 20) |
||||
{ |
||||
min_norm = temp_norm; |
||||
result_side_begin[1] = hull[0][index_hull]; |
||||
result_side_end[1] = hull[0][next_index_hull]; |
||||
} |
||||
|
||||
|
||||
index_hull = next_index_hull; |
||||
} |
||||
while(index_hull != finish_line[1]); |
||||
|
||||
if (min_norm == std::numeric_limits<double>::max()) |
||||
{ |
||||
result_side_begin[1] = angle_list[1]; |
||||
result_side_end[1] = angle_list[2]; |
||||
} |
||||
|
||||
double test_norm[4] = { 0.0, 0.0, 0.0, 0.0 }; |
||||
int test_index[4]; |
||||
for (int i = 0; i < 4; i++) |
||||
{ |
||||
test_index[i] = (i < 2) ? static_cast<int>(start_line[0]) |
||||
: static_cast<int>(finish_line[1]); |
||||
do |
||||
{ |
||||
next_index_hull = ((i + 1) % 2 != 0) ? test_index[i] + 1 : test_index[i] - 1; |
||||
if (next_index_hull == hull_size) { next_index_hull = 0; } |
||||
if (next_index_hull == -1) { next_index_hull = hull_size - 1; } |
||||
test_norm[i] += norm(hull[0][next_index_hull] - hull[0][unstable_pnt]); |
||||
test_index[i] = next_index_hull; |
||||
} |
||||
while(test_index[i] != unstable_pnt); |
||||
} |
||||
|
||||
std::vector<Point> result_angle_list(4), test_result_angle_list(4); |
||||
double min_area = std::numeric_limits<double>::max(), test_area; |
||||
index_hull = start_line[0]; |
||||
do |
||||
{ |
||||
if (test_norm[0] < test_norm[1]) { next_index_hull = index_hull + 1; } |
||||
else { next_index_hull = index_hull - 1; } |
||||
|
||||
if (next_index_hull == hull_size) { next_index_hull = 0; } |
||||
if (next_index_hull == -1) { next_index_hull = hull_size - 1; } |
||||
|
||||
extra_index_hull = finish_line[1]; |
||||
do |
||||
{ |
||||
if (test_norm[2] < test_norm[3]) { extra_next_index_hull = extra_index_hull + 1; } |
||||
else { extra_next_index_hull = extra_index_hull - 1; } |
||||
|
||||
if (extra_next_index_hull == hull_size) { extra_next_index_hull = 0; } |
||||
if (extra_next_index_hull == -1) { extra_next_index_hull = hull_size - 1; } |
||||
|
||||
test_result_angle_list[0] |
||||
= intersectionLines(result_side_begin[0], result_side_end[0], |
||||
result_side_begin[1], result_side_end[1]); |
||||
test_result_angle_list[1] |
||||
= intersectionLines(result_side_begin[1], result_side_end[1], |
||||
hull[0][extra_index_hull], hull[0][extra_next_index_hull]); |
||||
test_result_angle_list[2] |
||||
= intersectionLines(hull[0][extra_index_hull], hull[0][extra_next_index_hull], |
||||
hull[0][index_hull], hull[0][next_index_hull]); |
||||
test_result_angle_list[3] |
||||
= intersectionLines(hull[0][index_hull], hull[0][next_index_hull], |
||||
result_side_begin[0], result_side_end[0]); |
||||
test_area = getQuadrilateralArea(test_result_angle_list[0], |
||||
test_result_angle_list[1], |
||||
test_result_angle_list[2], |
||||
test_result_angle_list[3]); |
||||
if (min_area > test_area) |
||||
{ |
||||
min_area = test_area; |
||||
for (size_t i = 0; i < test_result_angle_list.size(); i++) |
||||
{ |
||||
result_angle_list[i] = test_result_angle_list[i]; |
||||
} |
||||
} |
||||
|
||||
extra_index_hull = extra_next_index_hull; |
||||
} |
||||
while(extra_index_hull != unstable_pnt); |
||||
|
||||
index_hull = next_index_hull; |
||||
} |
||||
while(index_hull != unstable_pnt); |
||||
|
||||
if (norm(result_angle_list[0] - angle_list[2]) > |
||||
norm(angle_list[2] - angle_list[1]) / 3) { result_angle_list[0] = angle_list[2]; } |
||||
|
||||
if (norm(result_angle_list[1] - angle_list[1]) > |
||||
norm(angle_list[1] - angle_list[0]) / 3) { result_angle_list[1] = angle_list[1]; } |
||||
|
||||
if (norm(result_angle_list[2] - angle_list[0]) > |
||||
norm(angle_list[0] - angle_list[3]) / 3) { result_angle_list[2] = angle_list[0]; } |
||||
|
||||
if (norm(result_angle_list[3] - angle_list[3]) > |
||||
norm(angle_list[3] - angle_list[2]) / 3) { result_angle_list[3] = angle_list[3]; } |
||||
|
||||
|
||||
|
||||
return result_angle_list; |
||||
} |
||||
|
||||
// b __________ c
|
||||
// / |
|
||||
// / |
|
||||
// / S |
|
||||
// / |
|
||||
// a --------------- d
|
||||
|
||||
double QRDecode::getQuadrilateralArea(Point a, Point b, Point c, Point d) |
||||
{ |
||||
double length_sides[4], perimeter = 0.0, result_area = 1.0; |
||||
length_sides[0] = norm(a - b); length_sides[1] = norm(b - c); |
||||
length_sides[2] = norm(c - d); length_sides[3] = norm(d - a); |
||||
|
||||
for (int i = 0; i < 4; i++) { perimeter += length_sides[i]; } |
||||
perimeter /= 2; |
||||
|
||||
for (int i = 0; i < 4; i++) |
||||
{ |
||||
result_area *= (perimeter - length_sides[i]); |
||||
} |
||||
|
||||
result_area = sqrt(result_area); |
||||
|
||||
return result_area; |
||||
} |
||||
|
||||
// / | b
|
||||
// / |
|
||||
// / |
|
||||
// a/ | c
|
||||
|
||||
double QRDecode::getCosVectors(Point a, Point b, Point c) |
||||
{ |
||||
return ((a - b).x * (c - b).x + (a - b).y * (c - b).y) / (norm(a - b) * norm(c - b)); |
||||
} |
||||
|
||||
CV_EXPORTS bool detectQRCode(InputArray in, std::vector<Point> &points, double eps_x, double eps_y) |
||||
{ |
||||
CV_Assert(in.isMat()); |
||||
CV_Assert(in.getMat().type() == CV_8UC1); |
||||
QRDecode qrdec; |
||||
qrdec.init(in.getMat(), eps_x, eps_y); |
||||
qrdec.binarization(); |
||||
if (!qrdec.localization()) { return false; } |
||||
if (!qrdec.transformation()) { return false; } |
||||
points = qrdec.getTransformationPoints(); |
||||
return true; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,74 @@ |
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "test_precomp.hpp" |
||||
|
||||
namespace opencv_test { namespace { |
||||
|
||||
TEST(Objdetect_QRCode, regression) |
||||
{ |
||||
String root = cvtest::TS::ptr()->get_data_path() + "qrcode/"; |
||||
// String cascades[] =
|
||||
// {
|
||||
// root + "haarcascade_frontalface_alt.xml",
|
||||
// root + "lbpcascade_frontalface.xml",
|
||||
// String()
|
||||
// };
|
||||
|
||||
// vector<Rect> objects;
|
||||
// RNG rng((uint64)-1);
|
||||
|
||||
// for( int i = 0; !cascades[i].empty(); i++ )
|
||||
// {
|
||||
// printf("%d. %s\n", i, cascades[i].c_str());
|
||||
// CascadeClassifier cascade(cascades[i]);
|
||||
// for( int j = 0; j < 100; j++ )
|
||||
// {
|
||||
// int width = rng.uniform(1, 100);
|
||||
// int height = rng.uniform(1, 100);
|
||||
// Mat img(height, width, CV_8U);
|
||||
// randu(img, 0, 256);
|
||||
// cascade.detectMultiScale(img, objects);
|
||||
// }
|
||||
// }
|
||||
} |
||||
|
||||
}} // namespace
|
@ -0,0 +1,215 @@ |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.Random; |
||||
|
||||
import org.opencv.core.Core; |
||||
import org.opencv.core.CvType; |
||||
import org.opencv.core.Mat; |
||||
import org.opencv.core.MatOfPoint; |
||||
import org.opencv.core.Point; |
||||
import org.opencv.core.Scalar; |
||||
import org.opencv.highgui.HighGui; |
||||
import org.opencv.imgcodecs.Imgcodecs; |
||||
import org.opencv.imgproc.Imgproc; |
||||
|
||||
/** |
||||
* |
||||
* @brief Sample code showing how to segment overlapping objects using Laplacian filtering, in addition to Watershed |
||||
* and Distance Transformation |
||||
* |
||||
*/ |
||||
class ImageSegmentation { |
||||
public void run(String[] args) { |
||||
//! [load_image]
|
||||
// Load the image
|
||||
String filename = args.length > 0 ? args[0] : "../data/cards.png"; |
||||
Mat srcOriginal = Imgcodecs.imread(filename); |
||||
if (srcOriginal.empty()) { |
||||
System.err.println("Cannot read image: " + filename); |
||||
System.exit(0); |
||||
} |
||||
|
||||
// Show source image
|
||||
HighGui.imshow("Source Image", srcOriginal); |
||||
//! [load_image]
|
||||
|
||||
//! [black_bg]
|
||||
// Change the background from white to black, since that will help later to
|
||||
// extract
|
||||
// better results during the use of Distance Transform
|
||||
Mat src = srcOriginal.clone(); |
||||
byte[] srcData = new byte[(int) (src.total() * src.channels())]; |
||||
src.get(0, 0, srcData); |
||||
for (int i = 0; i < src.rows(); i++) { |
||||
for (int j = 0; j < src.cols(); j++) { |
||||
if (srcData[(i * src.cols() + j) * 3] == (byte) 255 && srcData[(i * src.cols() + j) * 3 + 1] == (byte) 255 |
||||
&& srcData[(i * src.cols() + j) * 3 + 2] == (byte) 255) { |
||||
srcData[(i * src.cols() + j) * 3] = 0; |
||||
srcData[(i * src.cols() + j) * 3 + 1] = 0; |
||||
srcData[(i * src.cols() + j) * 3 + 2] = 0; |
||||
} |
||||
} |
||||
} |
||||
src.put(0, 0, srcData); |
||||
|
||||
// Show output image
|
||||
HighGui.imshow("Black Background Image", src); |
||||
//! [black_bg]
|
||||
|
||||
//! [sharp]
|
||||
// Create a kernel that we will use to sharpen our image
|
||||
Mat kernel = new Mat(3, 3, CvType.CV_32F); |
||||
// an approximation of second derivative, a quite strong kernel
|
||||
float[] kernelData = new float[(int) (kernel.total() * kernel.channels())]; |
||||
kernelData[0] = 1; kernelData[1] = 1; kernelData[2] = 1; |
||||
kernelData[3] = 1; kernelData[4] = -8; kernelData[5] = 1; |
||||
kernelData[6] = 1; kernelData[7] = 1; kernelData[8] = 1; |
||||
kernel.put(0, 0, kernelData); |
||||
|
||||
// do the laplacian filtering as it is
|
||||
// well, we need to convert everything in something more deeper then CV_8U
|
||||
// because the kernel has some negative values,
|
||||
// and we can expect in general to have a Laplacian image with negative values
|
||||
// BUT a 8bits unsigned int (the one we are working with) can contain values
|
||||
// from 0 to 255
|
||||
// so the possible negative number will be truncated
|
||||
Mat imgLaplacian = new Mat(); |
||||
Imgproc.filter2D(src, imgLaplacian, CvType.CV_32F, kernel); |
||||
Mat sharp = new Mat(); |
||||
src.convertTo(sharp, CvType.CV_32F); |
||||
Mat imgResult = new Mat(); |
||||
Core.subtract(sharp, imgLaplacian, imgResult); |
||||
|
||||
// convert back to 8bits gray scale
|
||||
imgResult.convertTo(imgResult, CvType.CV_8UC3); |
||||
imgLaplacian.convertTo(imgLaplacian, CvType.CV_8UC3); |
||||
|
||||
// imshow( "Laplace Filtered Image", imgLaplacian );
|
||||
HighGui.imshow("New Sharped Image", imgResult); |
||||
//! [sharp]
|
||||
|
||||
//! [bin]
|
||||
// Create binary image from source image
|
||||
Mat bw = new Mat(); |
||||
Imgproc.cvtColor(imgResult, bw, Imgproc.COLOR_BGR2GRAY); |
||||
Imgproc.threshold(bw, bw, 40, 255, Imgproc.THRESH_BINARY | Imgproc.THRESH_OTSU); |
||||
HighGui.imshow("Binary Image", bw); |
||||
//! [bin]
|
||||
|
||||
//! [dist]
|
||||
// Perform the distance transform algorithm
|
||||
Mat dist = new Mat(); |
||||
Imgproc.distanceTransform(bw, dist, Imgproc.DIST_L2, 3); |
||||
|
||||
// Normalize the distance image for range = {0.0, 1.0}
|
||||
// so we can visualize and threshold it
|
||||
Core.normalize(dist, dist, 0, 1., Core.NORM_MINMAX); |
||||
Mat distDisplayScaled = dist.mul(dist, 255); |
||||
Mat distDisplay = new Mat(); |
||||
distDisplayScaled.convertTo(distDisplay, CvType.CV_8U); |
||||
HighGui.imshow("Distance Transform Image", distDisplay); |
||||
//! [dist]
|
||||
|
||||
//! [peaks]
|
||||
// Threshold to obtain the peaks
|
||||
// This will be the markers for the foreground objects
|
||||
Imgproc.threshold(dist, dist, .4, 1., Imgproc.THRESH_BINARY); |
||||
|
||||
// Dilate a bit the dist image
|
||||
Mat kernel1 = Mat.ones(3, 3, CvType.CV_8U); |
||||
Imgproc.dilate(dist, dist, kernel1); |
||||
Mat distDisplay2 = new Mat(); |
||||
dist.convertTo(distDisplay2, CvType.CV_8U); |
||||
distDisplay2 = distDisplay2.mul(distDisplay2, 255); |
||||
HighGui.imshow("Peaks", distDisplay2); |
||||
//! [peaks]
|
||||
|
||||
//! [seeds]
|
||||
// Create the CV_8U version of the distance image
|
||||
// It is needed for findContours()
|
||||
Mat dist_8u = new Mat(); |
||||
dist.convertTo(dist_8u, CvType.CV_8U); |
||||
|
||||
// Find total markers
|
||||
List<MatOfPoint> contours = new ArrayList<>(); |
||||
Mat hierarchy = new Mat(); |
||||
Imgproc.findContours(dist_8u, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); |
||||
|
||||
// Create the marker image for the watershed algorithm
|
||||
Mat markers = Mat.zeros(dist.size(), CvType.CV_32S); |
||||
|
||||
// Draw the foreground markers
|
||||
for (int i = 0; i < contours.size(); i++) { |
||||
Imgproc.drawContours(markers, contours, i, new Scalar(i + 1), -1); |
||||
} |
||||
|
||||
// Draw the background marker
|
||||
Imgproc.circle(markers, new Point(5, 5), 3, new Scalar(255, 255, 255), -1); |
||||
Mat markersScaled = markers.mul(markers, 10000); |
||||
Mat markersDisplay = new Mat(); |
||||
markersScaled.convertTo(markersDisplay, CvType.CV_8U); |
||||
HighGui.imshow("Markers", markersDisplay); |
||||
//! [seeds]
|
||||
|
||||
//! [watershed]
|
||||
// Perform the watershed algorithm
|
||||
Imgproc.watershed(imgResult, markers); |
||||
|
||||
Mat mark = Mat.zeros(markers.size(), CvType.CV_8U); |
||||
markers.convertTo(mark, CvType.CV_8UC1); |
||||
Core.bitwise_not(mark, mark); |
||||
// imshow("Markers_v2", mark); // uncomment this if you want to see how the mark
|
||||
// image looks like at that point
|
||||
|
||||
// Generate random colors
|
||||
Random rng = new Random(12345); |
||||
List<Scalar> colors = new ArrayList<>(contours.size()); |
||||
for (int i = 0; i < contours.size(); i++) { |
||||
int b = rng.nextInt(256); |
||||
int g = rng.nextInt(256); |
||||
int r = rng.nextInt(256); |
||||
|
||||
colors.add(new Scalar(b, g, r)); |
||||
} |
||||
|
||||
// Create the result image
|
||||
Mat dst = Mat.zeros(markers.size(), CvType.CV_8UC3); |
||||
byte[] dstData = new byte[(int) (dst.total() * dst.channels())]; |
||||
dst.get(0, 0, dstData); |
||||
|
||||
// Fill labeled objects with random colors
|
||||
int[] markersData = new int[(int) (markers.total() * markers.channels())]; |
||||
markers.get(0, 0, markersData); |
||||
for (int i = 0; i < markers.rows(); i++) { |
||||
for (int j = 0; j < markers.cols(); j++) { |
||||
int index = markersData[i * markers.cols() + j]; |
||||
if (index > 0 && index <= contours.size()) { |
||||
dstData[(i * dst.cols() + j) * 3 + 0] = (byte) colors.get(index - 1).val[0]; |
||||
dstData[(i * dst.cols() + j) * 3 + 1] = (byte) colors.get(index - 1).val[1]; |
||||
dstData[(i * dst.cols() + j) * 3 + 2] = (byte) colors.get(index - 1).val[2]; |
||||
} else { |
||||
dstData[(i * dst.cols() + j) * 3 + 0] = 0; |
||||
dstData[(i * dst.cols() + j) * 3 + 1] = 0; |
||||
dstData[(i * dst.cols() + j) * 3 + 2] = 0; |
||||
} |
||||
} |
||||
} |
||||
dst.put(0, 0, dstData); |
||||
|
||||
// Visualize the final image
|
||||
HighGui.imshow("Final Result", dst); |
||||
//! [watershed]
|
||||
|
||||
HighGui.waitKey(); |
||||
System.exit(0); |
||||
} |
||||
} |
||||
|
||||
public class ImageSegmentationDemo { |
||||
public static void main(String[] args) { |
||||
// Load the native OpenCV library
|
||||
System.loadLibrary(Core.NATIVE_LIBRARY_NAME); |
||||
|
||||
new ImageSegmentation().run(args); |
||||
} |
||||
} |
@ -0,0 +1,138 @@ |
||||
from __future__ import print_function |
||||
import cv2 as cv |
||||
import numpy as np |
||||
import argparse |
||||
import random as rng |
||||
|
||||
rng.seed(12345) |
||||
|
||||
## [load_image] |
||||
# Load the image |
||||
parser = argparse.ArgumentParser(description='Code for Image Segmentation with Distance Transform and Watershed Algorithm.\ |
||||
Sample code showing how to segment overlapping objects using Laplacian filtering, \ |
||||
in addition to Watershed and Distance Transformation') |
||||
parser.add_argument('--input', help='Path to input image.', default='../data/cards.png') |
||||
args = parser.parse_args() |
||||
|
||||
src = cv.imread(args.input) |
||||
if src is None: |
||||
print('Could not open or find the image:', args.input) |
||||
exit(0) |
||||
|
||||
# Show source image |
||||
cv.imshow('Source Image', src) |
||||
## [load_image] |
||||
|
||||
## [black_bg] |
||||
# Change the background from white to black, since that will help later to extract |
||||
# better results during the use of Distance Transform |
||||
src[np.all(src == 255, axis=2)] = 0 |
||||
|
||||
# Show output image |
||||
cv.imshow('Black Background Image', src) |
||||
## [black_bg] |
||||
|
||||
## [sharp] |
||||
# Create a kernel that we will use to sharpen our image |
||||
# an approximation of second derivative, a quite strong kernel |
||||
kernel = np.array([[1, 1, 1], [1, -8, 1], [1, 1, 1]], dtype=np.float32) |
||||
|
||||
# do the laplacian filtering as it is |
||||
# well, we need to convert everything in something more deeper then CV_8U |
||||
# because the kernel has some negative values, |
||||
# and we can expect in general to have a Laplacian image with negative values |
||||
# BUT a 8bits unsigned int (the one we are working with) can contain values from 0 to 255 |
||||
# so the possible negative number will be truncated |
||||
imgLaplacian = cv.filter2D(src, cv.CV_32F, kernel) |
||||
sharp = np.float32(src) |
||||
imgResult = sharp - imgLaplacian |
||||
|
||||
# convert back to 8bits gray scale |
||||
imgResult = np.clip(imgResult, 0, 255) |
||||
imgResult = imgResult.astype('uint8') |
||||
imgLaplacian = np.clip(imgLaplacian, 0, 255) |
||||
imgLaplacian = np.uint8(imgLaplacian) |
||||
|
||||
#cv.imshow('Laplace Filtered Image', imgLaplacian) |
||||
cv.imshow('New Sharped Image', imgResult) |
||||
## [sharp] |
||||
|
||||
## [bin] |
||||
# Create binary image from source image |
||||
bw = cv.cvtColor(imgResult, cv.COLOR_BGR2GRAY) |
||||
_, bw = cv.threshold(bw, 40, 255, cv.THRESH_BINARY | cv.THRESH_OTSU) |
||||
cv.imshow('Binary Image', bw) |
||||
## [bin] |
||||
|
||||
## [dist] |
||||
# Perform the distance transform algorithm |
||||
dist = cv.distanceTransform(bw, cv.DIST_L2, 3) |
||||
|
||||
# Normalize the distance image for range = {0.0, 1.0} |
||||
# so we can visualize and threshold it |
||||
cv.normalize(dist, dist, 0, 1.0, cv.NORM_MINMAX) |
||||
cv.imshow('Distance Transform Image', dist) |
||||
## [dist] |
||||
|
||||
## [peaks] |
||||
# Threshold to obtain the peaks |
||||
# This will be the markers for the foreground objects |
||||
_, dist = cv.threshold(dist, 0.4, 1.0, cv.THRESH_BINARY) |
||||
|
||||
# Dilate a bit the dist image |
||||
kernel1 = np.ones((3,3), dtype=np.uint8) |
||||
dist = cv.dilate(dist, kernel1) |
||||
cv.imshow('Peaks', dist) |
||||
## [peaks] |
||||
|
||||
## [seeds] |
||||
# Create the CV_8U version of the distance image |
||||
# It is needed for findContours() |
||||
dist_8u = dist.astype('uint8') |
||||
|
||||
# Find total markers |
||||
_, contours, _ = cv.findContours(dist_8u, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) |
||||
|
||||
# Create the marker image for the watershed algorithm |
||||
markers = np.zeros(dist.shape, dtype=np.int32) |
||||
|
||||
# Draw the foreground markers |
||||
for i in range(len(contours)): |
||||
cv.drawContours(markers, contours, i, (i+1), -1) |
||||
|
||||
# Draw the background marker |
||||
cv.circle(markers, (5,5), 3, (255,255,255), -1) |
||||
cv.imshow('Markers', markers*10000) |
||||
## [seeds] |
||||
|
||||
## [watershed] |
||||
# Perform the watershed algorithm |
||||
cv.watershed(imgResult, markers) |
||||
|
||||
#mark = np.zeros(markers.shape, dtype=np.uint8) |
||||
mark = markers.astype('uint8') |
||||
mark = cv.bitwise_not(mark) |
||||
# uncomment this if you want to see how the mark |
||||
# image looks like at that point |
||||
#cv.imshow('Markers_v2', mark) |
||||
|
||||
# Generate random colors |
||||
colors = [] |
||||
for contour in contours: |
||||
colors.append((rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))) |
||||
|
||||
# Create the result image |
||||
dst = np.zeros((markers.shape[0], markers.shape[1], 3), dtype=np.uint8) |
||||
|
||||
# Fill labeled objects with random colors |
||||
for i in range(markers.shape[0]): |
||||
for j in range(markers.shape[1]): |
||||
index = markers[i,j] |
||||
if index > 0 and index <= len(contours): |
||||
dst[i,j,:] = colors[index-1] |
||||
|
||||
# Visualize the final image |
||||
cv.imshow('Final Result', dst) |
||||
## [watershed] |
||||
|
||||
cv.waitKey() |
Loading…
Reference in new issue