diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..e72c70d8c --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,30 @@ + + +##### System information (version) + + +- OpenCV => :grey_question: +- Operating System / Platform => :grey_question: +- Compiler => :grey_question: + +##### Detailed description + + + +##### Steps to reproduce + + \ No newline at end of file diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..210a25311 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,9 @@ + + +### This pullrequest changes + + diff --git a/.travis.yml b/.travis.yml index 23b3aba4e..5c603efde 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ compiler: - clang before_script: - cd ../ - - git clone https://github.com/Itseez/opencv.git + - git clone https://github.com/opencv/opencv.git - mkdir build-opencv - cd build-opencv - cmake -DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib/modules ../opencv diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1e13c8996..318e9ac8f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,3 @@ ## Contributing guidelines -All guidelines for contributing to the OpenCV repository can be found at [`How to contribute guideline`](https://github.com/Itseez/opencv/wiki/How_to_contribute). +All guidelines for contributing to the OpenCV repository can be found at [`How to contribute guideline`](https://github.com/opencv/opencv/wiki/How_to_contribute). diff --git a/modules/dnn/CMakeLists.txt b/modules/dnn/CMakeLists.txt index 4e06d566e..2bdfe2902 100644 --- a/modules/dnn/CMakeLists.txt +++ b/modules/dnn/CMakeLists.txt @@ -1,6 +1,8 @@ cmake_minimum_required(VERSION 2.8) -if(APPLE_FRAMEWORK OR WINRT) +if(APPLE_FRAMEWORK OR WINRT + OR AARCH64 # protobuf doesn't know this platform +) ocv_module_disable(dnn) endif() diff --git a/modules/dnn/tutorials/tutorial_dnn_build.markdown b/modules/dnn/tutorials/tutorial_dnn_build.markdown index d5fbc7f6a..36f0fecbf 100644 --- a/modules/dnn/tutorials/tutorial_dnn_build.markdown +++ b/modules/dnn/tutorials/tutorial_dnn_build.markdown @@ -3,7 +3,7 @@ Build opencv_contrib with dnn module {#tutorial_dnn_build} Introduction ------------ -opencv_dnn module is placed in the secondary [opencv_contrib](https://github.com/Itseez/opencv_contrib) repository, +opencv_dnn module is placed in the secondary [opencv_contrib](https://github.com/opencv/opencv_contrib) repository, which isn't distributed in binary form, therefore you need to build it manually. To do this you need to have installed: [CMake](http://www.cmake.org/download), git, and build system (*gcc* with *make* for Linux or *MS Visual Studio* for Windows) @@ -12,12 +12,12 @@ Steps ----- -# Make any directory, for example **opencv_root** --# Clone [opencv](https://github.com/Itseez/opencv) and [opencv_contrib](https://github.com/Itseez/opencv_contrib) repos to the **opencv_root**. +-# Clone [opencv](https://github.com/opencv/opencv) and [opencv_contrib](https://github.com/opencv/opencv_contrib) repos to the **opencv_root**. You can do it in terminal like here: @code cd opencv_root -git clone https://github.com/Itseez/opencv -git clone https://github.com/Itseez/opencv_contrib +git clone https://github.com/opencv/opencv +git clone https://github.com/opencv/opencv_contrib @endcode -# Run [CMake-gui] and set source and build directories: diff --git a/modules/optflow/include/opencv2/optflow.hpp b/modules/optflow/include/opencv2/optflow.hpp index ac7cc3463..e95124336 100644 --- a/modules/optflow/include/opencv2/optflow.hpp +++ b/modules/optflow/include/opencv2/optflow.hpp @@ -305,6 +305,25 @@ public: /** @copybrief getGradientDescentIterations @see getGradientDescentIterations */ CV_WRAP virtual void setVariationalRefinementIterations(int val) = 0; + /** @brief Weight of the smoothness term + @see setVariationalRefinementAlpha */ + CV_WRAP virtual float getVariationalRefinementAlpha() const = 0; + /** @copybrief getVariationalRefinementAlpha @see getVariationalRefinementAlpha */ + CV_WRAP virtual void setVariationalRefinementAlpha(float val) = 0; + + /** @brief Weight of the color constancy term + @see setVariationalRefinementDelta */ + CV_WRAP virtual float getVariationalRefinementDelta() const = 0; + /** @copybrief getVariationalRefinementDelta @see getVariationalRefinementDelta */ + CV_WRAP virtual void setVariationalRefinementDelta(float val) = 0; + + /** @brief Weight of the gradient constancy term + @see setVariationalRefinementGamma */ + CV_WRAP virtual float getVariationalRefinementGamma() const = 0; + /** @copybrief getVariationalRefinementGamma @see getVariationalRefinementGamma */ + CV_WRAP virtual void setVariationalRefinementGamma(float val) = 0; + + /** @brief Whether to use mean-normalization of patches when computing patch distance. It is turned on by default as it typically provides a noticeable quality boost because of increased robustness to illumanition variations. Turn it off if you are certain that your sequence does't contain any changes diff --git a/modules/optflow/src/deepflow.cpp b/modules/optflow/src/deepflow.cpp index 284061a4c..a813e5a94 100644 --- a/modules/optflow/src/deepflow.cpp +++ b/modules/optflow/src/deepflow.cpp @@ -67,26 +67,12 @@ protected: float gamma; // gradient constancy weight float omega; // relaxation factor in SOR - float zeta; // added to the denomimnator of theta_0 (normaliation of the data term) - float epsilon; // robust penalizer const int maxLayers; // max amount of layers in the pyramid + int interpolationType; private: - void calcOneLevel( const Mat I0, const Mat I1, Mat W ); - Mat warpImage( const Mat input, const Mat flow ); - void dataTerm( const Mat W, const Mat dW, const Mat Ix, const Mat Iy, const Mat Iz, - const Mat Ixx, const Mat Ixy, const Mat Iyy, const Mat Ixz, const Mat Iyz, - Mat a11, Mat a12, Mat a22, Mat b1, Mat b2 ); - void smoothnessWeights( const Mat W, Mat weightsX, Mat weightsY ); - void smoothnessTerm( const Mat W, const Mat weightsX, const Mat weightsY, Mat b1, Mat b2 ); - void sorSolve( const Mat a11, const Mat a12, const Mat a22, const Mat b1, const Mat b2, - const Mat smoothX, const Mat smoothY, Mat dW ); - void sorUnfolded( const Mat a11, const Mat a12, const Mat a22, const Mat b1, const Mat b2, - const Mat smoothX, const Mat smoothY, Mat dW ); std::vector buildPyramid( const Mat& src ); - int interpolationType; - }; OpticalFlowDeepFlow::OpticalFlowDeepFlow() @@ -104,8 +90,6 @@ OpticalFlowDeepFlow::OpticalFlowDeepFlow() //consts interpolationType = INTER_LINEAR; - zeta = 0.1f; - epsilon = 0.001f; maxLayers = 200; } @@ -130,31 +114,7 @@ std::vector OpticalFlowDeepFlow::buildPyramid( const Mat& src ) } return pyramid; } -Mat OpticalFlowDeepFlow::warpImage( const Mat input, const Mat flow ) -{ - // warps the image "backwards" - // if flow = computeFlow( I0, I1 ), then - // I0 = warpImage( I1, flow ) - approx. - Mat output; - Mat mapX = Mat(flow.size(), CV_32FC1); - Mat mapY = Mat(flow.size(), CV_32FC1); - const float *pFlow; - float *pMapX, *pMapY; - for ( int j = 0; j < flow.rows; ++j ) - { - pFlow = flow.ptr(j); - pMapX = mapX.ptr(j); - pMapY = mapY.ptr(j); - for ( int i = 0; i < flow.cols; ++i ) - { - pMapX[i] = i + pFlow[2 * i]; - pMapY[i] = j + pFlow[2 * i + 1]; - } - } - remap(input, output, mapX, mapY, interpolationType); - return output; -} void OpticalFlowDeepFlow::calc( InputArray _I0, InputArray _I1, InputOutputArray _flow ) { Mat I0temp = _I0.getMat(); @@ -189,7 +149,16 @@ void OpticalFlowDeepFlow::calc( InputArray _I0, InputArray _I1, InputOutputArray for ( int level = levelCount - 1; level >= 0; --level ) { //iterate through all levels, beginning with the most coarse - calcOneLevel(pyramid_I0[level], pyramid_I1[level], W); + Ptr var = createVariationalFlowRefinement(); + + var->setAlpha(4 * alpha); + var->setDelta(delta / 3); + var->setGamma(gamma / 3); + var->setFixedPointIterations(fixedPointIterations); + var->setSorIterations(sorIterations); + var->setOmega(omega); + + var->calc(pyramid_I0[level], pyramid_I1[level], W); if ( level > 0 ) //not the last level { Mat temp; @@ -201,666 +170,9 @@ void OpticalFlowDeepFlow::calc( InputArray _I0, InputArray _I1, InputOutputArray W.copyTo(_flow); } -void OpticalFlowDeepFlow::calcOneLevel( const Mat I0, const Mat I1, Mat W ) -{ - CV_DbgAssert( I0.size() == I1.size() );CV_DbgAssert( I0.type() == I1.type() );CV_DbgAssert( W.size() == I0.size() ); - - // linear equation systems - Size s = I0.size(); - int t = CV_32F; // data type - Mat a11, a12, a22, b1, b2; - a11.create(s, t); - a12.create(s, t); - a22.create(s, t); - b1.create(s, t); - b2.create(s, t); - // diffusivity coeffs - Mat weightsX, weightsY; - weightsX.create(s, t); - weightsY.create(s, t); - - Mat warpedI1 = warpImage(I1, W); // warped second image - Mat averageFrame = 0.5 * (I0 + warpedI1); // mean value of 2 frames - to compute derivatives on - - //computing derivatives, notation as in Brox's paper - Mat Ix, Iy, Iz, Ixx, Ixy, Iyy, Ixz, Iyz; - int ddepth = -1; //as source image - int kernel_size = 1; - - Sobel(averageFrame, Ix, ddepth, 1, 0, kernel_size, 1, 0.00, BORDER_REPLICATE); - Sobel(averageFrame, Iy, ddepth, 0, 1, kernel_size, 1, 0.00, BORDER_REPLICATE); - Iz.create(I1.size(), I1.type()); - Iz = warpedI1 - I0; - Sobel(Ix, Ixx, ddepth, 1, 0, kernel_size, 1, 0.00, BORDER_REPLICATE); - Sobel(Ix, Ixy, ddepth, 0, 1, kernel_size, 1, 0.00, BORDER_REPLICATE); - Sobel(Iy, Iyy, ddepth, 0, 1, kernel_size, 1, 0.00, BORDER_REPLICATE); - Sobel(Iz, Ixz, ddepth, 1, 0, kernel_size, 1, 0.00, BORDER_REPLICATE); - Sobel(Iz, Iyz, ddepth, 0, 1, kernel_size, 1, 0.00, BORDER_REPLICATE); - - Mat tempW = W.clone(); // flow version to be modified in each iteration - Mat dW = Mat::zeros(W.size(), W.type()); // flow increment - - //fixed-point iterations - for ( int i = 0; i < fixedPointIterations; ++i ) - { - dataTerm(W, dW, Ix, Iy, Iz, Ixx, Ixy, Iyy, Ixz, Iyz, a11, a12, a22, b1, b2); - smoothnessWeights(tempW, weightsX, weightsY); - smoothnessTerm(W, weightsX, weightsY, b1, b2); - sorSolve(a11, a12, a22, b1, b2, weightsX, weightsY, dW); - tempW = W + dW; - } - tempW.copyTo(W); -} -void OpticalFlowDeepFlow::dataTerm( const Mat W, const Mat dW, const Mat Ix, const Mat Iy, - const Mat Iz, const Mat Ixx, const Mat Ixy, const Mat Iyy, const Mat Ixz, - const Mat Iyz, Mat a11, Mat a12, Mat a22, Mat b1, Mat b2 ) -{ - const float zeta_squared = zeta * zeta; // added in normalization factor to be non-zero - const float epsilon_squared = epsilon * epsilon; - - const float *pIx, *pIy, *pIz; - const float *pIxx, *pIxy, *pIyy, *pIxz, *pIyz; - const float *pdU, *pdV; // accessing 2 layers of dW. Succesive columns interleave u and v - float *pa11, *pa12, *pa22, *pb1, *pb2; // linear equation sys. coeffs for each pixel - - float derivNorm; //denominator of the spatial-derivative normalizing factor (theta_0) - float derivNorm2; - float Ik1z, Ik1zx, Ik1zy; // approximations of I^(k+1) values by Taylor expansions - float temp; - for ( int j = 0; j < W.rows; j++ ) //for each row - { - pIx = Ix.ptr(j); - pIy = Iy.ptr(j); - pIz = Iz.ptr(j); - pIxx = Ixx.ptr(j); - pIxy = Ixy.ptr(j); - pIyy = Iyy.ptr(j); - pIxz = Ixz.ptr(j); - pIyz = Iyz.ptr(j); - - pa11 = a11.ptr(j); - pa12 = a12.ptr(j); - pa22 = a22.ptr(j); - pb1 = b1.ptr(j); - pb2 = b2.ptr(j); - - pdU = dW.ptr(j); - pdV = pdU + 1; - for ( int i = 0; i < W.cols; i++ ) //for each pixel in the row - { // TODO: implement masking of points warped out of the image - //color constancy component - derivNorm = (*pIx) * (*pIx) + (*pIy) * (*pIy) + zeta_squared; - Ik1z = *pIz + (*pIx * *pdU) + (*pIy * *pdV); - temp = (0.5f*delta/3) / sqrt(Ik1z * Ik1z / derivNorm + epsilon_squared); - *pa11 = *pIx * *pIx * temp / derivNorm; - *pa12 = *pIx * *pIy * temp / derivNorm; - *pa22 = *pIy * *pIy * temp / derivNorm; - *pb1 = -*pIz * *pIx * temp / derivNorm; - *pb2 = -*pIz * *pIy * temp / derivNorm; - - // gradient constancy component - - derivNorm = *pIxx * *pIxx + *pIxy * *pIxy + zeta_squared; - derivNorm2 = *pIyy * *pIyy + *pIxy * *pIxy + zeta_squared; - Ik1zx = *pIxz + *pIxx * *pdU + *pIxy * *pdV; - Ik1zy = *pIyz + *pIxy * *pdU + *pIyy * *pdV; - - temp = (0.5f*gamma/3) - / sqrt( - Ik1zx * Ik1zx / derivNorm + Ik1zy * Ik1zy / derivNorm2 - + epsilon_squared); - *pa11 += temp * (*pIxx * *pIxx / derivNorm + *pIxy * *pIxy / derivNorm2); - *pa12 += temp * (*pIxx * *pIxy / derivNorm + *pIxy * *pIyy / derivNorm2); - *pa22 += temp * (*pIxy * *pIxy / derivNorm + *pIyy * *pIyy / derivNorm2); - *pb1 += -temp * (*pIxx * *pIxz / derivNorm + *pIxy * *pIyz / derivNorm2); - *pb2 += -temp * (*pIxy * *pIxz / derivNorm + *pIyy * *pIyz / derivNorm2); - - ++pIx; - ++pIy; - ++pIz; - ++pIxx; - ++pIxy; - ++pIyy; - ++pIxz; - ++pIyz; - pdU += 2; - pdV += 2; - ++pa11; - ++pa12; - ++pa22; - ++pb1; - ++pb2; - - } - } - - - -} -void OpticalFlowDeepFlow::smoothnessWeights( const Mat W, Mat weightsX, Mat weightsY ) -{ - float k[] = { -0.5, 0, 0.5 }; - const float epsilon_squared = epsilon * epsilon; - Mat kernel_h = Mat(1, 3, CV_32FC1, k); - Mat kernel_v = Mat(3, 1, CV_32FC1, k); - Mat Wx, Wy; // partial derivatives of the flow - Mat S = Mat(W.size(), CV_32FC1); // sum of squared derivatives - weightsX = Mat::zeros(W.size(), CV_32FC1); //output - weights of smoothness terms in x and y directions - weightsY = Mat::zeros(W.size(), CV_32FC1); - - filter2D(W, Wx, CV_32FC2, kernel_h); - filter2D(W, Wy, CV_32FC2, kernel_v); - - const float * ux, *uy, *vx, *vy; - float * pS, *pWeight, *temp; - - for ( int j = 0; j < S.rows; ++j ) - { - ux = Wx.ptr(j); - vx = ux + 1; - uy = Wy.ptr(j); - vy = uy + 1; - pS = S.ptr(j); - for ( int i = 0; i < S.cols; ++i ) - { - *pS = alpha / sqrt(*ux * *ux + *vx * *vx + *uy * *uy + *vy * *vy + epsilon_squared); - ux += 2; - vx += 2; - uy += 2; - vy += 2; - ++pS; - } - } - // horizontal weights - for ( int j = 0; j < S.rows; ++j ) - { - pWeight = weightsX.ptr(j); - pS = S.ptr(j); - for ( int i = 0; i < S.cols - 1; ++i ) - { - *pWeight = *pS + *(pS + 1); - ++pS; - ++pWeight; - } - } - //vertical weights - for ( int j = 0; j < S.rows - 1; ++j ) - { - pWeight = weightsY.ptr(j); - pS = S.ptr(j); - temp = S.ptr(j + 1); // next row pointer for easy access - for ( int i = 0; i < S.cols; ++i ) - { - *pWeight = *(pS++) + *(temp++); - ++pWeight; - } - } -} -void OpticalFlowDeepFlow::smoothnessTerm( const Mat W, const Mat weightsX, const Mat weightsY, - Mat b1, Mat b2 ) -{ - float *pB1, *pB2; - const float *pU, *pV, *pWeight; - float iB1, iB2; // increments of b1 and b2 - //horizontal direction - both U and V (b1 and b2) - for ( int j = 0; j < W.rows; j++ ) - { - pB1 = b1.ptr(j); - pB2 = b2.ptr(j); - pU = W.ptr(j); - pV = pU + 1; - pWeight = weightsX.ptr(j); - for ( int i = 0; i < W.cols - 1; i++ ) - { - iB1 = (*(pU + 2) - *pU) * *pWeight; - iB2 = (*(pV + 2) - *pV) * *pWeight; - *pB1 += iB1; - *(pB1 + 1) -= iB1; - *pB2 += iB2; - *(pB2 + 1) -= iB2; - - pB1++; - pB2++; - pU += 2; - pV += 2; - pWeight++; - } - } - const float *pUnext, *pVnext; // temp pointers for next row - float *pB1next, *pB2next; - //vertical direction - both U and V - for ( int j = 0; j < W.rows - 1; j++ ) - { - pB1 = b1.ptr(j); - pB2 = b2.ptr(j); - pU = W.ptr(j); - pV = pU + 1; - pUnext = W.ptr(j + 1); - pVnext = pUnext + 1; - pB1next = b1.ptr(j + 1); - pB2next = b2.ptr(j + 1); - pWeight = weightsY.ptr(j); - for ( int i = 0; i < W.cols; i++ ) - { - iB1 = (*pUnext - *pU) * *pWeight; - iB2 = (*pVnext - *pV) * *pWeight; - *pB1 += iB1; - *pB1next -= iB1; - *pB2 += iB2; - *pB2next -= iB2; - - pB1++; - pB2++; - pU += 2; - pV += 2; - pWeight++; - pUnext += 2; - pVnext += 2; - pB1next++; - pB2next++; - } - } -} - -void OpticalFlowDeepFlow::sorSolve( const Mat a11, const Mat a12, const Mat a22, const Mat b1, - const Mat b2, const Mat smoothX, const Mat smoothY, Mat dW ) -{ - CV_Assert(a11.isContinuous()); - CV_Assert(a12.isContinuous()); - CV_Assert(a22.isContinuous()); - CV_Assert(b1.isContinuous()); - CV_Assert(b2.isContinuous()); - CV_Assert(smoothX.isContinuous()); - CV_Assert(smoothY.isContinuous()); - - if(dW.cols > 2 && dW.rows > 2) - { - sorUnfolded(a11, a12, a22, b1, b2, smoothX, smoothY, dW ); - //more efficient version - this one is mostly for future reference and readability - return; - } - std::vector dWChannels(2); - split(dW, dWChannels); - - Mat *du = &(dWChannels[0]); - Mat *dv = &(dWChannels[1]); - - CV_Assert(du->isContinuous()); - CV_Assert(dv->isContinuous()); - - const float *pa11, *pa12, *pa22, *pb1, *pb2, *psmoothX, *psmoothY; - float *pdu, *pdv; - psmoothX = smoothX.ptr(0); - psmoothY = smoothY.ptr(0); - pdu = du->ptr(0); - pdv = dv->ptr(0); - - float sigmaU, sigmaV, dPsi, A11, A22, A12, B1, B2, det; - - int cols = dW.cols; - int rows = dW.rows; - - int s = dW.cols; // step between rows - - for ( int iter = 0; iter < sorIterations; ++iter ) - { - pa11 = a11.ptr(0); - pa12 = a12.ptr(0); - pa22 = a22.ptr(0); - pb1 = b1.ptr(0); - pb2 = b2.ptr(0); - for ( int j = 0; j < rows; ++j ) - { - for ( int i = 0; i < cols; ++i ) - { - int o = j * s + i; - if ( i == 0 && j == 0 ) - { - dPsi = psmoothX[o] + psmoothY[o]; - sigmaU = psmoothX[o] * pdu[o + 1] + psmoothY[o] * pdu[o + s]; - sigmaV = psmoothX[o] * pdv[o + 1] + psmoothY[o] * pdv[o + s]; - } else if ( i == cols - 1 && j == 0 ) - { - dPsi = psmoothX[o - 1] + psmoothY[o]; - sigmaU = psmoothX[o - 1] * pdu[o - 1] - + psmoothY[o] * pdu[o + s]; - sigmaV = psmoothX[o - 1] * pdv[o - 1] - + psmoothY[o] * pdv[o + s]; - } else if ( j == 0 ) - { - dPsi = psmoothX[o - 1] + psmoothX[o] + psmoothY[o]; - sigmaU = psmoothX[o - 1] * pdu[o - 1] - + psmoothX[o] * pdu[o + 1] + psmoothY[o] * pdu[o + s]; - sigmaV = psmoothX[o - 1] * pdv[o - 1] - + psmoothX[o] * pdv[o + 1] + psmoothY[o] * pdv[o + s]; - } else if ( i == 0 && j == rows - 1 ) - { - dPsi = psmoothX[o] + psmoothY[o - s]; - sigmaU = psmoothX[o] * pdu[o + 1] - + psmoothY[o - s] * pdu[o - s]; - sigmaV = psmoothX[o] * pdv[o + 1] - + psmoothY[o - s] * pdv[o - s]; - } else if ( i == cols - 1 && j == rows - 1 ) - { - dPsi = psmoothX[o - 1] + psmoothY[o - s]; - sigmaU = psmoothX[o - 1] * pdu[o - 1] - + psmoothY[o - s] * pdu[o - s]; - sigmaV = psmoothX[o - 1] * pdv[o - 1] - + psmoothY[o - s] * pdv[o - s]; - } else if ( j == rows - 1 ) - { - dPsi = psmoothX[o - 1] + psmoothX[o] + psmoothY[o - s]; - sigmaU = psmoothX[o - 1] * pdu[o - 1] - + psmoothX[o] * pdu[o + 1] - + psmoothY[o - s] * pdu[o - s]; - sigmaV = psmoothX[o - 1] * pdv[o - 1] - + psmoothX[o] * pdv[o + 1] - + psmoothY[o - s] * pdv[o - s]; - } else if ( i == 0 ) - { - dPsi = psmoothX[o] + psmoothY[o - s] + psmoothY[o]; - sigmaU = psmoothX[o] * pdu[o + 1] - + psmoothY[o - s] * pdu[o - s] - + psmoothY[o] * pdu[o + s]; - sigmaV = psmoothX[o] * pdv[o + 1] - + psmoothY[o - s] * pdv[o - s] - + psmoothY[o] * pdv[o + s]; - } else if ( i == cols - 1 ) - { - dPsi = psmoothX[o - 1] + psmoothY[o - s] + psmoothY[o]; - sigmaU = psmoothX[o - 1] * pdu[o - 1] - + psmoothY[o - s] * pdu[o - s] - + psmoothY[o] * pdu[o + s]; - sigmaV = psmoothX[o - 1] * pdv[o - 1] - + psmoothY[o - s] * pdv[o - s] - + psmoothY[o] * pdv[o + s]; - } else - { - dPsi = psmoothX[o - 1] + psmoothX[o] + psmoothY[o - s] - + psmoothY[o]; - sigmaU = psmoothX[o - 1] * pdu[o - 1] - + psmoothX[o] * pdu[o + 1] - + psmoothY[o - s] * pdu[o - s] - + psmoothY[o] * pdu[o + s]; - sigmaV = psmoothX[o - 1] * pdv[o - 1] - + psmoothX[o] * pdv[o + 1] - + psmoothY[o - s] * pdv[o - s] - + psmoothY[o] * pdv[o + s]; - } - A11 = *pa22 + dPsi; - A12 = -*pa12; - A22 = *pa11 + dPsi; - det = A11 * A22 - A12 * A12; - A11 /= det; - A12 /= det; - A22 /= det; - B1 = *pb1 + sigmaU; - B2 = *pb2 + sigmaV; - pdu[o] += omega * (A11 * B1 + A12 * B2 - pdu[o]); - pdv[o] += omega * (A12 * B1 + A22 * B2 - pdv[o]); - ++pa11; ++pa12; ++pa22; ++pb1; ++pb2; - } - } - } - merge(dWChannels, dW); -} - - -void OpticalFlowDeepFlow::sorUnfolded( const Mat a11, const Mat a12, const Mat a22, const Mat b1, const Mat b2, - const Mat smoothX, const Mat smoothY, Mat dW ) -{ - // the same effect as sorSolve(), but written more efficiently - std::vector dWChannels(2); - split(dW, dWChannels); - - Mat *du = &(dWChannels[0]); - Mat *dv = &(dWChannels[1]); - - CV_Assert(du->isContinuous()); - CV_Assert(dv->isContinuous()); - - const float *pa11, *pa12, *pa22, *pb1, *pb2, *psmoothX, *psmoothY; - float *pdu, *pdv; - - - float sigmaU, sigmaV, dPsi, A11, A22, A12, B1, B2, det; - - int cols = dW.cols; - int rows = dW.rows; - - int s = dW.cols; // step between rows - int j, i, o; //row, column, offset - - for ( int iter = 0; iter < sorIterations; ++iter ) - { - pa11 = a11.ptr(0); - pa12 = a12.ptr(0); - pa22 = a22.ptr(0); - pb1 = b1.ptr(0); - pb2 = b2.ptr(0); - psmoothX = smoothX.ptr(0); - psmoothY = smoothY.ptr(0); - pdu = du->ptr(0); - pdv = dv->ptr(0); - - // first row - // first column - o=0; - dPsi = psmoothX[o] + psmoothY[o]; - sigmaU = psmoothX[o] * pdu[o + 1] + psmoothY[o] * pdu[o + s]; - sigmaV = psmoothX[o] * pdv[o + 1] + psmoothY[o] * pdv[o + s]; - A11 = *pa22 + dPsi; - A12 = -*pa12; - A22 = *pa11 + dPsi; - det = A11 * A22 - A12 * A12; - A11 /= det; - A12 /= det; - A22 /= det; - B1 = *pb1 + sigmaU; - B2 = *pb2 + sigmaV; - pdu[o] += omega * (A11 * B1 + A12 * B2 - pdu[o]); - pdv[o] += omega * (A12 * B1 + A22 * B2 - pdv[o]); - ++pa11; ++pa12; ++pa22; ++pb1; ++pb2; - // middle rows - for ( o = 1; o < cols-1; ++o ) - { - dPsi = psmoothX[o - 1] + psmoothX[o] + psmoothY[o]; - sigmaU = psmoothX[o - 1] * pdu[o - 1] - + psmoothX[o] * pdu[o + 1] + psmoothY[o] * pdu[o + s]; - sigmaV = psmoothX[o - 1] * pdv[o - 1] - + psmoothX[o] * pdv[o + 1] + psmoothY[o] * pdv[o + s]; - A11 = *pa22 + dPsi; - A12 = -*pa12; - A22 = *pa11 + dPsi; - det = A11 * A22 - A12 * A12; - A11 /= det; - A12 /= det; - A22 /= det; - B1 = *pb1 + sigmaU; - B2 = *pb2 + sigmaV; - pdu[o] += omega * (A11 * B1 + A12 * B2 - pdu[o]); - pdv[o] += omega * (A12 * B1 + A22 * B2 - pdv[o]); - ++pa11; ++pa12; ++pa22; ++pb1; ++pb2; - } - // last column - dPsi = psmoothX[o - 1] + psmoothY[o]; - sigmaU = psmoothX[o - 1] * pdu[o - 1] - + psmoothY[o] * pdu[o + s]; - sigmaV = psmoothX[o - 1] * pdv[o - 1] - + psmoothY[o] * pdv[o + s]; - A11 = *pa22 + dPsi; - A12 = -*pa12; - A22 = *pa11 + dPsi; - det = A11 * A22 - A12 * A12; - A11 /= det; - A12 /= det; - A22 /= det; - B1 = *pb1 + sigmaU; - B2 = *pb2 + sigmaV; - pdu[o] += omega * (A11 * B1 + A12 * B2 - pdu[o]); - pdv[o] += omega * (A12 * B1 + A22 * B2 - pdv[o]); - ++pa11; ++pa12; ++pa22; ++pb1; ++pb2; - ++o; - //middle rows - for ( j = 1; j < rows - 1; ++j) - { - // first column - dPsi = psmoothX[o] + psmoothY[o - s] + psmoothY[o]; - sigmaU = psmoothX[o] * pdu[o + 1] - + psmoothY[o - s] * pdu[o - s] - + psmoothY[o] * pdu[o + s]; - sigmaV = psmoothX[o] * pdv[o + 1] - + psmoothY[o - s] * pdv[o - s] - + psmoothY[o] * pdv[o + s]; - A11 = *pa22 + dPsi; - A12 = -*pa12; - A22 = *pa11 + dPsi; - det = A11 * A22 - A12 * A12; - A11 /= det; - A12 /= det; - A22 /= det; - B1 = *pb1 + sigmaU; - B2 = *pb2 + sigmaV; - pdu[o] += omega * (A11 * B1 + A12 * B2 - pdu[o]); - pdv[o] += omega * (A12 * B1 + A22 * B2 - pdv[o]); - ++pa11; ++pa12; ++pa22; ++pb1; ++pb2; - ++o; - // middle columns - for ( i = 1; i < cols - 1; ++i) - { - dPsi = psmoothX[o - 1] + psmoothX[o] + psmoothY[o - s] - + psmoothY[o]; - sigmaU = psmoothX[o - 1] * pdu[o - 1] - + psmoothX[o] * pdu[o + 1] - + psmoothY[o - s] * pdu[o - s] - + psmoothY[o] * pdu[o + s]; - sigmaV = psmoothX[o - 1] * pdv[o - 1] - + psmoothX[o] * pdv[o + 1] - + psmoothY[o - s] * pdv[o - s] - + psmoothY[o] * pdv[o + s]; - A11 = *pa22 + dPsi; - A12 = -*pa12; - A22 = *pa11 + dPsi; - det = A11 * A22 - A12 * A12; - A11 /= det; - A12 /= det; - A22 /= det; - B1 = *pb1 + sigmaU; - B2 = *pb2 + sigmaV; - pdu[o] += omega * (A11 * B1 + A12 * B2 - pdu[o]); - pdv[o] += omega * (A12 * B1 + A22 * B2 - pdv[o]); - ++pa11; ++pa12; ++pa22; ++pb1; ++pb2; - ++o; - } - //last column - dPsi = psmoothX[o - 1] + psmoothY[o - s] + psmoothY[o]; - sigmaU = psmoothX[o - 1] * pdu[o - 1] - + psmoothY[o - s] * pdu[o - s] - + psmoothY[o] * pdu[o + s]; - sigmaV = psmoothX[o - 1] * pdv[o - 1] - + psmoothY[o - s] * pdv[o - s] - + psmoothY[o] * pdv[o + s]; - A11 = *pa22 + dPsi; - A12 = -*pa12; - A22 = *pa11 + dPsi; - det = A11 * A22 - A12 * A12; - A11 /= det; - A12 /= det; - A22 /= det; - B1 = *pb1 + sigmaU; - B2 = *pb2 + sigmaV; - pdu[o] += omega * (A11 * B1 + A12 * B2 - pdu[o]); - pdv[o] += omega * (A12 * B1 + A22 * B2 - pdv[o]); - ++pa11; ++pa12; ++pa22; ++pb1; ++pb2; - ++o; - } - //last row - //first column - dPsi = psmoothX[o] + psmoothY[o - s]; - sigmaU = psmoothX[o] * pdu[o + 1] - + psmoothY[o - s] * pdu[o - s]; - sigmaV = psmoothX[o] * pdv[o + 1] - + psmoothY[o - s] * pdv[o - s]; - A11 = *pa22 + dPsi; - A12 = -*pa12; - A22 = *pa11 + dPsi; - det = A11 * A22 - A12 * A12; - A11 /= det; - A12 /= det; - A22 /= det; - B1 = *pb1 + sigmaU; - B2 = *pb2 + sigmaV; - pdu[o] += omega * (A11 * B1 + A12 * B2 - pdu[o]); - pdv[o] += omega * (A12 * B1 + A22 * B2 - pdv[o]); - ++pa11; ++pa12; ++pa22; ++pb1; ++pb2; - ++o; - //middle columns - for ( i = 1; i < cols - 1; ++i) - { - dPsi = psmoothX[o - 1] + psmoothX[o] + psmoothY[o - s]; - sigmaU = psmoothX[o - 1] * pdu[o - 1] - + psmoothX[o] * pdu[o + 1] - + psmoothY[o - s] * pdu[o - s]; - sigmaV = psmoothX[o - 1] * pdv[o - 1] - + psmoothX[o] * pdv[o + 1] - + psmoothY[o - s] * pdv[o - s]; - A11 = *pa22 + dPsi; - A12 = -*pa12; - A22 = *pa11 + dPsi; - det = A11 * A22 - A12 * A12; - A11 /= det; - A12 /= det; - A22 /= det; - B1 = *pb1 + sigmaU; - B2 = *pb2 + sigmaV; - pdu[o] += omega * (A11 * B1 + A12 * B2 - pdu[o]); - pdv[o] += omega * (A12 * B1 + A22 * B2 - pdv[o]); - ++pa11; ++pa12; ++pa22; ++pb1; ++pb2; - ++o; - } - //last column - dPsi = psmoothX[o - 1] + psmoothY[o - s]; - sigmaU = psmoothX[o - 1] * pdu[o - 1] - + psmoothY[o - s] * pdu[o - s]; - sigmaV = psmoothX[o - 1] * pdv[o - 1] - + psmoothY[o - s] * pdv[o - s]; - A11 = *pa22 + dPsi; - A12 = -*pa12; - A22 = *pa11 + dPsi; - det = A11 * A22 - A12 * A12; - A11 /= det; - A12 /= det; - A22 /= det; - B1 = *pb1 + sigmaU; - B2 = *pb2 + sigmaV; - pdu[o] += omega * (A11 * B1 + A12 * B2 - pdu[o]); - pdv[o] += omega * (A12 * B1 + A22 * B2 - pdv[o]); - ++pa11; ++pa12; ++pa22; ++pb1; ++pb2; - } - merge(dWChannels, dW); - -} -void OpticalFlowDeepFlow::collectGarbage() -{ - -} -// -//CV_INIT_ALGORITHM(OpticalFlowDeepFlow, "DenseOpticalFlow.DeepFlow", -// obj.info()->addParam(obj, "sigma", obj.sigma, false, 0, 0, "Gaussian blur parameter"); -// obj.info()->addParam(obj, "alpha", obj.alpha, false, 0, 0, "Smoothness assumption weight"); -// obj.info()->addParam(obj, "delta", obj.delta, false, 0, 0, "Color constancy weight"); -// obj.info()->addParam(obj, "gamma", obj.gamma, false, 0, 0, "Gradient constancy weight"); -// obj.info()->addParam(obj, "omega", obj.omega, false, 0, 0, "Relaxation factor in SOR"); -// obj.info()->addParam(obj, "minSize", obj.minSize, false, 0, 0, "Min. image size in the pyramid"); -// obj.info()->addParam(obj, "fixedPointIterations", obj.fixedPointIterations, false, 0, 0, "Fixed point iterations"); -// obj.info()->addParam(obj, "sorIterations", obj.sorIterations, false, 0, 0, "SOR iterations"); -// obj.info()->addParam(obj, "downscaleFactor", obj.downscaleFactor, false, 0, 0,"Downscale factor")) +void OpticalFlowDeepFlow::collectGarbage() {} - -Ptr createOptFlow_DeepFlow() -{ - return makePtr(); -} +Ptr createOptFlow_DeepFlow() { return makePtr(); } }//optflow }//cv diff --git a/modules/optflow/src/dis_flow.cpp b/modules/optflow/src/dis_flow.cpp index fed97439f..15b3133e9 100644 --- a/modules/optflow/src/dis_flow.cpp +++ b/modules/optflow/src/dis_flow.cpp @@ -65,6 +65,9 @@ class DISOpticalFlowImpl : public DISOpticalFlow int patch_stride; int grad_descent_iter; int variational_refinement_iter; + float variational_refinement_alpha; + float variational_refinement_gamma; + float variational_refinement_delta; bool use_mean_normalization; bool use_spatial_propagation; @@ -84,6 +87,13 @@ class DISOpticalFlowImpl : public DISOpticalFlow void setGradientDescentIterations(int val) { grad_descent_iter = val; } int getVariationalRefinementIterations() const { return variational_refinement_iter; } void setVariationalRefinementIterations(int val) { variational_refinement_iter = val; } + float getVariationalRefinementAlpha() const { return variational_refinement_alpha; } + void setVariationalRefinementAlpha(float val) { variational_refinement_alpha = val; } + float getVariationalRefinementDelta() const { return variational_refinement_delta; } + void setVariationalRefinementDelta(float val) { variational_refinement_delta = val; } + float getVariationalRefinementGamma() const { return variational_refinement_gamma; } + void setVariationalRefinementGamma(float val) { variational_refinement_gamma = val; } + bool getUseMeanNormalization() const { return use_mean_normalization; } void setUseMeanNormalization(bool val) { use_mean_normalization = val; } bool getUseSpatialPropagation() const { return use_spatial_propagation; } @@ -161,6 +171,10 @@ DISOpticalFlowImpl::DISOpticalFlowImpl() patch_stride = 4; grad_descent_iter = 16; variational_refinement_iter = 5; + variational_refinement_alpha = 20.f; + variational_refinement_gamma = 10.f; + variational_refinement_delta = 5.f; + border_size = 16; use_mean_normalization = true; use_spatial_propagation = true; @@ -234,9 +248,9 @@ void DISOpticalFlowImpl::prepareBuffers(Mat &I0, Mat &I1) spatialGradient(I0s[i], I0xs[i], I0ys[i]); Ux[i].create(cur_rows, cur_cols); Uy[i].create(cur_rows, cur_cols); - variational_refinement_processors[i]->setAlpha(20.0f); - variational_refinement_processors[i]->setDelta(5.0f); - variational_refinement_processors[i]->setGamma(10.0f); + variational_refinement_processors[i]->setAlpha(variational_refinement_alpha); + variational_refinement_processors[i]->setDelta(variational_refinement_delta); + variational_refinement_processors[i]->setGamma(variational_refinement_gamma); variational_refinement_processors[i]->setSorIterations(5); variational_refinement_processors[i]->setFixedPointIterations(variational_refinement_iter); } diff --git a/modules/optflow/src/variational_refinement.cpp b/modules/optflow/src/variational_refinement.cpp index e7eccf318..6353c09a7 100644 --- a/modules/optflow/src/variational_refinement.cpp +++ b/modules/optflow/src/variational_refinement.cpp @@ -1074,9 +1074,10 @@ void VariationalRefinementImpl::RedBlackSOR_ParBody::operator()(const Range &ran void VariationalRefinementImpl::calc(InputArray I0, InputArray I1, InputOutputArray flow) { - CV_Assert(!I0.empty() && I0.depth() == CV_8U && I0.channels() == 1); - CV_Assert(!I1.empty() && I1.depth() == CV_8U && I1.channels() == 1); + CV_Assert(!I0.empty() && I0.channels() == 1); + CV_Assert(!I1.empty() && I1.channels() == 1); CV_Assert(I0.sameSize(I1)); + CV_Assert((I0.depth() == CV_8U && I1.depth() == CV_8U) || (I0.depth() == CV_32F && I1.depth() == CV_32F)); CV_Assert(!flow.empty() && flow.depth() == CV_32F && flow.channels() == 2); CV_Assert(I0.sameSize(flow)); @@ -1089,9 +1090,10 @@ void VariationalRefinementImpl::calc(InputArray I0, InputArray I1, InputOutputAr void VariationalRefinementImpl::calcUV(InputArray I0, InputArray I1, InputOutputArray flow_u, InputOutputArray flow_v) { - CV_Assert(!I0.empty() && I0.depth() == CV_8U && I0.channels() == 1); - CV_Assert(!I1.empty() && I1.depth() == CV_8U && I1.channels() == 1); + CV_Assert(!I0.empty() && I0.channels() == 1); + CV_Assert(!I1.empty() && I1.channels() == 1); CV_Assert(I0.sameSize(I1)); + CV_Assert((I0.depth() == CV_8U && I1.depth() == CV_8U) || (I0.depth() == CV_32F && I1.depth() == CV_32F)); CV_Assert(!flow_u.empty() && flow_u.depth() == CV_32F && flow_u.channels() == 1); CV_Assert(!flow_v.empty() && flow_v.depth() == CV_32F && flow_v.channels() == 1); CV_Assert(I0.sameSize(flow_u)); diff --git a/modules/text/include/opencv2/text.hpp b/modules/text/include/opencv2/text.hpp index 591424cb4..945194a16 100644 --- a/modules/text/include/opencv2/text.hpp +++ b/modules/text/include/opencv2/text.hpp @@ -92,7 +92,7 @@ grouping horizontally aligned text, and the method proposed by Lluis Gomez and D in [Gomez13][Gomez14] for grouping arbitrary oriented text (see erGrouping). To see the text detector at work, have a look at the textdetection demo: - + @defgroup text_recognize Scene Text Recognition @} diff --git a/modules/text/include/opencv2/text/erfilter.hpp b/modules/text/include/opencv2/text/erfilter.hpp index d17ac8879..9303e128f 100644 --- a/modules/text/include/opencv2/text/erfilter.hpp +++ b/modules/text/include/opencv2/text/erfilter.hpp @@ -345,7 +345,7 @@ single vector\, the function separates them in two different vectors (th ERStats where extracted from two different channels). An example of MSERsToERStats in use can be found in the text detection webcam_demo: - + */ CV_EXPORTS void MSERsToERStats(InputArray image, std::vector > &contours, std::vector > ®ions); diff --git a/modules/text/include/opencv2/text/ocr.hpp b/modules/text/include/opencv2/text/ocr.hpp index 651934b0c..1261046cd 100644 --- a/modules/text/include/opencv2/text/ocr.hpp +++ b/modules/text/include/opencv2/text/ocr.hpp @@ -81,10 +81,10 @@ Notice that it is compiled only when tesseract-ocr is correctly installed. @note - (C++) An example of OCRTesseract recognition combined with scene text detection can be found at the end_to_end_recognition demo: - + - (C++) Another example of OCRTesseract recognition combined with scene text detection can be found at the webcam_demo: - + */ class CV_EXPORTS_W OCRTesseract : public BaseOCR { @@ -152,7 +152,7 @@ enum decoder_mode @note - (C++) An example on using OCRHMMDecoder recognition combined with scene text detection can be found at the webcam_demo sample: - + */ class CV_EXPORTS_W OCRHMMDecoder : public BaseOCR { @@ -165,7 +165,7 @@ public: The default character classifier and feature extractor can be loaded using the utility funtion loadOCRHMMClassifierNM and KNN model provided in - . + . */ class CV_EXPORTS_W ClassifierCallback { @@ -321,7 +321,7 @@ CV_EXPORTS_W Ptr loadOCRHMMClassifierCNN(cons * The function calculate frequency statistics of character pairs from the given lexicon and fills the output transition_probabilities_table with them. The transition_probabilities_table can be used as input in the OCRHMMDecoder::create() and OCRBeamSearchDecoder::create() methods. * @note * - (C++) An alternative would be to load the default generic language transition table provided in the text module samples folder (created from ispell 42869 english words list) : - * + * **/ CV_EXPORTS void createOCRHMMTransitionsTable(std::string& vocabulary, std::vector& lexicon, OutputArray transition_probabilities_table); @@ -335,7 +335,7 @@ CV_EXPORTS_W Mat createOCRHMMTransitionsTable(const String& vocabulary, std::vec @note - (C++) An example on using OCRBeamSearchDecoder recognition combined with scene text detection can be found at the demo sample: - + */ class CV_EXPORTS_W OCRBeamSearchDecoder : public BaseOCR { @@ -348,7 +348,7 @@ public: The default character classifier and feature extractor can be loaded using the utility funtion loadOCRBeamSearchClassifierCNN with all its parameters provided in - . + . */ class CV_EXPORTS_W ClassifierCallback { diff --git a/modules/text/src/erfilter.cpp b/modules/text/src/erfilter.cpp index eaee701bf..be17b4b3d 100644 --- a/modules/text/src/erfilter.cpp +++ b/modules/text/src/erfilter.cpp @@ -2820,12 +2820,12 @@ bool guo_hall_thinning(const Mat1b & img, Mat& skeleton) p8 = (skeleton.data[row * skeleton.cols + col-1]) > 0; p9 = (skeleton.data[(row-1) * skeleton.cols + col-1]) > 0; - int C = (!p2 & (p3 | p4)) + (!p4 & (p5 | p6)) + - (!p6 & (p7 | p8)) + (!p8 & (p9 | p2)); - int N1 = (p9 | p2) + (p3 | p4) + (p5 | p6) + (p7 | p8); - int N2 = (p2 | p3) + (p4 | p5) + (p6 | p7) + (p8 | p9); + int C = (!p2 && (p3 || p4)) + (!p4 && (p5 || p6)) + + (!p6 && (p7 || p8)) + (!p8 && (p9 || p2)); + int N1 = (p9 || p2) + (p3 || p4) + (p5 || p6) + (p7 || p8); + int N2 = (p2 || p3) + (p4 || p5) + (p6 || p7) + (p8 || p9); int N = N1 < N2 ? N1 : N2; - int m = iter == 0 ? ((p6 | p7 | !p9) & p8) : ((p2 | p3 | !p5) & p4); + int m = iter == 0 ? ((p6 || p7 || !p9) && p8) : ((p2 || p3 || !p5) && p4); if ((C == 1) && (N >= 2) && (N <= 3) && (m == 0)) { diff --git a/modules/text/src/ocr_hmm_decoder.cpp b/modules/text/src/ocr_hmm_decoder.cpp index 1076475f1..5b7a5aa31 100644 --- a/modules/text/src/ocr_hmm_decoder.cpp +++ b/modules/text/src/ocr_hmm_decoder.cpp @@ -1206,7 +1206,7 @@ the output transition_probabilities_table with them. The transition_probabilities_table can be used as input in the OCRHMMDecoder::create() and OCRBeamSearchDecoder::create() methods. @note - (C++) An alternative would be to load the default generic language transition table provided in the text module samples folder (created from ispell 42869 english words list) : - + */ void createOCRHMMTransitionsTable(string& vocabulary, vector& lexicon, OutputArray _transitions) { diff --git a/modules/tracking/tutorials/tutorial_introduction_to_tracker.markdown b/modules/tracking/tutorials/tutorial_introduction_to_tracker.markdown index 500df0c1c..9e2b6eb89 100644 --- a/modules/tracking/tutorials/tutorial_introduction_to_tracker.markdown +++ b/modules/tracking/tutorials/tutorial_introduction_to_tracker.markdown @@ -28,8 +28,8 @@ Explanation as shown in help. In the help, it means that the image files are numbered with 4 digits (e.g. the file naming will be 0001.jpg, 0002.jpg, and so on). - You can find video samples in Itseez/opencv_extra/testdata/cv/tracking - + You can find video samples in opencv_extra/testdata/cv/tracking + -# **Declares the required variables** diff --git a/modules/ximgproc/README.md b/modules/ximgproc/README.md index b566aa354..1afdd610b 100644 --- a/modules/ximgproc/README.md +++ b/modules/ximgproc/README.md @@ -9,3 +9,4 @@ Extended Image Processing 6. Superpixels 7. Graph segmentation 8. Selective search from segmentation +10. Paillou Filter diff --git a/modules/ximgproc/doc/ximgproc.bib b/modules/ximgproc/doc/ximgproc.bib index 3de1724c9..0fbbb374b 100644 --- a/modules/ximgproc/doc/ximgproc.bib +++ b/modules/ximgproc/doc/ximgproc.bib @@ -166,3 +166,13 @@ year={2014}, organization={IEEE} } + +@article{paillou1997detecting, + title={Detecting step edges in noisy SAR images: a new linear operator}, + author={Paillou, Philippe}, + journal={IEEE transactions on geoscience and remote sensing}, + volume={35}, + number={1}, + pages={191--196}, + year={1997} +} diff --git a/modules/ximgproc/include/opencv2/ximgproc.hpp b/modules/ximgproc/include/opencv2/ximgproc.hpp index 84015b910..b803ce3ef 100644 --- a/modules/ximgproc/include/opencv2/ximgproc.hpp +++ b/modules/ximgproc/include/opencv2/ximgproc.hpp @@ -48,6 +48,8 @@ #include "ximgproc/weighted_median_filter.hpp" #include "ximgproc/slic.hpp" #include "ximgproc/lsc.hpp" +#include "ximgproc/paillou_filter.hpp" + /** @defgroup ximgproc Extended Image Processing @{ diff --git a/modules/ximgproc/include/opencv2/ximgproc/paillou_filter.hpp b/modules/ximgproc/include/opencv2/ximgproc/paillou_filter.hpp new file mode 100644 index 000000000..e58b609d5 --- /dev/null +++ b/modules/ximgproc/include/opencv2/ximgproc/paillou_filter.hpp @@ -0,0 +1,67 @@ +/* + * 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 + * (3 - clause BSD License) + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met : + * + * *Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions 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. + * + * * Neither the names of the copyright holders nor the names of the contributors + * may 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 copyright holders 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. + */ + +#ifndef __OPENCV_PAILLOUFILTER_HPP__ +#define __OPENCV_PAILLOUFILTER_HPP__ +#ifdef __cplusplus + +#include + +namespace cv { +namespace ximgproc { + +//! @addtogroup ximgproc_filters +//! @{ + +/** +* @brief Applies Paillou filter to an image. +* +* For more details about this implementation, please see @cite paillou1997detecting +* +* @param op Source 8-bit or 16bit image, 1-channel or 3-channel image. +* @param _dst result CV_32F image with same numeber of channel than op. +* @param omega double see paper +* @param alpha double see paper +* +* @sa GradientPaillouX, GradientPaillouY +*/ +CV_EXPORTS void GradientPaillouY(InputArray op, OutputArray _dst, double alpha, double omega); +CV_EXPORTS void GradientPaillouX(InputArray op, OutputArray _dst, double alpha, double omega); + +} +} +#endif +#endif diff --git a/modules/ximgproc/samples/paillou_demo.cpp b/modules/ximgproc/samples/paillou_demo.cpp new file mode 100644 index 000000000..7ac98b682 --- /dev/null +++ b/modules/ximgproc/samples/paillou_demo.cpp @@ -0,0 +1,107 @@ +/* + * 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 + * (3 - clause BSD License) + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met : + * + * *Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions 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. + * + * * Neither the names of the copyright holders nor the names of the contributors + * may 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 copyright holders 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. + */ + +#include +#include +#include +#include +#include "opencv2/ximgproc/paillou_filter.hpp" + +using namespace cv; +using namespace cv::ximgproc; + +#include +using namespace std; + +int aa = 100, ww = 10; +Mat dx, dy; +UMat img; +const char* window_name = "Gradient Modulus"; + +static void DisplayImage(Mat x,string s) +{ + vector sx; + split(x, sx); + vector minVal(3), maxVal(3); + for (int i = 0; i < static_cast(sx.size()); i++) + { + minMaxLoc(sx[i], &minVal[i], &maxVal[i]); + } + maxVal[0] = *max_element(maxVal.begin(), maxVal.end()); + minVal[0] = *min_element(minVal.begin(), minVal.end()); + Mat uc; + x.convertTo(uc, CV_8U,255/(maxVal[0]-minVal[0]),-255*minVal[0]/(maxVal[0]-minVal[0])); + imshow(s, uc); +} + + +/** + * @function paillouFilter + * @brief Trackbar callback + */ +static void PaillouFilter(int, void*) +{ + Mat dst; + double a=aa/100.0,w=ww/100.0; + Mat rx,ry; + GradientPaillouX(img,rx,a,w); + GradientPaillouY(img,ry,a,w); + DisplayImage(rx, "Gx"); + DisplayImage(ry, "Gy"); + add(rx.mul(rx),ry.mul(ry),dst); + sqrt(dst,dst); + DisplayImage(dst, window_name ); +} + + +int main(int argc, char* argv[]) +{ + if (argc==2) + imread(argv[1]).copyTo(img); + if (img.empty()) + { + cout << "File not found or empty image\n"; + } + imshow("Original",img); + namedWindow( window_name, WINDOW_AUTOSIZE ); + + /// Create a Trackbar for user to enter threshold + createTrackbar( "a:",window_name, &aa, 400, PaillouFilter ); + createTrackbar( "w:", window_name, &ww, 400, PaillouFilter ); + PaillouFilter(0,NULL); + waitKey(); + return 0; +} \ No newline at end of file diff --git a/modules/ximgproc/samples/structured_edge_detection.cpp b/modules/ximgproc/samples/structured_edge_detection.cpp index 4c20d01a5..a11e9f102 100644 --- a/modules/ximgproc/samples/structured_edge_detection.cpp +++ b/modules/ximgproc/samples/structured_edge_detection.cpp @@ -1,7 +1,7 @@ /************************************************************************************** The structered edge demo requires you to provide a model. This model can be found at the opencv_extra repository on Github on the following link: -https://github.com/Itseez/opencv_extra/blob/master/testdata/cv/ximgproc/model.yml.gz +https://github.com/opencv/opencv_extra/blob/master/testdata/cv/ximgproc/model.yml.gz ***************************************************************************************/ #include diff --git a/modules/ximgproc/src/paillou_filter.cpp b/modules/ximgproc/src/paillou_filter.cpp new file mode 100644 index 000000000..a82158051 --- /dev/null +++ b/modules/ximgproc/src/paillou_filter.cpp @@ -0,0 +1,486 @@ +#include "precomp.hpp" +#include "opencv2/highgui.hpp" +#include +#include +#include + +namespace cv { +namespace ximgproc { + +/* +If you use this code please cite this @cite paillou1997detecting +Detecting step edges in noisy SAR images: a new linear operator IEEE Transactions on Geoscience and Remote Sensing (Volume:35 , Issue: 1 ) 1997 +*/ + + +class ParallelGradientPaillouYCols: public ParallelLoopBody +{ +private: + Mat &img; + Mat &dst; + double a; + double w; + bool verbose; +public: + ParallelGradientPaillouYCols(Mat& imgSrc, Mat &d,double aa,double ww): + img(imgSrc), + dst(d), + a(aa), + w(ww), + verbose(false) + {} + void Verbose(bool b){verbose=b;} + virtual void operator()(const Range& range) const + { + CV_Assert(img.depth()==CV_8UC1 || img.depth()==CV_16SC1 || img.depth()==CV_16UC1); + CV_Assert(dst.depth()==CV_32FC1); + if (verbose) + std::cout << getThreadNum()<<"# :Start from row " << range.start << " to " << range.end-1<<" ("<img.cols)?img.rows:img.cols; + Mat matYp(1,tailleSequence,CV_64FC1), matYm(1,tailleSequence,CV_64FC1); + double *yp=matYp.ptr(0), *ym=matYm.ptr(0); + int rows=img.rows,cols=img.cols; + + // Equation 12 p193 + double b1=-2*exp(-a)*cosh(w); + double a1=2*exp(-a)*cosh(w)-exp(-2*a)-1; + double b2=exp(-2*a); + + switch(img.depth()){ + case CV_8U : + for (int j=range.start;j(0)+j; + double border=*c1; + yp[0] = *c1 ; + c1+=cols; + yp[1] = *c1 - b1*yp[0]-b2*border; + c1+=cols; + for (int i=2;i=0;i--,c1-=cols) + ym[i]=*c1-b1*ym[i+1]-b2*ym[i+2]; + // Equation 25 p193 + for (int i=0;i(0) + j; + f2 = dst.ptr(0) + j; + double border = *c1; + yp[0] = *c1; + c1 += cols; + yp[1] = *c1 - b1*yp[0] - b2*border; + c1 += cols; + for (int i = 2; i(rows - 1) + j; + border = *c1; + ym[rows - 1] = *c1; + c1 -= cols; + ym[rows - 2] = *c1 - b1*ym[rows - 1]; + c1 -= cols; + for (int i = rows - 3; i >= 0; i--, c1 -= cols) + ym[i] = *c1 - b1*ym[i + 1] - b2*ym[i + 2]; + // Equation 25 p193 + for (int i = 0; i(0) + j; + f2 = dst.ptr(0) + j; + double border = *c1; + yp[0] = *c1; + c1 += cols; + yp[1] = *c1 - b1*yp[0] - b2*border; + c1 += cols; + for (int i = 2; i(rows - 1) + j; + border = *c1; + ym[rows - 1] = *c1; + c1 -= cols; + ym[rows - 2] = *c1 - b1*ym[rows - 1]; + c1 -= cols; + for (int i = rows - 3; i >= 0; i--, c1 -= cols) + ym[i] = *c1 - b1*ym[i + 1] - b2*ym[i + 2]; + // Equation 25 p193 + for (int i = 0; iimg.cols)?img.rows:img.cols; + Mat matIym(1,tailleSequence,CV_64FC1), matIyp(1,tailleSequence,CV_64FC1); + double *iym=matIym.ptr(0), *iyp=matIyp.ptr(0); + int cols=img.cols; + + // Equation 13 p193 + double d=(1-2*exp(-a)*cosh(w)+exp(-2*a))/(2*a*exp(-a)*sinh(w)+w*(1-exp(-2*a))); + double c1=a*d; + double c2=w*d; + // Equation 12 p193 + double b1=-2*exp(-a)*cosh(w); + double b2=exp(-2*a); + // Equation 14 p193 + double a0p=c2; + double a1p=(c1*sinh(w)-c2*cosh(w))*exp(-a); + double a1m=a1p-c2*b1; + double a2m=-c2*b2; + + for (int i=range.start;i(i); + int j=0; + iyp[0] = a0p*iy0[0] ; + iyp[1] = a0p*iy0[1] + a1p*iy0[0] - b1*iyp[0]; + iy0 += 2; + for (j=2;j(i)+cols-1; + iym[cols-1] = 0; + iy0--; + iym[cols-2] = a1m*iy0[1] - b1*iym[cols-1]; + iy0--; + for (j=cols-3;j>=0;j--,iy0--) + iym[j] = a1m*iy0[1] + a2m*iy0[2] - b1*iym[j+1] - b2*iym[j+2]; + iy = dst.ptr(i); + for (j=0;jimg.cols) ? img.rows : img.cols; + Mat matIym(1,tailleSequence,CV_64FC1), matIyp(1,tailleSequence,CV_64FC1); + double *iym=matIym.ptr(0), *iyp=matIyp.ptr(0); + int rows = img.rows,cols=img.cols; + + // Equation 13 p193 + double d = (1 - 2 * exp(-a)*cosh(w) + exp(-2 * a)) / (2 * a*exp(-a)*sinh(w) + w*(1 - exp(-2 * a))); + double c1 = a*d; + double c2 = w*d; + // Equation 12 p193 + double b1 = -2 * exp(-a)*cosh(w); + double b2 = exp(-2 * a); + // Equation 14 p193 + double a0p = c2; + double a1p = (c1*sinh(w) - c2*cosh(w))*exp(-a); + double a1m = a1p - c2*b1; + double a2m = -c2*b2; + + for (int j = range.start; j(0)+j; + iyp[0] = a0p*iy0[0]; + iy0 +=cols; + iyp[1] = a0p*iy0[0] + a1p*iy0[-cols] - b1*iyp[0]; + iy0 +=cols; + for (int i = 2; i(rows-1) + j; + iym[rows - 1] = 0; + iy0 -=cols; + iym[rows - 2] = a1m*iy0[cols] - b1*iym[rows-1]; + iy0-=cols; + for (int i = rows - 3; i >= 0; i--, iy0-=cols) + iym[i] = a1m*iy0[cols] + a2m*iy0[2*cols] - b1*iym[i + 1] - b2*iym[i + 2]; + iy = dst.ptr(0)+j; + for (int i = 0; iimg.cols) ? img.rows : img.cols; + Mat matYp(1,tailleSequence,CV_64FC1), matYm(1,tailleSequence,CV_64FC1); + double *yp=matYp.ptr(0), *ym=matYm.ptr(0); + int cols = img.cols; + + // Equation 12 p193 + double b1 = -2 * exp(-a)*cosh(w); + double a1 = 2 * exp(-a)*cosh(w) - exp(-2 * a) - 1; + double b2 = exp(-2 * a); + + switch(img.depth()){ + case CV_8U : + for (int i = range.start; i= 0; j--, c1--) + ym[j] = *c1 - b1*ym[j + 1] - b2*ym[j + 2]; + // Equation 25 p193 + f2 = im1.ptr(i); + for (int j = 0; j(i); + double border = *c1; + yp[0] = *c1; + c1++; + yp[1] = *c1 - b1*yp[0] - b2*border; + c1++; + for (int j = 2; j(i)+cols-1; + border = *c1; + ym[cols - 1] = *c1; + c1--; + ym[cols - 2] = *c1 - b1*ym[cols - 1]; + c1--; + for (int j = cols - 3; j >= 0; j--, c1--) + ym[j] = *c1 - b1*ym[j + 1] - b2*ym[j + 2]; + // Equation 25 p193 + f2 = im1.ptr(i); + for (int j = 0; j(i); + f2 = im1.ptr(i); + double border = *c1; + yp[0] = *c1; + c1++; + yp[1] = *c1 - b1*yp[0] - b2*border; + c1++; + for (int j = 2; j(i) + cols - 1; + border = *c1; + ym[cols - 1] = *c1; + c1--; + ym[cols - 2] = *c1 - b1*ym[cols - 1]; + c1--; + for (int j = cols - 3; j >= 0; j--, c1--) + ym[j] = *c1 - b1*ym[j + 1] - b2*ym[j + 2]; + // Equation 25 p193 + for (int j = 0; j(i); + f2 = im1.ptr(i); + double border = *c1; + yp[0] = *c1; + c1++; + yp[1] = *c1 - b1*yp[0] - b2*border; + c1++; + for (int j = 2; j(i) + cols - 1; + border = *c1; + ym[cols - 1] = *c1; + c1--; + ym[cols - 2] = *c1 - b1*ym[cols - 1]; + c1--; + for (int j = cols - 3; j >= 0; j--, c1--) + ym[j] = *c1 - b1*ym[j + 1] - b2*ym[j + 2]; + // Equation 25 p193 + for (int j = 0; j planSrc; + split(opSrc,planSrc); + std::vector planTmp; + split(tmp,planTmp); + std::vector planDst; + split(_dst,planDst); + for (int i = 0; i < static_cast(planSrc.size()); i++) + { + if (planSrc[i].isContinuous() && planTmp[i].isContinuous() && planDst[i].isContinuous()) + { + ParallelGradientPaillouYCols x(planSrc[i],planTmp[i],alpha,omega); + parallel_for_(Range(0,opSrc.cols), x,getNumThreads()); + ParallelGradientPaillouYRows xr(planTmp[i],planDst[i],alpha,omega); + parallel_for_(Range(0,opSrc.rows), xr,getNumThreads()); + + } + else + std::cout << "PB"; + } + merge(planDst,_dst); +} + +void GradientPaillouX(InputArray _op, OutputArray _dst, double alpha, double omega) +{ + Mat tmp(_op.size(),CV_32FC(_op.channels())); + _dst.create( _op.size(),CV_32FC(tmp.channels()) ); + Mat opSrc = _op.getMat(); + std::vector planSrc; + split(opSrc,planSrc); + std::vector planTmp; + split(tmp,planTmp); + std::vector planDst; + split(_dst,planDst); + for (int i = 0; i < static_cast(planSrc.size()); i++) + { + if (planSrc[i].isContinuous() && planTmp[i].isContinuous() && planDst[i].isContinuous()) + { + ParallelGradientPaillouXRows x(planSrc[i],planTmp[i],alpha,omega); + parallel_for_(Range(0,opSrc.rows), x,getNumThreads()); + ParallelGradientPaillouXCols xr(planTmp[i],planDst[i],alpha,omega); + parallel_for_(Range(0,opSrc.cols), xr,getNumThreads()); + } + else + std::cout << "PB"; + } + merge(planDst,_dst); +} +} +} diff --git a/modules/ximgproc/tutorials/disparity_filtering.markdown b/modules/ximgproc/tutorials/disparity_filtering.markdown index 4ca559f83..0248c6db4 100644 --- a/modules/ximgproc/tutorials/disparity_filtering.markdown +++ b/modules/ximgproc/tutorials/disparity_filtering.markdown @@ -27,7 +27,7 @@ Source Stereoscopic Image Source Code ----------- -We will be using snippets from the example application, that can be downloaded [here ](https://github.com/Itseez/opencv_contrib/blob/master/modules/ximgproc/samples/disparity_filtering.cpp). +We will be using snippets from the example application, that can be downloaded [here ](https://github.com/opencv/opencv_contrib/blob/master/modules/ximgproc/samples/disparity_filtering.cpp). Explanation ----------- diff --git a/modules/xobjdetect/tools/waldboost_detector/CMakeLists.txt b/modules/xobjdetect/tools/waldboost_detector/CMakeLists.txt index 40424180e..8ed7eb6db 100644 --- a/modules/xobjdetect/tools/waldboost_detector/CMakeLists.txt +++ b/modules/xobjdetect/tools/waldboost_detector/CMakeLists.txt @@ -19,7 +19,7 @@ file(GLOB ${the_target}_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) add_executable(${the_target} ${${the_target}_SOURCES}) -target_link_libraries(${the_target} ${OPENCV_${the_target}_DEPS}) +ocv_target_link_libraries(${the_target} ${OPENCV_${the_target}_DEPS}) set_target_properties(${the_target} PROPERTIES DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"