コード例 #1
0
void spatialGradient( InputArray _src, OutputArray _dx, OutputArray _dy,
                      int ksize, int borderType )
{
    CV_INSTRUMENT_REGION()

    // Prepare InputArray src
    Mat src = _src.getMat();
    CV_Assert( !src.empty() );
    CV_Assert( src.type() == CV_8UC1 );
    CV_Assert( borderType == BORDER_DEFAULT || borderType == BORDER_REPLICATE );

    // Prepare OutputArrays dx, dy
    _dx.create( src.size(), CV_16SC1 );
    _dy.create( src.size(), CV_16SC1 );
    Mat dx = _dx.getMat(),
        dy = _dy.getMat();

    // TODO: Allow for other kernel sizes
    CV_Assert(ksize == 3);

    // Get dimensions
    const int H = src.rows,
              W = src.cols;

    // Row, column indices
    int i = 0,
        j = 0;

    // Handle border types
    int i_top    = 0,     // Case for H == 1 && W == 1 && BORDER_REPLICATE
        i_bottom = H - 1,
        j_offl   = 0,     // j offset from 0th   pixel to reach -1st pixel
        j_offr   = 0;     // j offset from W-1th pixel to reach Wth  pixel

    if ( borderType == BORDER_DEFAULT ) // Equiv. to BORDER_REFLECT_101
    {
        if ( H > 1 )
        {
            i_top    = 1;
            i_bottom = H - 2;
        }
        if ( W > 1 )
        {
            j_offl = 1;
            j_offr = -1;
        }
    }

    // Pointer to row vectors
    uchar *p_src, *c_src, *n_src; // previous, current, next row
    short *c_dx,  *c_dy;

    int i_start = 0;
    int j_start = 0;
#if CV_SIMD128 && CV_SSE2
    if(hasSIMD128())
    {
        uchar *m_src;
        short *n_dx, *n_dy;

        // Characters in variable names have the following meanings:
        // u: unsigned char
        // s: signed int
        //
        // [row][column]
        // m: offset -1
        // n: offset  0
        // p: offset  1
        // Example: umn is offset -1 in row and offset 0 in column
        for ( i = 0; i < H - 1; i += 2 )
        {
            if   ( i == 0 ) p_src = src.ptr<uchar>(i_top);
            else            p_src = src.ptr<uchar>(i-1);

            c_src = src.ptr<uchar>(i);
            n_src = src.ptr<uchar>(i+1);

            if ( i == H - 2 ) m_src = src.ptr<uchar>(i_bottom);
            else              m_src = src.ptr<uchar>(i+2);

            c_dx = dx.ptr<short>(i);
            c_dy = dy.ptr<short>(i);
            n_dx = dx.ptr<short>(i+1);
            n_dy = dy.ptr<short>(i+1);

            v_uint8x16 v_select_m = v_uint8x16(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                               0, 0, 0, 0xFF);

            // Process rest of columns 16-column chunks at a time
            for ( j = 1; j < W - 16; j += 16 )
            {
                // Load top row for 3x3 Sobel filter
                v_uint8x16 v_um = v_load(&p_src[j-1]);
                v_uint8x16 v_up = v_load(&p_src[j+1]);
                // TODO: Replace _mm_slli_si128 with hal method
                v_uint8x16 v_un = v_select(v_select_m, v_uint8x16(_mm_slli_si128(v_up.val, 1)),
                                                       v_uint8x16(_mm_srli_si128(v_um.val, 1)));
                v_uint16x8 v_um1, v_um2, v_un1, v_un2, v_up1, v_up2;
                v_expand(v_um, v_um1, v_um2);
                v_expand(v_un, v_un1, v_un2);
                v_expand(v_up, v_up1, v_up2);
                v_int16x8 v_s1m1 = v_reinterpret_as_s16(v_um1);
                v_int16x8 v_s1m2 = v_reinterpret_as_s16(v_um2);
                v_int16x8 v_s1n1 = v_reinterpret_as_s16(v_un1);
                v_int16x8 v_s1n2 = v_reinterpret_as_s16(v_un2);
                v_int16x8 v_s1p1 = v_reinterpret_as_s16(v_up1);
                v_int16x8 v_s1p2 = v_reinterpret_as_s16(v_up2);

                // Load second row for 3x3 Sobel filter
                v_um = v_load(&c_src[j-1]);
                v_up = v_load(&c_src[j+1]);
                // TODO: Replace _mm_slli_si128 with hal method
                v_un = v_select(v_select_m, v_uint8x16(_mm_slli_si128(v_up.val, 1)),
                                            v_uint8x16(_mm_srli_si128(v_um.val, 1)));
                v_expand(v_um, v_um1, v_um2);
                v_expand(v_un, v_un1, v_un2);
                v_expand(v_up, v_up1, v_up2);
                v_int16x8 v_s2m1 = v_reinterpret_as_s16(v_um1);
                v_int16x8 v_s2m2 = v_reinterpret_as_s16(v_um2);
                v_int16x8 v_s2n1 = v_reinterpret_as_s16(v_un1);
                v_int16x8 v_s2n2 = v_reinterpret_as_s16(v_un2);
                v_int16x8 v_s2p1 = v_reinterpret_as_s16(v_up1);
                v_int16x8 v_s2p2 = v_reinterpret_as_s16(v_up2);

                // Load third row for 3x3 Sobel filter
                v_um = v_load(&n_src[j-1]);
                v_up = v_load(&n_src[j+1]);
                // TODO: Replace _mm_slli_si128 with hal method
                v_un = v_select(v_select_m, v_uint8x16(_mm_slli_si128(v_up.val, 1)),
                                            v_uint8x16(_mm_srli_si128(v_um.val, 1)));
                v_expand(v_um, v_um1, v_um2);
                v_expand(v_un, v_un1, v_un2);
                v_expand(v_up, v_up1, v_up2);
                v_int16x8 v_s3m1 = v_reinterpret_as_s16(v_um1);
                v_int16x8 v_s3m2 = v_reinterpret_as_s16(v_um2);
                v_int16x8 v_s3n1 = v_reinterpret_as_s16(v_un1);
                v_int16x8 v_s3n2 = v_reinterpret_as_s16(v_un2);
                v_int16x8 v_s3p1 = v_reinterpret_as_s16(v_up1);
                v_int16x8 v_s3p2 = v_reinterpret_as_s16(v_up2);

                // dx & dy for rows 1, 2, 3
                v_int16x8 v_sdx1, v_sdy1;
                spatialGradientKernel<v_int16x8>( v_sdx1, v_sdy1,
                                                  v_s1m1, v_s1n1, v_s1p1,
                                                  v_s2m1,         v_s2p1,
                                                  v_s3m1, v_s3n1, v_s3p1 );

                v_int16x8 v_sdx2, v_sdy2;
                spatialGradientKernel<v_int16x8>( v_sdx2, v_sdy2,
                                                  v_s1m2, v_s1n2, v_s1p2,
                                                  v_s2m2,         v_s2p2,
                                                  v_s3m2, v_s3n2, v_s3p2 );

                // Store
                v_store(&c_dx[j],   v_sdx1);
                v_store(&c_dx[j+8], v_sdx2);
                v_store(&c_dy[j],   v_sdy1);
                v_store(&c_dy[j+8], v_sdy2);

                // Load fourth row for 3x3 Sobel filter
                v_um = v_load(&m_src[j-1]);
                v_up = v_load(&m_src[j+1]);
                // TODO: Replace _mm_slli_si128 with hal method
                v_un = v_select(v_select_m, v_uint8x16(_mm_slli_si128(v_up.val, 1)),
                                            v_uint8x16(_mm_srli_si128(v_um.val, 1)));
                v_expand(v_um, v_um1, v_um2);
                v_expand(v_un, v_un1, v_un2);
                v_expand(v_up, v_up1, v_up2);
                v_int16x8 v_s4m1 = v_reinterpret_as_s16(v_um1);
                v_int16x8 v_s4m2 = v_reinterpret_as_s16(v_um2);
                v_int16x8 v_s4n1 = v_reinterpret_as_s16(v_un1);
                v_int16x8 v_s4n2 = v_reinterpret_as_s16(v_un2);
                v_int16x8 v_s4p1 = v_reinterpret_as_s16(v_up1);
                v_int16x8 v_s4p2 = v_reinterpret_as_s16(v_up2);

                // dx & dy for rows 2, 3, 4
                spatialGradientKernel<v_int16x8>( v_sdx1, v_sdy1,
                                                  v_s2m1, v_s2n1, v_s2p1,
                                                  v_s3m1,         v_s3p1,
                                                  v_s4m1, v_s4n1, v_s4p1 );

                spatialGradientKernel<v_int16x8>( v_sdx2, v_sdy2,
                                                  v_s2m2, v_s2n2, v_s2p2,
                                                  v_s3m2,         v_s3p2,
                                                  v_s4m2, v_s4n2, v_s4p2 );

                // Store
                v_store(&n_dx[j],   v_sdx1);
                v_store(&n_dx[j+8], v_sdx2);
                v_store(&n_dy[j],   v_sdy1);
                v_store(&n_dy[j+8], v_sdy2);
            }
        }
    }
    i_start = i;
    j_start = j;
#endif
    int j_p, j_n;
    uchar v00, v01, v02, v10, v11, v12, v20, v21, v22;
    for ( i = 0; i < H; i++ )
    {
        if   ( i == 0 ) p_src = src.ptr<uchar>(i_top);
        else            p_src = src.ptr<uchar>(i-1);

        c_src = src.ptr<uchar>(i);

        if ( i == H - 1 ) n_src = src.ptr<uchar>(i_bottom);
        else              n_src = src.ptr<uchar>(i+1);

        c_dx = dx.ptr<short>(i);
        c_dy = dy.ptr<short>(i);

        // Process left-most column
        j = 0;
        j_p = j + j_offl;
        j_n = 1;
        if ( j_n >= W ) j_n = j + j_offr;
        v00 = p_src[j_p]; v01 = p_src[j]; v02 = p_src[j_n];
        v10 = c_src[j_p]; v11 = c_src[j]; v12 = c_src[j_n];
        v20 = n_src[j_p]; v21 = n_src[j]; v22 = n_src[j_n];
        spatialGradientKernel<short>( c_dx[0], c_dy[0], v00, v01, v02, v10,
                                      v12, v20, v21, v22 );
        v00 = v01; v10 = v11; v20 = v21;
        v01 = v02; v11 = v12; v21 = v22;

        // Process middle columns
        j = i >= i_start ? 1 : j_start;
        j_p = j - 1;
        v00 = p_src[j_p]; v01 = p_src[j];
        v10 = c_src[j_p]; v11 = c_src[j];
        v20 = n_src[j_p]; v21 = n_src[j];

        for ( ; j < W - 1; j++ )
        {
            // Get values for next column
            j_n = j + 1; v02 = p_src[j_n]; v12 = c_src[j_n]; v22 = n_src[j_n];
            spatialGradientKernel<short>( c_dx[j], c_dy[j], v00, v01, v02, v10,
                                          v12, v20, v21, v22 );

            // Move values back one column for next iteration
            v00 = v01; v10 = v11; v20 = v21;
            v01 = v02; v11 = v12; v21 = v22;
        }

        // Process right-most column
        if ( j < W )
        {
            j_n = j + j_offr; v02 = p_src[j_n]; v12 = c_src[j_n]; v22 = n_src[j_n];
            spatialGradientKernel<short>( c_dx[j], c_dy[j], v00, v01, v02, v10,
                                          v12, v20, v21, v22 );
        }
    }

}
コード例 #2
0
ファイル: templmatch.cpp プロジェクト: 2693/opencv
void cv::matchTemplate( InputArray _img, InputArray _templ, OutputArray _result, int method )
{
    CV_Assert( CV_TM_SQDIFF <= method && method <= CV_TM_CCOEFF_NORMED );

    int numType = method == CV_TM_CCORR || method == CV_TM_CCORR_NORMED ? 0 :
                  method == CV_TM_CCOEFF || method == CV_TM_CCOEFF_NORMED ? 1 : 2;
    bool isNormed = method == CV_TM_CCORR_NORMED ||
                    method == CV_TM_SQDIFF_NORMED ||
                    method == CV_TM_CCOEFF_NORMED;

    Mat img = _img.getMat(), templ = _templ.getMat();
    if( img.rows < templ.rows || img.cols < templ.cols )
        std::swap(img, templ);

    CV_Assert( (img.depth() == CV_8U || img.depth() == CV_32F) &&
               img.type() == templ.type() );

    Size corrSize(img.cols - templ.cols + 1, img.rows - templ.rows + 1);
    _result.create(corrSize, CV_32F);
    Mat result = _result.getMat();

    int cn = img.channels();
    crossCorr( img, templ, result, result.size(), result.type(), Point(0,0), 0, 0);

    if( method == CV_TM_CCORR )
        return;

    double invArea = 1./((double)templ.rows * templ.cols);

    Mat sum, sqsum;
    Scalar templMean, templSdv;
    double *q0 = 0, *q1 = 0, *q2 = 0, *q3 = 0;
    double templNorm = 0, templSum2 = 0;

    if( method == CV_TM_CCOEFF )
    {
        integral(img, sum, CV_64F);
        templMean = mean(templ);
    }
    else
    {
        integral(img, sum, sqsum, CV_64F);
        meanStdDev( templ, templMean, templSdv );

        templNorm = CV_SQR(templSdv[0]) + CV_SQR(templSdv[1]) +
                    CV_SQR(templSdv[2]) + CV_SQR(templSdv[3]);

        if( templNorm < DBL_EPSILON && method == CV_TM_CCOEFF_NORMED )
        {
            result = Scalar::all(1);
            return;
        }

        templSum2 = templNorm +
                     CV_SQR(templMean[0]) + CV_SQR(templMean[1]) +
                     CV_SQR(templMean[2]) + CV_SQR(templMean[3]);

        if( numType != 1 )
        {
            templMean = Scalar::all(0);
            templNorm = templSum2;
        }

        templSum2 /= invArea;
        templNorm = sqrt(templNorm);
        templNorm /= sqrt(invArea); // care of accuracy here

        q0 = (double*)sqsum.data;
        q1 = q0 + templ.cols*cn;
        q2 = (double*)(sqsum.data + templ.rows*sqsum.step);
        q3 = q2 + templ.cols*cn;
    }

    double* p0 = (double*)sum.data;
    double* p1 = p0 + templ.cols*cn;
    double* p2 = (double*)(sum.data + templ.rows*sum.step);
    double* p3 = p2 + templ.cols*cn;

    int sumstep = sum.data ? (int)(sum.step / sizeof(double)) : 0;
    int sqstep = sqsum.data ? (int)(sqsum.step / sizeof(double)) : 0;

    int i, j, k;

    for( i = 0; i < result.rows; i++ )
    {
        float* rrow = (float*)(result.data + i*result.step);
        int idx = i * sumstep;
        int idx2 = i * sqstep;

        for( j = 0; j < result.cols; j++, idx += cn, idx2 += cn )
        {
            double num = rrow[j], t;
            double wndMean2 = 0, wndSum2 = 0;

            if( numType == 1 )
            {
                for( k = 0; k < cn; k++ )
                {
                    t = p0[idx+k] - p1[idx+k] - p2[idx+k] + p3[idx+k];
                    wndMean2 += CV_SQR(t);
                    num -= t*templMean[k];
                }

                wndMean2 *= invArea;
            }

            if( isNormed || numType == 2 )
            {
                for( k = 0; k < cn; k++ )
                {
                    t = q0[idx2+k] - q1[idx2+k] - q2[idx2+k] + q3[idx2+k];
                    wndSum2 += t;
                }

                if( numType == 2 )
                    num = wndSum2 - 2*num + templSum2;
            }

            if( isNormed )
            {
                t = sqrt(MAX(wndSum2 - wndMean2,0))*templNorm;
                if( fabs(num) < t )
                    num /= t;
                else if( fabs(num) < t*1.125 )
                    num = num > 0 ? 1 : -1;
                else
                    num = method != CV_TM_SQDIFF_NORMED ? 0 : 1;
            }

            rrow[j] = (float)num;
        }
    }
}
コード例 #3
0
ファイル: btv_l1.cpp プロジェクト: 2december/opencv
    void BTVL1_Base::process(InputArrayOfArrays _src, OutputArray _dst, InputArrayOfArrays _forwardMotions,
                             InputArrayOfArrays _backwardMotions, int baseIdx)
    {
        CV_Assert( scale_ > 1 );
        CV_Assert( iterations_ > 0 );
        CV_Assert( tau_ > 0.0 );
        CV_Assert( alpha_ > 0.0 );
        CV_Assert( btvKernelSize_ > 0 );
        CV_Assert( blurKernelSize_ > 0 );
        CV_Assert( blurSigma_ >= 0.0 );

        CV_OCL_RUN(_src.isUMatVector() && _dst.isUMat() && _forwardMotions.isUMatVector() &&
                   _backwardMotions.isUMatVector(),
                   ocl_process(_src, _dst, _forwardMotions, _backwardMotions, baseIdx))

        std::vector<Mat> & src = *(std::vector<Mat> *)_src.getObj(),
                & forwardMotions = *(std::vector<Mat> *)_forwardMotions.getObj(),
                & backwardMotions = *(std::vector<Mat> *)_backwardMotions.getObj();

        // update blur filter and btv weights
        if (blurKernelSize_ != curBlurKernelSize_ || blurSigma_ != curBlurSigma_ || src[0].type() != curSrcType_)
        {
            //filter_ = createGaussianFilter(src[0].type(), Size(blurKernelSize_, blurKernelSize_), blurSigma_);
            curBlurKernelSize_ = blurKernelSize_;
            curBlurSigma_ = blurSigma_;
            curSrcType_ = src[0].type();
        }

        if (btvWeights_.empty() || btvKernelSize_ != curBtvKernelSize_ || alpha_ != curAlpha_)
        {
            calcBtvWeights(btvKernelSize_, alpha_, btvWeights_);
            curBtvKernelSize_ = btvKernelSize_;
            curAlpha_ = alpha_;
        }

        // calc high res motions
        calcRelativeMotions(forwardMotions, backwardMotions, lowResForwardMotions_, lowResBackwardMotions_, baseIdx, src[0].size());

        upscaleMotions(lowResForwardMotions_, highResForwardMotions_, scale_);
        upscaleMotions(lowResBackwardMotions_, highResBackwardMotions_, scale_);

        forwardMaps_.resize(highResForwardMotions_.size());
        backwardMaps_.resize(highResForwardMotions_.size());
        for (size_t i = 0; i < highResForwardMotions_.size(); ++i)
            buildMotionMaps(highResForwardMotions_[i], highResBackwardMotions_[i], forwardMaps_[i], backwardMaps_[i]);

        // initial estimation
        const Size lowResSize = src[0].size();
        const Size highResSize(lowResSize.width * scale_, lowResSize.height * scale_);

        resize(src[baseIdx], highRes_, highResSize, 0, 0, INTER_CUBIC);

        // iterations
        diffTerm_.create(highResSize, highRes_.type());
        a_.create(highResSize, highRes_.type());
        b_.create(highResSize, highRes_.type());
        c_.create(lowResSize, highRes_.type());

        for (int i = 0; i < iterations_; ++i)
        {
            diffTerm_.setTo(Scalar::all(0));

            for (size_t k = 0; k < src.size(); ++k)
            {
                // a = M * Ih
                remap(highRes_, a_, backwardMaps_[k], noArray(), INTER_NEAREST);
                // b = HM * Ih
                GaussianBlur(a_, b_, Size(blurKernelSize_, blurKernelSize_), blurSigma_);
                // c = DHM * Ih
                resize(b_, c_, lowResSize, 0, 0, INTER_NEAREST);

                diffSign(src[k], c_, c_);

                // a = Dt * diff
                upscale(c_, a_, scale_);
                // b = HtDt * diff
                GaussianBlur(a_, b_, Size(blurKernelSize_, blurKernelSize_), blurSigma_);
                // a = MtHtDt * diff
                remap(b_, a_, forwardMaps_[k], noArray(), INTER_NEAREST);

                add(diffTerm_, a_, diffTerm_);
            }

            if (lambda_ > 0)
            {
                calcBtvRegularization(highRes_, regTerm_, btvKernelSize_, btvWeights_, ubtvWeights_);
                addWeighted(diffTerm_, 1.0, regTerm_, -lambda_, 0.0, diffTerm_);
            }

            addWeighted(highRes_, 1.0, diffTerm_, tau_, 0.0, highRes_);
        }

        Rect inner(btvKernelSize_, btvKernelSize_, highRes_.cols - 2 * btvKernelSize_, highRes_.rows - 2 * btvKernelSize_);
        highRes_(inner).copyTo(_dst);
    }
コード例 #4
0
//----------------------------------------------------------------------------
bool FxCompiler::UpdateShader (Shader* shader, const Program& program,
    InputArray& inputs, OutputArray& outputs, ConstantArray& constants,
    SamplerArray& samplers)
{
    int numInputs = (int)inputs.size();
    if (numInputs != shader->GetNumInputs())
    {
        ReportError("Mismatch in number of inputs.\n");
        return false;
    }

    int numOutputs = (int)outputs.size();
    if (numOutputs != shader->GetNumOutputs())
    {
        ReportError("Mismatch in number of outputs.\n");
        return false;
    }

    int numConstants = (int)constants.size();
    if (numConstants != shader->GetNumConstants())
    {
        ReportError("Mismatch in number of constants.\n");
        return false;
    }

    int numSamplers = (int)samplers.size();
    if (numSamplers != shader->GetNumSamplers())
    {
        ReportError("Mismatch in number of samplers.\n");
        return false;
    }

    std::string message;
    int i;
    for (i = 0; i < numInputs; ++i)
    {
        Input& input = inputs[i];
        if (input.Name != shader->GetInputName(i))
        {
            message =  "Mismatch in input names '" +
                input.Name +
                "' and '" +
                shader->GetInputName(i);

            ReportError(message);
            return false;
        }
        if (input.Type != shader->GetInputType(i))
        {
            message =  "Mismatch in input types '" +
                msVTName[input.Type] +
                "' and '" +
                msVTName[shader->GetInputType(i)];

            ReportError(message);
            return false;
        }
        if (input.Semantic != shader->GetInputSemantic(i))
        {
            message =  "Mismatch in input semantics '" +
                msVSName[input.Semantic] +
                "' and '" +
                msVSName[shader->GetInputSemantic(i)];

            ReportError(message);
            return false;
        }
    }

    for (i = 0; i < numOutputs; ++i)
    {
        Output& output = outputs[i];
        if (output.Name != shader->GetOutputName(i))
        {
            message =  "Mismatch in output names '" +
                output.Name +
                "' and '" +
                shader->GetOutputName(i);

            ReportError(message);
            return false;
        }
        if (output.Type != shader->GetOutputType(i))
        {
            message =  "Mismatch in output types '" +
                msVTName[output.Type] +
                "' and '" +
                msVTName[shader->GetOutputType(i)];

            ReportError(message);
            return false;
        }
        if (output.Semantic != shader->GetOutputSemantic(i))
        {
            message =  "Mismatch in output semantics '" +
                msVSName[output.Semantic] +
                "' and '" +
                msVSName[shader->GetOutputSemantic(i)];

            ReportError(message);
            return false;
        }
    }

    for (i = 0; i < numConstants; ++i)
    {
        Constant& constant = constants[i];
        if (constant.Name != shader->GetConstantName(i))
        {
            message =  "Mismatch in constant names '" +
                constant.Name +
                "' and '" +
                shader->GetConstantName(i);

            ReportError(message);
            return false;
        }
        if (constant.NumRegistersUsed != shader->GetNumRegistersUsed(i))
        {
            char number0[8], number1[8];
            sprintf(number0, "%d", constant.NumRegistersUsed);
            sprintf(number1, "%d", shader->GetNumRegistersUsed(i));
            message =  "Mismatch in constant registers used '" +
                std::string(number0) +
                "' and '" +
                std::string(number1);

            ReportError(message);
            return false;
        }
        shader->SetBaseRegister(mActiveProfile, i, constant.BaseRegister);
    }

    for (i = 0; i < numSamplers; ++i)
    {
        Sampler& sampler = samplers[i];
        if (sampler.Name != shader->GetSamplerName(i))
        {
            message =  "Mismatch in sampler names '" +
                sampler.Name +
                "' and '" +
                shader->GetSamplerName(i);

            ReportError(message);
            return false;
        }
        if (sampler.Type != shader->GetSamplerType(i))
        {
            message =  "Mismatch in sampler types '" +
                msSTName[sampler.Type] +
                "' and '" +
                msSTName[shader->GetSamplerType(i)];

            ReportError(message);
            return false;
        }
        shader->SetTextureUnit(mActiveProfile, i, sampler.Unit);
    }

    shader->SetProgram(mActiveProfile, program.Text);
    return true;
}
コード例 #5
0
        bool PositionCalculatorImpl::computeStateImpl( double /*time*/, OutputArray _state, OutputArray _covariance )
        {
            _state.create( 3, 1, CV_64F );
            Mat& state = _state.getMatRef();

            const int num = static_cast< int >(positions.size());
            F.create( 2 * num, 3, CV_64F );
            b.create( 2 * num, 1, CV_64F );

            for ( int i = 0; i < num; ++i )
            {
                F.at< double >( i, 0 ) = sin( angles[i].x );
                F.at< double >( i, 1 ) = -cos( angles[i].x );
                F.at< double >( i, 2 ) = 0;

                F.at< double >( num + i, 0 ) = -sin( angles[i].y ) * cos( angles[i].x );
                F.at< double >( num + i, 1 ) = -sin( angles[i].y ) * sin( angles[i].x );
                F.at< double >( num + i, 2 ) = cos( angles[i].y );

                b.at< double >( i ) = ( F( Rect( 0, i, 3, 1 ) ) * positions[i] ).operator Mat().at< double >( 0 );
                b.at< double >( num + i ) = ( F( Rect( 0, num + i, 3, 1 ) ) * positions[i] ).operator Mat().at< double
                >( 0 );
            }

            Mat iple;
            solve( F, b, iple, DECOMP_SVD );

            G.create( 2 * num, 3, CV_64F );
            W.create( 2 * num, 2 * num, CV_64F );
            W.setTo( 0 );

            for ( int i = 0; i < num; ++i )
            {
                const Point2d new_ang = getAzEl( positions[i], iple );
                G.at< double >( i, 0 ) = sin( new_ang.x );
                G.at< double >( i, 1 ) = -cos( new_ang.x );
                G.at< double >( i, 2 ) = 0;

                G.at< double >( num + i, 0 ) = -sin( new_ang.y ) * cos( new_ang.x );
                G.at< double >( num + i, 1 ) = -sin( new_ang.y ) * sin( new_ang.x );
                G.at< double >( num + i, 2 ) = cos( new_ang.y );

                Point2f diff2;
                Point3f diff3;

                diff2.x = ( iple.at< double >( 0 ) - positions[i].at< double >( 0 ) );
                diff2.y = ( iple.at< double >( 1 ) - positions[i].at< double >( 1 ) );
                diff3.x = diff2.x;
                diff3.y = diff2.y;
                diff3.z = ( iple.at< double >( 2 ) - positions[i].at< double >( 2 ) );
                W.at< double >( i, i ) = norm( diff2 );
                W.at< double >( i + num, i + num ) = ( norm( diff3 ) - W.at< double >( i, i ) );
            }

            state = ( G.t() * W * F ).operator Mat().inv() * G.t() * W * b;

            if ( _covariance.needed() )
            {
                Mat& cov = _covariance.getMatRef();
                cov = G.t() * F / ( num / 2.0 );
                multiply( cov, sum( F * state - b )( 0 ), cov );
            }
            return true;
        }
コード例 #6
0
void cv::merge(const Mat* mv, size_t n, OutputArray _dst)
{
    CV_Assert( mv && n > 0 );
    
    int depth = mv[0].depth();
    bool allch1 = true;
    int k, cn = 0;
    size_t i;
    
    for( i = 0; i < n; i++ )
    {
        CV_Assert(mv[i].size == mv[0].size && mv[i].depth() == depth);
        allch1 = allch1 && mv[i].channels() == 1;
        cn += mv[i].channels();
    }
    
    CV_Assert( 0 < cn && cn <= CV_CN_MAX );
    _dst.create(mv[0].dims, mv[0].size, CV_MAKETYPE(depth, cn));
    Mat dst = _dst.getMat();
    
    if( n == 1 )
    {
        mv[0].copyTo(dst);
        return;
    }
    
    if( !allch1 )
    {
        AutoBuffer<int> pairs(cn*2);
        int j, ni=0;
        
        for( i = 0, j = 0; i < n; i++, j += ni )
        {
            ni = mv[i].channels();
            for( k = 0; k < ni; k++ )
            {
                pairs[(j+k)*2] = j + k;
                pairs[(j+k)*2+1] = j + k;
            }
        }
        mixChannels( mv, n, &dst, 1, &pairs[0], cn );
        return;
    }
        
    size_t esz = dst.elemSize(), esz1 = dst.elemSize1();
    int blocksize0 = (int)((BLOCK_SIZE + esz-1)/esz);
    AutoBuffer<uchar> _buf((cn+1)*(sizeof(Mat*) + sizeof(uchar*)) + 16);
    const Mat** arrays = (const Mat**)(uchar*)_buf;
    uchar** ptrs = (uchar**)alignPtr(arrays + cn + 1, 16);
    
    arrays[0] = &dst;
    for( k = 0; k < cn; k++ )
        arrays[k+1] = &mv[k];
    
    NAryMatIterator it(arrays, ptrs, cn+1);
    int total = (int)it.size, blocksize = cn <= 4 ? total : std::min(total, blocksize0);
    MergeFunc func = mergeTab[depth];
    
    for( i = 0; i < it.nplanes; i++, ++it )
    {
        for( int j = 0; j < total; j += blocksize )
        {
            int bsz = std::min(total - j, blocksize);
            func( (const uchar**)&ptrs[1], ptrs[0], bsz, cn );
            
            if( j + blocksize < total )
            {
                ptrs[0] += bsz*esz;
                for( int k = 0; k < cn; k++ )
                    ptrs[k+1] += bsz*esz1;
            }
        }
    }
}
コード例 #7
0
ファイル: test_misc.cpp プロジェクト: 2december/opencv
 static void create(OutputArray arr, Size submatSize, int type)
 {
     int sizes[] = {submatSize.width, submatSize.height};
     arr.create(sizeof(sizes)/sizeof(sizes[0]), sizes, type);
 }
コード例 #8
0
ファイル: convhull.cpp プロジェクト: acss/opencv
void convexityDefects( InputArray _points, InputArray _hull, OutputArray _defects )
{
    CV_INSTRUMENT_REGION()

    Mat points = _points.getMat();
    int i, j = 0, npoints = points.checkVector(2, CV_32S);
    CV_Assert( npoints >= 0 );

    if( npoints <= 3 )
    {
        _defects.release();
        return;
    }

    Mat hull = _hull.getMat();
    int hpoints = hull.checkVector(1, CV_32S);
    CV_Assert( hpoints > 2 );

    const Point* ptr = points.ptr<Point>();
    const int* hptr = hull.ptr<int>();
    std::vector<Vec4i> defects;

    // 1. recognize co-orientation of the contour and its hull
    bool rev_orientation = ((hptr[1] > hptr[0]) + (hptr[2] > hptr[1]) + (hptr[0] > hptr[2])) != 2;

    // 2. cycle through points and hull, compute defects
    int hcurr = hptr[rev_orientation ? 0 : hpoints-1];
    CV_Assert( 0 <= hcurr && hcurr < npoints );

    for( i = 0; i < hpoints; i++ )
    {
        int hnext = hptr[rev_orientation ? hpoints - i - 1 : i];
        CV_Assert( 0 <= hnext && hnext < npoints );

        Point pt0 = ptr[hcurr], pt1 = ptr[hnext];
        double dx0 = pt1.x - pt0.x;
        double dy0 = pt1.y - pt0.y;
        double scale = dx0 == 0 && dy0 == 0 ? 0. : 1./std::sqrt(dx0*dx0 + dy0*dy0);

        int defect_deepest_point = -1;
        double defect_depth = 0;
        bool is_defect = false;
        j=hcurr;
        for(;;)
        {
            // go through points to achieve next hull point
            j++;
            j &= j >= npoints ? 0 : -1;
            if( j == hnext )
                break;

            // compute distance from current point to hull edge
            double dx = ptr[j].x - pt0.x;
            double dy = ptr[j].y - pt0.y;
            double dist = fabs(-dy0*dx + dx0*dy) * scale;

            if( dist > defect_depth )
            {
                defect_depth = dist;
                defect_deepest_point = j;
                is_defect = true;
            }
        }

        if( is_defect )
        {
            int idepth = cvRound(defect_depth*256);
            defects.push_back(Vec4i(hcurr, hnext, defect_deepest_point, idepth));
        }

        hcurr = hnext;
    }

    Mat(defects).copyTo(_defects);
}
コード例 #9
0
ファイル: kmeans.cpp プロジェクト: 410pfeliciano/opencv
double cv::kmeans( InputArray _data, int K,
                   InputOutputArray _bestLabels,
                   TermCriteria criteria, int attempts,
                   int flags, OutputArray _centers )
{
    const int SPP_TRIALS = 3;
    Mat data0 = _data.getMat();
    bool isrow = data0.rows == 1;
    int N = isrow ? data0.cols : data0.rows;
    int dims = (isrow ? 1 : data0.cols)*data0.channels();
    int type = data0.depth();

    attempts = std::max(attempts, 1);
    CV_Assert( data0.dims <= 2 && type == CV_32F && K > 0 );
    CV_Assert( N >= K );

    Mat data(N, dims, CV_32F, data0.ptr(), isrow ? dims * sizeof(float) : static_cast<size_t>(data0.step));

    _bestLabels.create(N, 1, CV_32S, -1, true);

    Mat _labels, best_labels = _bestLabels.getMat();
    if( flags & CV_KMEANS_USE_INITIAL_LABELS )
    {
        CV_Assert( (best_labels.cols == 1 || best_labels.rows == 1) &&
                   best_labels.cols*best_labels.rows == N &&
                   best_labels.type() == CV_32S &&
                   best_labels.isContinuous());
        best_labels.copyTo(_labels);
    }
    else
    {
        if( !((best_labels.cols == 1 || best_labels.rows == 1) &&
                best_labels.cols*best_labels.rows == N &&
                best_labels.type() == CV_32S &&
                best_labels.isContinuous()))
            best_labels.create(N, 1, CV_32S);
        _labels.create(best_labels.size(), best_labels.type());
    }
    int* labels = _labels.ptr<int>();

    Mat centers(K, dims, type), old_centers(K, dims, type), temp(1, dims, type);
    std::vector<int> counters(K);
    std::vector<Vec2f> _box(dims);
    Vec2f* box = &_box[0];
    double best_compactness = DBL_MAX, compactness = 0;
    RNG& rng = theRNG();
    int a, iter, i, j, k;

    if( criteria.type & TermCriteria::EPS )
        criteria.epsilon = std::max(criteria.epsilon, 0.);
    else
        criteria.epsilon = FLT_EPSILON;
    criteria.epsilon *= criteria.epsilon;

    if( criteria.type & TermCriteria::COUNT )
        criteria.maxCount = std::min(std::max(criteria.maxCount, 2), 100);
    else
        criteria.maxCount = 100;

    if( K == 1 )
    {
        attempts = 1;
        criteria.maxCount = 2;
    }

    const float* sample = data.ptr<float>(0);
    for( j = 0; j < dims; j++ )
        box[j] = Vec2f(sample[j], sample[j]);

    for( i = 1; i < N; i++ )
    {
        sample = data.ptr<float>(i);
        for( j = 0; j < dims; j++ )
        {
            float v = sample[j];
            box[j][0] = std::min(box[j][0], v);
            box[j][1] = std::max(box[j][1], v);
        }
    }

    for( a = 0; a < attempts; a++ )
    {
        double max_center_shift = DBL_MAX;
        for( iter = 0;; )
        {
            swap(centers, old_centers);

            if( iter == 0 && (a > 0 || !(flags & KMEANS_USE_INITIAL_LABELS)) )
            {
                if( flags & KMEANS_PP_CENTERS )
                    generateCentersPP(data, centers, K, rng, SPP_TRIALS);
                else
                {
                    for( k = 0; k < K; k++ )
                        generateRandomCenter(_box, centers.ptr<float>(k), rng);
                }
            }
            else
            {
                if( iter == 0 && a == 0 && (flags & KMEANS_USE_INITIAL_LABELS) )
                {
                    for( i = 0; i < N; i++ )
                        CV_Assert( (unsigned)labels[i] < (unsigned)K );
                }

                // compute centers
                centers = Scalar(0);
                for( k = 0; k < K; k++ )
                    counters[k] = 0;

                for( i = 0; i < N; i++ )
                {
                    sample = data.ptr<float>(i);
                    k = labels[i];
                    float* center = centers.ptr<float>(k);
                    j=0;
#if CV_ENABLE_UNROLLED
                    for(; j <= dims - 4; j += 4 )
                    {
                        float t0 = center[j] + sample[j];
                        float t1 = center[j+1] + sample[j+1];

                        center[j] = t0;
                        center[j+1] = t1;

                        t0 = center[j+2] + sample[j+2];
                        t1 = center[j+3] + sample[j+3];

                        center[j+2] = t0;
                        center[j+3] = t1;
                    }
#endif
                    for( ; j < dims; j++ )
                        center[j] += sample[j];
                    counters[k]++;
                }

                if( iter > 0 )
                    max_center_shift = 0;

                for( k = 0; k < K; k++ )
                {
                    if( counters[k] != 0 )
                        continue;

                    // if some cluster appeared to be empty then:
                    //   1. find the biggest cluster
                    //   2. find the farthest from the center point in the biggest cluster
                    //   3. exclude the farthest point from the biggest cluster and form a new 1-point cluster.
                    int max_k = 0;
                    for( int k1 = 1; k1 < K; k1++ )
                    {
                        if( counters[max_k] < counters[k1] )
                            max_k = k1;
                    }

                    double max_dist = 0;
                    int farthest_i = -1;
                    float* new_center = centers.ptr<float>(k);
                    float* old_center = centers.ptr<float>(max_k);
                    float* _old_center = temp.ptr<float>(); // normalized
                    float scale = 1.f/counters[max_k];
                    for( j = 0; j < dims; j++ )
                        _old_center[j] = old_center[j]*scale;

                    for( i = 0; i < N; i++ )
                    {
                        if( labels[i] != max_k )
                            continue;
                        sample = data.ptr<float>(i);
                        double dist = normL2Sqr(sample, _old_center, dims);

                        if( max_dist <= dist )
                        {
                            max_dist = dist;
                            farthest_i = i;
                        }
                    }

                    counters[max_k]--;
                    counters[k]++;
                    labels[farthest_i] = k;
                    sample = data.ptr<float>(farthest_i);

                    for( j = 0; j < dims; j++ )
                    {
                        old_center[j] -= sample[j];
                        new_center[j] += sample[j];
                    }
                }

                for( k = 0; k < K; k++ )
                {
                    float* center = centers.ptr<float>(k);
                    CV_Assert( counters[k] != 0 );

                    float scale = 1.f/counters[k];
                    for( j = 0; j < dims; j++ )
                        center[j] *= scale;

                    if( iter > 0 )
                    {
                        double dist = 0;
                        const float* old_center = old_centers.ptr<float>(k);
                        for( j = 0; j < dims; j++ )
                        {
                            double t = center[j] - old_center[j];
                            dist += t*t;
                        }
                        max_center_shift = std::max(max_center_shift, dist);
                    }
                }
            }

            if( ++iter == MAX(criteria.maxCount, 2) || max_center_shift <= criteria.epsilon )
                break;

            // assign labels
            Mat dists(1, N, CV_64F);
            double* dist = dists.ptr<double>(0);
            parallel_for_(Range(0, N),
                          KMeansDistanceComputer(dist, labels, data, centers));
            compactness = 0;
            for( i = 0; i < N; i++ )
            {
                compactness += dist[i];
            }
        }

        if( compactness < best_compactness )
        {
            best_compactness = compactness;
            if( _centers.needed() )
                centers.copyTo(_centers);
            _labels.copyTo(best_labels);
        }
    }

    return best_compactness;
}
コード例 #10
0
void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners,
                              int maxCorners, double qualityLevel, double minDistance,
                              InputArray _mask, int blockSize,
                              bool useHarrisDetector, double harrisK )
{
    Mat image = _image.getMat(), mask = _mask.getMat();
    
    CV_Assert( qualityLevel > 0 && minDistance >= 0 && maxCorners >= 0 );
    CV_Assert( mask.empty() || (mask.type() == CV_8UC1 && mask.size() == image.size()) );

    Mat eig, tmp;
    if( useHarrisDetector )
        cornerHarris( image, eig, blockSize, 3, harrisK );
    else
        cornerMinEigenVal( image, eig, blockSize, 3 );

    double maxVal = 0;
    minMaxLoc( eig, 0, &maxVal, 0, 0, mask );
    threshold( eig, eig, maxVal*qualityLevel, 0, THRESH_TOZERO );
    dilate( eig, tmp, Mat());

    Size imgsize = image.size();

    vector<const float*> tmpCorners;

    // collect list of pointers to features - put them into temporary image
    for( int y = 1; y < imgsize.height - 1; y++ )
    {
        const float* eig_data = (const float*)eig.ptr(y);
        const float* tmp_data = (const float*)tmp.ptr(y);
        const uchar* mask_data = mask.data ? mask.ptr(y) : 0;

        for( int x = 1; x < imgsize.width - 1; x++ )
        {
            float val = eig_data[x];
            if( val != 0 && val == tmp_data[x] && (!mask_data || mask_data[x]) )
                tmpCorners.push_back(eig_data + x);
        }
    }

    sort( tmpCorners, greaterThanPtr<float>() );
    vector<Point2f> corners;
    size_t i, j, total = tmpCorners.size(), ncorners = 0;

    if(minDistance >= 1)
    {
         // Partition the image into larger grids
        int w = image.cols;
        int h = image.rows;

        const int cell_size = cvRound(minDistance);
        const int grid_width = (w + cell_size - 1) / cell_size;
        const int grid_height = (h + cell_size - 1) / cell_size;

        std::vector<std::vector<Point2f> > grid(grid_width*grid_height);

        minDistance *= minDistance;

        for( i = 0; i < total; i++ )
        {
            int ofs = (int)((const uchar*)tmpCorners[i] - eig.data);
            int y = (int)(ofs / eig.step);
            int x = (int)((ofs - y*eig.step)/sizeof(float));

	        bool good = true;

            int x_cell = x / cell_size;
            int y_cell = y / cell_size;

            int x1 = x_cell - 1;
            int y1 = y_cell - 1;
            int x2 = x_cell + 1;
            int y2 = y_cell + 1;

            // boundary check
            x1 = std::max(0, x1);
            y1 = std::max(0, y1);
            x2 = std::min(grid_width-1, x2);
            y2 = std::min(grid_height-1, y2);

            for( int yy = y1; yy <= y2; yy++ )
            {
                for( int xx = x1; xx <= x2; xx++ )
                {   
                    vector <Point2f> &m = grid[yy*grid_width + xx];

                    if( m.size() )
                    {
                        for(j = 0; j < m.size(); j++)
                        {
                            float dx = x - m[j].x;
                            float dy = y - m[j].y;

                            if( dx*dx + dy*dy < minDistance )
                            {
                                good = false;
                                goto break_out;
                            }
                        }
                    }                
                }
            }

            break_out:

            if(good)
            {
                // printf("%d: %d %d -> %d %d, %d, %d -- %d %d %d %d, %d %d, c=%d\n",
                //    i,x, y, x_cell, y_cell, (int)minDistance, cell_size,x1,y1,x2,y2, grid_width,grid_height,c);
                grid[y_cell*grid_width + x_cell].push_back(Point2f((float)x, (float)y));

                corners.push_back(Point2f((float)x, (float)y));
                ++ncorners;

                if( maxCorners > 0 && (int)ncorners == maxCorners )
                    break;
            }
        }
    }
    else
    {
        for( i = 0; i < total; i++ )
        {
            int ofs = (int)((const uchar*)tmpCorners[i] - eig.data);
            int y = (int)(ofs / eig.step);
            int x = (int)((ofs - y*eig.step)/sizeof(float));

            corners.push_back(Point2f((float)x, (float)y));
            ++ncorners;
            if( maxCorners > 0 && (int)ncorners == maxCorners )
                break;
        }
    }
    
    Mat(corners).convertTo(_corners, _corners.fixedType() ? _corners.type() : CV_32F);

    /*
    for( i = 0; i < total; i++ )
    {
        int ofs = (int)((const uchar*)tmpCorners[i] - eig.data);
        int y = (int)(ofs / eig.step);
        int x = (int)((ofs - y*eig.step)/sizeof(float));

        if( minDistance > 0 )
        {
            for( j = 0; j < ncorners; j++ )
            {
                float dx = x - corners[j].x;
                float dy = y - corners[j].y;
                if( dx*dx + dy*dy < minDistance )
                    break;
            }
            if( j < ncorners )
                continue;
        }

        corners.push_back(Point2f((float)x, (float)y));
        ++ncorners;
        if( maxCorners > 0 && (int)ncorners == maxCorners )
            break;
    }
*/
}
コード例 #11
0
ファイル: convhull.cpp プロジェクト: acss/opencv
void convexHull( InputArray _points, OutputArray _hull, bool clockwise, bool returnPoints )
{
    CV_INSTRUMENT_REGION()

    Mat points = _points.getMat();
    int i, total = points.checkVector(2), depth = points.depth(), nout = 0;
    int miny_ind = 0, maxy_ind = 0;
    CV_Assert(total >= 0 && (depth == CV_32F || depth == CV_32S));

    if( total == 0 )
    {
        _hull.release();
        return;
    }

    returnPoints = !_hull.fixedType() ? returnPoints : _hull.type() != CV_32S;

    bool is_float = depth == CV_32F;
    AutoBuffer<Point*> _pointer(total);
    AutoBuffer<int> _stack(total + 2), _hullbuf(total);
    Point** pointer = _pointer;
    Point2f** pointerf = (Point2f**)pointer;
    Point* data0 = points.ptr<Point>();
    int* stack = _stack;
    int* hullbuf = _hullbuf;

    CV_Assert(points.isContinuous());

    for( i = 0; i < total; i++ )
        pointer[i] = &data0[i];

    // sort the point set by x-coordinate, find min and max y
    if( !is_float )
    {
        std::sort(pointer, pointer + total, CHullCmpPoints<int>());
        for( i = 1; i < total; i++ )
        {
            int y = pointer[i]->y;
            if( pointer[miny_ind]->y > y )
                miny_ind = i;
            if( pointer[maxy_ind]->y < y )
                maxy_ind = i;
        }
    }
    else
    {
        std::sort(pointerf, pointerf + total, CHullCmpPoints<float>());
        for( i = 1; i < total; i++ )
        {
            float y = pointerf[i]->y;
            if( pointerf[miny_ind]->y > y )
                miny_ind = i;
            if( pointerf[maxy_ind]->y < y )
                maxy_ind = i;
        }
    }

    if( pointer[0]->x == pointer[total-1]->x &&
        pointer[0]->y == pointer[total-1]->y )
    {
        hullbuf[nout++] = 0;
    }
    else
    {
        // upper half
        int *tl_stack = stack;
        int tl_count = !is_float ?
            Sklansky_( pointer, 0, maxy_ind, tl_stack, -1, 1) :
            Sklansky_( pointerf, 0, maxy_ind, tl_stack, -1, 1);
        int *tr_stack = stack + tl_count;
        int tr_count = !is_float ?
            Sklansky_( pointer, total-1, maxy_ind, tr_stack, -1, -1) :
            Sklansky_( pointerf, total-1, maxy_ind, tr_stack, -1, -1);

        // gather upper part of convex hull to output
        if( !clockwise )
        {
            std::swap( tl_stack, tr_stack );
            std::swap( tl_count, tr_count );
        }

        for( i = 0; i < tl_count-1; i++ )
            hullbuf[nout++] = int(pointer[tl_stack[i]] - data0);
        for( i = tr_count - 1; i > 0; i-- )
            hullbuf[nout++] = int(pointer[tr_stack[i]] - data0);
        int stop_idx = tr_count > 2 ? tr_stack[1] : tl_count > 2 ? tl_stack[tl_count - 2] : -1;

        // lower half
        int *bl_stack = stack;
        int bl_count = !is_float ?
            Sklansky_( pointer, 0, miny_ind, bl_stack, 1, -1) :
            Sklansky_( pointerf, 0, miny_ind, bl_stack, 1, -1);
        int *br_stack = stack + bl_count;
        int br_count = !is_float ?
            Sklansky_( pointer, total-1, miny_ind, br_stack, 1, 1) :
            Sklansky_( pointerf, total-1, miny_ind, br_stack, 1, 1);

        if( clockwise )
        {
            std::swap( bl_stack, br_stack );
            std::swap( bl_count, br_count );
        }

        if( stop_idx >= 0 )
        {
            int check_idx = bl_count > 2 ? bl_stack[1] :
            bl_count + br_count > 2 ? br_stack[2-bl_count] : -1;
            if( check_idx == stop_idx || (check_idx >= 0 &&
                                          pointer[check_idx]->x == pointer[stop_idx]->x &&
                                          pointer[check_idx]->y == pointer[stop_idx]->y) )
            {
                // if all the points lie on the same line, then
                // the bottom part of the convex hull is the mirrored top part
                // (except the exteme points).
                bl_count = MIN( bl_count, 2 );
                br_count = MIN( br_count, 2 );
            }
        }

        for( i = 0; i < bl_count-1; i++ )
            hullbuf[nout++] = int(pointer[bl_stack[i]] - data0);
        for( i = br_count-1; i > 0; i-- )
            hullbuf[nout++] = int(pointer[br_stack[i]] - data0);
    }

    if( !returnPoints )
        Mat(nout, 1, CV_32S, hullbuf).copyTo(_hull);
    else
    {
        _hull.create(nout, 1, CV_MAKETYPE(depth, 2));
        Mat hull = _hull.getMat();
        size_t step = !hull.isContinuous() ? hull.step[0] : sizeof(Point);
        for( i = 0; i < nout; i++ )
            *(Point*)(hull.ptr() + i*step) = data0[hullbuf[i]];
    }
}
コード例 #12
0
ファイル: sift.cpp プロジェクト: Amorming/opencv
void SIFT::operator()(InputArray _image, InputArray _mask,
                      std::vector<KeyPoint>& keypoints,
                      OutputArray _descriptors,
                      bool useProvidedKeypoints) const
{
    int firstOctave = -1, actualNOctaves = 0, actualNLayers = 0;
    Mat image = _image.getMat(), mask = _mask.getMat();

    if( image.empty() || image.depth() != CV_8U )
        CV_Error( Error::StsBadArg, "image is empty or has incorrect depth (!=CV_8U)" );

    if( !mask.empty() && mask.type() != CV_8UC1 )
        CV_Error( Error::StsBadArg, "mask has incorrect type (!=CV_8UC1)" );

    if( useProvidedKeypoints )
    {
        firstOctave = 0;
        int maxOctave = INT_MIN;
        for( size_t i = 0; i < keypoints.size(); i++ )
        {
            int octave, layer;
            float scale;
            unpackOctave(keypoints[i], octave, layer, scale);
            firstOctave = std::min(firstOctave, octave);
            maxOctave = std::max(maxOctave, octave);
            actualNLayers = std::max(actualNLayers, layer-2);
        }

        firstOctave = std::min(firstOctave, 0);
        CV_Assert( firstOctave >= -1 && actualNLayers <= nOctaveLayers );
        actualNOctaves = maxOctave - firstOctave + 1;
    }

    Mat base = createInitialImage(image, firstOctave < 0, (float)sigma);
    std::vector<Mat> gpyr, dogpyr;
    int nOctaves = actualNOctaves > 0 ? actualNOctaves : cvRound(std::log( (double)std::min( base.cols, base.rows ) ) / std::log(2.) - 2) - firstOctave;

    //double t, tf = getTickFrequency();
    //t = (double)getTickCount();
    buildGaussianPyramid(base, gpyr, nOctaves);
    buildDoGPyramid(gpyr, dogpyr);

    //t = (double)getTickCount() - t;
    //printf("pyramid construction time: %g\n", t*1000./tf);

    if( !useProvidedKeypoints )
    {
        //t = (double)getTickCount();
        findScaleSpaceExtrema(gpyr, dogpyr, keypoints);
        KeyPointsFilter::removeDuplicated( keypoints );

        if( !mask.empty() )
            KeyPointsFilter::runByPixelsMask( keypoints, mask );

        if( nfeatures > 0 )
            KeyPointsFilter::retainBest(keypoints, nfeatures);
        //t = (double)getTickCount() - t;
        //printf("keypoint detection time: %g\n", t*1000./tf);

        if( firstOctave < 0 )
            for( size_t i = 0; i < keypoints.size(); i++ )
            {
                KeyPoint& kpt = keypoints[i];
                float scale = 1.f/(float)(1 << -firstOctave);
                kpt.octave = (kpt.octave & ~255) | ((kpt.octave + firstOctave) & 255);
                kpt.pt *= scale;
                kpt.size *= scale;
            }
    }
    else
    {
        // filter keypoints by mask
        //KeyPointsFilter::runByPixelsMask( keypoints, mask );
    }

    if( _descriptors.needed() )
    {
        //t = (double)getTickCount();
        int dsize = descriptorSize();
        _descriptors.create((int)keypoints.size(), dsize, CV_32F);
        Mat descriptors = _descriptors.getMat();

        calcDescriptors(gpyr, keypoints, descriptors, nOctaveLayers, firstOctave);
        //t = (double)getTickCount() - t;
        //printf("descriptor extraction time: %g\n", t*1000./tf);
    }
}
コード例 #13
0
ファイル: templmatch.cpp プロジェクト: 93sam/opencv
static bool matchTemplate_CCOEFF_NORMED(InputArray _image, InputArray _templ, OutputArray _result)
{
    matchTemplate(_image, _templ, _result, CV_TM_CCORR);

    UMat temp, image_sums, image_sqsums;
    integral(_image, image_sums, image_sqsums, CV_32F, CV_32F);

    int type = image_sums.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);

    ocl::Kernel k("matchTemplate_CCOEFF_NORMED", ocl::imgproc::match_template_oclsrc,
        format("-D CCOEFF_NORMED -D type=%s -D elem_type=%s -D cn=%d", ocl::typeToStr(type), ocl::typeToStr(depth), cn));
    if (k.empty())
        return false;

    UMat templ = _templ.getUMat();
    Size size = _image.size(), tsize = templ.size();
    _result.create(size.height - templ.rows + 1, size.width - templ.cols + 1, CV_32F);
    UMat result = _result.getUMat();

    float scale = 1.f / tsize.area();

    if (cn == 1)
    {
        float templ_sum = (float)sum(templ)[0];

        multiply(templ, templ, temp, 1, CV_32F);
        float templ_sqsum = (float)sum(temp)[0];

        templ_sqsum -= scale * templ_sum * templ_sum;
        templ_sum   *= scale;

        if (templ_sqsum < DBL_EPSILON)
        {
            result = Scalar::all(1);
            return true;
        }

        k.args(ocl::KernelArg::ReadOnlyNoSize(image_sums), ocl::KernelArg::ReadOnlyNoSize(image_sqsums),
                      ocl::KernelArg::ReadWrite(result), templ.rows, templ.cols, scale, templ_sum, templ_sqsum);
    }
    else
    {
        Vec4f templ_sum = Vec4f::all(0), templ_sqsum = Vec4f::all(0);
        templ_sum = sum(templ);

        multiply(templ, templ, temp, 1, CV_32F);
        templ_sqsum = sum(temp);

        float templ_sqsum_sum = 0;
        for (int i = 0; i < cn; i ++)
            templ_sqsum_sum += templ_sqsum[i] - scale * templ_sum[i] * templ_sum[i];

        templ_sum *= scale;

        if (templ_sqsum_sum < DBL_EPSILON)
        {
            result = Scalar::all(1);
            return true;
        }

        if (cn == 2)
            k.args(ocl::KernelArg::ReadOnlyNoSize(image_sums), ocl::KernelArg::ReadOnlyNoSize(image_sqsums),
                   ocl::KernelArg::ReadWrite(result), templ.rows, templ.cols, scale,
                   templ_sum[0], templ_sum[1], templ_sqsum_sum);
        else
            k.args(ocl::KernelArg::ReadOnlyNoSize(image_sums), ocl::KernelArg::ReadOnlyNoSize(image_sqsums),
                   ocl::KernelArg::ReadWrite(result), templ.rows, templ.cols, scale,
                   templ_sum[0], templ_sum[1], templ_sum[2], templ_sum[3], templ_sqsum_sum);
    }

    size_t globalsize[2] = { result.cols, result.rows };
    return k.run(2, globalsize, NULL, false);
}
コード例 #14
0
ファイル: baft.cpp プロジェクト: stardust2602/BAFT
/**
 * Function that computes the Harris responses in a
 * 2*r x 2*r patch at given points in the image
 */
static void
HarrisResponses(InputArray _img, InputArray _diff_x, InputArray _diff_y,
                std::vector<KeyPoint>& pts,
                OutputArray _response, int r, float harris_k)
{
    size_t ptidx, ptsize = pts.size();

    // Get mats
    Mat img = _img.getMat(), diff_x = _diff_x.getMat(),
        diff_y = _diff_y.getMat(), response;
    CV_Assert( img.type() == CV_8UC1 );


    bool compute_response = _response.needed();
    if (compute_response) response = _response.getMat();

    const int* dx00 = diff_x.ptr<int>();
    const int* dy00 = diff_y.ptr<int>();
    float* r00 = response.ptr<float>();
    int step = diff_x.step1();
    int r_step = response.step1();

    for( ptidx = 0; ptidx < ptsize; ptidx++ )
    {
        float kp_x = pts[ptidx].pt.x;
        float kp_y = pts[ptidx].pt.y;
        int x0 = (int)kp_x;
        int y0 = (int)kp_y;

        float xd = 2;
        float yd = 2;
        //float xd = 0.5;
        //float yd = 0.5;

        const int* dx0 = dx00 + (y0)*step + x0;
        const int* dy0 = dy00 + (y0)*step + x0;
        int a = 0, b = 0, c = 0, d = 0;
        float* r0 = r00 + ptidx*r_step;

        for( int i = -r; i < r; i++ )
        {
            for( int j = -r; j < r; j++ )
            {
                const int ofs = i*step + j;
                const int* dx = dx0 + ofs;
                const int* dy = dy0 + ofs;
                const int Ix = (float)dx[-1]*(xd) + (float)dx[0] + (float)dx[1]*xd + (float)dx[-step]*(yd) + (float)dx[step]*yd;
                const int Iy = (float)dy[-1]*(xd) + (float)dy[0] + (float)dy[1]*xd + (float)dy[-step]*(yd) + (float)dy[step]*yd;
                a += (Ix*Ix);
                b += (Iy*Iy);
                c += (Ix*Iy);
                d += Ix;
            }
        }
        if (compute_response) {
            r0[0] = (float)a;
            r0[1] = (float)b;
            r0[2] = (float)c;
            r0[3] = (float)d;
        }
        else
            pts[ptidx].response = ((float)a * b - (float)c * c -
                                   harris_k * ((float)a + b) * ((float)a + b));
    }
}
コード例 #15
0
ファイル: contrast_preserve.cpp プロジェクト: Zanion/opencv
void cv::decolor(InputArray _src, OutputArray _dst, OutputArray _color_boost)
{
    Mat I = _src.getMat();
    _dst.create(I.size(), CV_8UC1);
    Mat dst = _dst.getMat();

    _color_boost.create(I.size(), CV_8UC3);
    Mat color_boost = _color_boost.getMat();

    if(!I.data )
    {
        cout <<  "Could not open or find the image" << endl ;
        return;
    }
    if(I.channels() !=3)
    {
        cout << "Input Color Image" << endl;
        return;
    }

    // Parameter Setting
    int maxIter = 15;
    int iterCount = 0;
    double tol = .0001;
    double E = 0;
    double pre_E = std::numeric_limits<double>::infinity();

    Decolor obj;

    Mat img;

    img = Mat(I.size(),CV_32FC3);
    I.convertTo(img,CV_32FC3,1.0/255.0);

    // Initialization
    obj.init();

    vector <double> Cg;
    vector < vector <double> > polyGrad;
    vector < vector < int > > comb;

    vector <double> alf;

    obj.grad_system(img,polyGrad,Cg,comb);
    obj.weak_order(img,alf);

    // Solver
    Mat Mt = Mat(polyGrad.size(),polyGrad[0].size(), CV_32FC1);
    obj.wei_update_matrix(polyGrad,Cg,Mt);

    vector <double> wei;
    obj.wei_inti(comb,wei);

    //////////////////////////////// main loop starting ////////////////////////////////////////

    while(sqrt(pow(E-pre_E,2)) > tol)
    {
        iterCount +=1;
        pre_E = E;

        vector <double> G_pos;
        vector <double> G_neg;

        vector <double> temp;
        vector <double> temp1;

        double val = 0.0;
        for(unsigned int i=0;i< polyGrad[0].size();i++)
        {
            val = 0.0;
            for(unsigned int j =0;j<polyGrad.size();j++)
                val = val + (polyGrad[j][i] * wei[j]);
            temp.push_back(val - Cg[i]);
            temp1.push_back(val + Cg[i]);
        }

        double pos = 0.0;
        double neg = 0.0;
        for(unsigned int i =0;i<alf.size();i++)
        {
            pos = ((1 + alf[i])/2) * exp((-1.0 * 0.5 * pow(temp[i],2))/pow(obj.sigma,2));
            neg = ((1 - alf[i])/2) * exp((-1.0 * 0.5 * pow(temp1[i],2))/pow(obj.sigma,2));
            G_pos.push_back(pos);
            G_neg.push_back(neg);
        }

        vector <double> EXPsum;
        vector <double> EXPterm;

        for(unsigned int i = 0;i<G_pos.size();i++)
            EXPsum.push_back(G_pos[i]+G_neg[i]);

        vector <double> temp2;

        for(unsigned int i=0;i<EXPsum.size();i++)
        {
            if(EXPsum[i] == 0)
                temp2.push_back(1.0);
            else
                temp2.push_back(0.0);
        }

        for(unsigned int i =0; i < G_pos.size();i++)
            EXPterm.push_back((G_pos[i] - G_neg[i])/(EXPsum[i] + temp2[i]));

        double val1 = 0.0;
        vector <double> wei1;

        for(unsigned int i=0;i< polyGrad.size();i++)
        {
            val1 = 0.0;
            for(unsigned int j =0;j<polyGrad[0].size();j++)
            {
                val1 = val1 + (Mt.at<float>(i,j) * EXPterm[j]);
            }
            wei1.push_back(val1);
        }

        for(unsigned int i =0;i<wei.size();i++)
            wei[i] = wei1[i];

        E = obj.energyCalcu(Cg,polyGrad,wei);

        if(iterCount > maxIter)
            break;

        G_pos.clear();
        G_neg.clear();
        temp.clear();
        temp1.clear();
        EXPsum.clear();
        EXPterm.clear();
        temp2.clear();
        wei1.clear();
    }

    Mat Gray = Mat::zeros(img.size(),CV_32FC1);
    obj.grayImContruct(wei, img, Gray);

    Gray.convertTo(dst,CV_8UC1,255);

    ///////////////////////////////////       Contrast Boosting   /////////////////////////////////

    Mat lab = Mat(img.size(),CV_8UC3);
    Mat color = Mat(img.size(),CV_8UC3);

    cvtColor(I,lab,COLOR_BGR2Lab);

    vector <Mat> lab_channel;
    split(lab,lab_channel);

    dst.copyTo(lab_channel[0]);

    merge(lab_channel,lab);

    cvtColor(lab,color_boost,COLOR_Lab2BGR);
}
コード例 #16
0
  void cvtColorInvariants(InputArray _src, OutputArray _dst, int code, int dcn )
  {
    Mat src = _src.getMat(), dst;
    Size sz = src.size();
    int scn = src.channels(), depth = src.depth(), bidx;
    int blueIdx;

    CV_Assert( depth == CV_8U || depth == CV_16U || depth == CV_32F );

    switch(code) {
      case COLOR_INVARIANCE_PASSTHROUGH:
        dst = src;
        break;
      case COLOR_INVARIANCE_BGR2GAUSSIAN_OPPONENT:
      case COLOR_INVARIANCE_RGB2GAUSSIAN_OPPONENT:
        CV_Assert( scn == 3 || scn == 4 );
        dcn = 3;
        blueIdx = (code == COLOR_INVARIANCE_BGR2GAUSSIAN_OPPONENT) ? 0 : 2;

        _dst.create( sz, CV_MAKETYPE(depth, dcn));
        dst = _dst.getMat();

        if( depth == CV_8U )
          CvtColorLoop(src, dst, GaussianOpponent<uchar>(scn, dcn, blueIdx,256));
        else if( depth == CV_16U )
          CvtColorLoop(src, dst, GaussianOpponent<ushort>(scn, dcn, blueIdx, 2<<16 ) );
        else
          CvtColorLoop(src, dst, GaussianOpponent<float>(scn, dcn, blueIdx, 1 ));
        break;
      case COLOR_INVARIANCE_BGR2HInvariant:
        CV_Assert( scn == 3 || scn == 4 );
        dcn = 1;
        blueIdx = (code == COLOR_INVARIANCE_BGR2HInvariant) ? 0 : 2;

        _dst.create( sz, CV_MAKETYPE(depth, dcn));
        dst = _dst.getMat();

        if( depth == CV_8U )
          CvtColorLoop(src, dst, HInvariant<uchar>(scn, dcn, blueIdx, 256));
        else if( depth == CV_16U )
          CvtColorLoop(src, dst, HInvariant<ushort>(scn, dcn, blueIdx, 2<<16 ) );
        else
          CvtColorLoop(src, dst, HInvariant<float>(scn, dcn, blueIdx, 1 ));
        break;
       case COLOR_INVARIANCE_Gray2YB:
        CV_Assert( scn == 1 );
        dcn = 3;

        _dst.create( sz, CV_MAKETYPE(CV_8U, 3));
        dst = _dst.getMat();

        if( depth == CV_8U )
          CvtColorLoop(src, dst, Gray2YB<uchar>( 256 ) );
        else if( depth == CV_16U )
          CvtColorLoop(src, dst, Gray2YB<ushort>( 2<<16 ) );
        else
          CvtColorLoop(src, dst, Gray2YB<float>( 1 ) );
        break;
      case COLOR_INVARIANCE_Gray2RG:
        CV_Assert( scn == 1 );
        dcn = 3;

        _dst.create( sz, CV_MAKETYPE(CV_8U, 3));
        dst = _dst.getMat();

        if( depth == CV_8U )
          CvtColorLoop(src, dst, Gray2RG<uchar>( 256 ) );
        else if( depth == CV_16U )
          CvtColorLoop(src, dst, Gray2RG<ushort>( 2<<16 ) );
        else
          CvtColorLoop(src, dst, Gray2RG<float>( 1 ) );
        break;
      default:
        CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" );
    }

  }
コード例 #17
0
ファイル: 222.cpp プロジェクト: huihui891/LBPLine
template <typename _Tp> static
inline void ulbp_(InputArray _src, OutputArray _dst, int radius, int neighbors, vector<int> m_uniform)
{
    if (neighbors != 8 || m_uniform.size() != 58)
    {
        cout << "neighbor must be 8! and uniform size be 58!\n";
        system("pause");
        exit(-1);
    }


    //get matrices
    Mat src = _src.getMat();
    // allocate memory for result
    _dst.create(src.rows-2*radius, src.cols-2*radius, CV_32SC1);
    Mat dst = _dst.getMat();
    // zero
    dst.setTo(0);
    for(int n=0; n<neighbors; n++)
    {
        // sample points
        float x = static_cast<float>(-radius) * sin(2.0*CV_PI*n/static_cast<float>(neighbors));
        float y = static_cast<float>(radius) * cos(2.0*CV_PI*n/static_cast<float>(neighbors));
        // relative indices
        int fx = static_cast<int>(floor(x));
        int fy = static_cast<int>(floor(y));
        int cx = static_cast<int>(ceil(x));
        int cy = static_cast<int>(ceil(y));
        // fractional part
        float ty = y - fy;
        float tx = x - fx;
        // set interpolation weights
        float w1 = (1 - tx) * (1 - ty);
        float w2 =      tx  * (1 - ty);
        float w3 = (1 - tx) *      ty;
        float w4 =      tx  *      ty;
        // iterate through your data
        for(int i=radius; i < src.rows-radius; i++) {
            for(int j=radius; j < src.cols-radius; j++) {
                // calculate interpolated value
                float t = w1*src.at<_Tp>(i+fy,j+fx) + w2*src.at<_Tp>(i+fy,j+cx) + w3*src.at<_Tp>(i+cy,j+fx) + w4*src.at<_Tp>(i+cy,j+cx);
                // floating point precision, so check some machine-dependent epsilon
                dst.at<int>(i-radius,j-radius) += ((t > src.at<_Tp>(i,j)) ||
                                                   (std::abs(t-src.at<_Tp>(i,j)) < std::numeric_limits<float>::epsilon()))
                                                  << n;
            }
        }
    }


    for (int i = 0; i < dst.rows; ++i)
    {
        for (int j = 0; j < dst.cols; ++j)
        {
            int data = dst.at<int>(i, j);
            vector<int>::iterator iter = find(m_uniform.begin(), m_uniform.end(), data);
            if (iter == m_uniform.end())
            {
                dst.at<int>(i, j) = 0;
            }
            else
            {
                int new_data = iter - m_uniform.begin() ;
                dst.at<int>(i, j) = new_data + 1;
            }
        }
    }
}
コード例 #18
0
ファイル: em.cpp プロジェクト: 007Indian/opencv
    bool doTrain(int startStep, OutputArray logLikelihoods, OutputArray labels, OutputArray probs)
    {
        int dim = trainSamples.cols;
        // Precompute the empty initial train data in the cases of START_E_STEP and START_AUTO_STEP
        if(startStep != START_M_STEP)
        {
            if(covs.empty())
            {
                CV_Assert(weights.empty());
                clusterTrainSamples();
            }
        }

        if(!covs.empty() && covsEigenValues.empty() )
        {
            CV_Assert(invCovsEigenValues.empty());
            decomposeCovs();
        }

        if(startStep == START_M_STEP)
            mStep();

        double trainLogLikelihood, prevTrainLogLikelihood = 0.;
        int maxIters = (termCrit.type & TermCriteria::MAX_ITER) ?
            termCrit.maxCount : DEFAULT_MAX_ITERS;
        double epsilon = (termCrit.type & TermCriteria::EPS) ? termCrit.epsilon : 0.;

        for(int iter = 0; ; iter++)
        {
            eStep();
            trainLogLikelihood = sum(trainLogLikelihoods)[0];

            if(iter >= maxIters - 1)
                break;

            double trainLogLikelihoodDelta = trainLogLikelihood - prevTrainLogLikelihood;
            if( iter != 0 &&
                (trainLogLikelihoodDelta < -DBL_EPSILON ||
                 trainLogLikelihoodDelta < epsilon * std::fabs(trainLogLikelihood)))
                break;

            mStep();

            prevTrainLogLikelihood = trainLogLikelihood;
        }

        if( trainLogLikelihood <= -DBL_MAX/10000. )
        {
            clear();
            return false;
        }

        // postprocess covs
        covs.resize(nclusters);
        for(int clusterIndex = 0; clusterIndex < nclusters; clusterIndex++)
        {
            if(covMatType == COV_MAT_SPHERICAL)
            {
                covs[clusterIndex].create(dim, dim, CV_64FC1);
                setIdentity(covs[clusterIndex], Scalar(covsEigenValues[clusterIndex].at<double>(0)));
            }
            else if(covMatType == COV_MAT_DIAGONAL)
            {
                covs[clusterIndex] = Mat::diag(covsEigenValues[clusterIndex]);
            }
        }

        if(labels.needed())
            trainLabels.copyTo(labels);
        if(probs.needed())
            trainProbs.copyTo(probs);
        if(logLikelihoods.needed())
            trainLogLikelihoods.copyTo(logLikelihoods);

        trainSamples.release();
        trainProbs.release();
        trainLabels.release();
        trainLogLikelihoods.release();

        return true;
    }
コード例 #19
0
    void FeatureShiCorner::computeRawCornerMat( InputArray _image, OutputArray _corner )
    {
        // TODO check: _corner must be CV_32SC1

        const Mat image  = _image.getMat();
        const int height = image.rows;
        const int width  = image.cols;
        const int radius = 1;
        Mat derX( height, width, CV_32SC1, Scalar( 0 ) );
        Mat derY( height, width, CV_32SC1, Scalar( 0 ) );
        Mat Mx2( height, width, CV_32SC1, Scalar( 0 ) );
        Mat My2( height, width, CV_32SC1, Scalar( 0 ) );
        Mat Mxy( height, width, CV_32SC1, Scalar( 0 ) );


        applyFilter< uchar, int32_t >( _image, derX, &filter_derX[0][0], 3, 1, 0, true );
        applyFilter< uchar, int32_t >( _image, derY, &filter_derY[0][0], 1, 3, 0, true );


        int normDivisor     = 0;
        const int * pGauss  = &FeatureShiCorner::filter_gauss[0][0];
        int const * pGaussE = pGauss + 9;
        for(; pGauss != pGaussE; pGauss++ )
        {
            normDivisor += abs( *pGauss );
        }

        int32_t maxVal = 0;
        for( int y = 0; y < height; y++ )
        {
            for( int x = 0; x < width; x++ )
            {
                for( int dy = -radius; dy <= radius; dy++ )
                {
                    for( int dx = -radius; dx <= radius; dx++ )
                    {
                        int fx = x + dx;
                        if( (fx < 0) || (fx >= width) ) { continue; }
                        int fy = y + dy;
                        if( (fy < 0) || (fy >= height) ) { continue; }

                        int f = FeatureShiCorner::filter_gauss[(radius + dx)][(radius + dy)];

                        Mx2.at< int32_t >( y, x ) += int32_t( f * pow( derX.at< int32_t >( fy, fx ), 2 ) );
                        My2.at< int32_t >( y, x ) += int32_t( f * pow( derY.at< int32_t >( fy, fx ), 2 ) );
                        Mxy.at< int32_t >( y, x ) += int32_t( f * derX.at< int32_t >( fy, fx ) * derY.at< int >( fy, fx ) );
                    }
                }

                Mx2.at< int32_t >( y, x ) /= normDivisor;
                My2.at< int32_t >( y, x ) /= normDivisor;
                Mxy.at< int32_t >( y, x ) /= normDivisor;
                maxVal = max( Mx2.at< int32_t >( y, x ), maxVal );
                maxVal = max( My2.at< int32_t >( y, x ), maxVal );
                maxVal = max( Mxy.at< int32_t >( y, x ), maxVal );
            }
        }

        Mat corners      = _corner.getMat();
        const auto it_cE = corners.end< int32_t >();
        auto it_cS       = corners.begin< int32_t >();
        auto it_Mx2S     = Mx2.begin< int32_t >();
        auto it_My2S     = My2.begin< int32_t >();
        auto it_MxyS     = Mxy.begin< int32_t >();

        // reduce to high values if necessary
        // maxval: 0..1 * 255^2, maxval^2 should not overflow for the next step
        // reduce to sqrt( 2^31-1 (signed int)  ) -> 46340
        const int maxValC = 46340;
        if( maxVal > maxValC )
        {
            cout << "maxVal > maxValC | maxVal: " << maxVal << endl;

            const double scaleFac = maxValC / (double) maxVal; // scaleFac = 0.xxxx

            while( it_cS != it_cE )
            {
                *it_cS   *= int32_t( scaleFac );
                *it_Mx2S *= int32_t( scaleFac );
                *it_My2S *= int32_t( scaleFac );
                *it_MxyS *= int32_t( scaleFac );

                it_cS++;
                it_Mx2S++;
                it_My2S++;
                it_MxyS++;
            }

            // reset iterators
            it_cS   = corners.begin< int32_t >();
            it_Mx2S = Mx2.begin< int32_t >();
            it_My2S = My2.begin< int32_t >();
            it_MxyS = Mxy.begin< int32_t >();
        }

        maxVal = 0;

        // calc eigenvalues
        int32_t trc, det;
        double ev_sqrt, trc_halve, eigVal1, eigVal2;
        while( it_cS != it_cE )
        {
            trc = *it_Mx2S + *it_My2S;
            det = *it_Mx2S * *it_My2S - *it_MxyS * *it_MxyS;

            ev_sqrt   = sqrt( ( (trc * trc) / 4 ) - det );
            trc_halve = trc / 2.0;

            eigVal1 = trc_halve + ev_sqrt;
            eigVal2 = trc_halve - ev_sqrt;

            if( (eigVal1 < 0) || (eigVal2 < 0) )
            {
                eigVal1 = 0;
                eigVal2 = 0;
            }

            *it_cS = (int32_t) min( eigVal1, eigVal2 );
            maxVal = max( (int32_t) min( eigVal1, eigVal2 ), maxVal );

            it_cS++;
            it_Mx2S++;
            it_My2S++;
            it_MxyS++;
        }

        // *
        if( maxVal != 0 )
        {
            const double threshold = maxVal * 0.2;
            for( auto it_cE = corners.end< int32_t >(), it_cS = corners.begin< int32_t >(); it_cS != it_cE; it_cS++ )
            {
                if( *it_cS < threshold ) { *it_cS = 0; }
            }
        }
        // */

        // *
        Mat cornersFiltered( height, width, CV_32SC1 );
        maxFilter< int32_t >( corners, cornersFiltered, 5, 5 );
        // */

        if( isDebugMode )
        {
            Mat derXd, derYd, cornersd;
            cornersFiltered.convertTo( cornersd, CV_8UC1 );
            derX.convertTo( derXd, CV_8UC1 );
            derY.convertTo( derYd, CV_8UC1 );

            // Display corners over the image (cross)
            Mat cornersdc = image.clone();

            auto cornerPoints = genPoints( cornersFiltered );

            for( auto p : cornerPoints )
            {
                for( int dx = -2; dx <= 2; dx++ )
                {
                    int x = p.first + dx;
                    int y = p.second;
                    if( ( x < 0) || ( x >= width) ) { continue; }
                    cornersdc.at< uchar >( y, x ) = 0;
                }

                for( int dy = -2; dy <= 2; dy++ )
                {
                    int x = p.first;
                    int y = p.second + dy;
                    if( ( y < 0) || ( y >= height) ) { continue; }

                    cornersdc.at< uchar >( y, x ) = 0;
                }
            }

            imshow( "image", image );
            imshow( "derX", derXd );
            imshow( "derY", derYd );
            imshow( "Shi Corner", cornersd );
            imshow( "Shi Corner Image", cornersdc );

            waitKey( 0 );
            destroyAllWindows();
            waitKey( 1 );
        }
    }
コード例 #20
0
void cv::solvePnPRansac(InputArray _opoints, InputArray _ipoints,
                        InputArray _cameraMatrix, InputArray _distCoeffs,
                        OutputArray _rvec, OutputArray _tvec, bool useExtrinsicGuess,
                        int iterationsCount, float reprojectionError, int minInliersCount,
                        OutputArray _inliers, int flags)
{
    Mat opoints = _opoints.getMat(), ipoints = _ipoints.getMat();
    Mat cameraMatrix = _cameraMatrix.getMat(), distCoeffs = _distCoeffs.getMat();
    
    CV_Assert(opoints.isContinuous());
    CV_Assert(opoints.depth() == CV_32F);
    CV_Assert((opoints.rows == 1 && opoints.channels() == 3) || opoints.cols*opoints.channels() == 3);
    CV_Assert(ipoints.isContinuous());
    CV_Assert(ipoints.depth() == CV_32F);
    CV_Assert((ipoints.rows == 1 && ipoints.channels() == 2) || ipoints.cols*ipoints.channels() == 2);
    
    _rvec.create(3, 1, CV_64FC1);
    _tvec.create(3, 1, CV_64FC1);
    Mat rvec = _rvec.getMat();
    Mat tvec = _tvec.getMat();
    
    Mat objectPoints = opoints.reshape(3, 1), imagePoints = ipoints.reshape(2, 1);
    
    if (minInliersCount <= 0)
        minInliersCount = objectPoints.cols;
    cv::pnpransac::Parameters params;
    params.iterationsCount = iterationsCount;
    params.minInliersCount = minInliersCount;
    params.reprojectionError = reprojectionError;
    params.useExtrinsicGuess = useExtrinsicGuess;
    params.camera.init(cameraMatrix, distCoeffs);
	params.flags = flags;
    
    vector<int> localInliers;
    Mat localRvec, localTvec;
    rvec.copyTo(localRvec);
    tvec.copyTo(localTvec);
    
    if (objectPoints.cols >= pnpransac::MIN_POINTS_COUNT)
    {
        parallel_for(BlockedRange(0,iterationsCount), cv::pnpransac::PnPSolver(objectPoints, imagePoints, params,
                                                                               localRvec, localTvec, localInliers));
    }
    
    if (localInliers.size() >= (size_t)pnpransac::MIN_POINTS_COUNT)
    {
		if (flags != CV_P3P)
		{
			int i, pointsCount = (int)localInliers.size();
			Mat inlierObjectPoints(1, pointsCount, CV_32FC3), inlierImagePoints(1, pointsCount, CV_32FC2);
			for (i = 0; i < pointsCount; i++)
			{
				int index = localInliers[i];
				Mat colInlierImagePoints = inlierImagePoints(Rect(i, 0, 1, 1));
				imagePoints.col(index).copyTo(colInlierImagePoints);
				Mat colInlierObjectPoints = inlierObjectPoints(Rect(i, 0, 1, 1));
				objectPoints.col(index).copyTo(colInlierObjectPoints);
			}
			solvePnP(inlierObjectPoints, inlierImagePoints, params.camera.intrinsics, params.camera.distortion, localRvec, localTvec, true, flags);
		}
		localRvec.copyTo(rvec);
        localTvec.copyTo(tvec);
        if (_inliers.needed())
            Mat(localInliers).copyTo(_inliers);
    }
    else
    {
        tvec.setTo(Scalar(0));
        Mat R = Mat::eye(3, 3, CV_64F);
        Rodrigues(R, rvec);
        if( _inliers.needed() )
            _inliers.release();
    }
    return;
}
コード例 #21
0
bool GrayCodePattern_Impl::decode( InputArrayOfArrays patternImages, OutputArray disparityMap,
                                   InputArrayOfArrays blackImages, InputArrayOfArrays whitheImages, int flags ) const
{
  std::vector<std::vector<Mat> >& acquired_pattern = *( std::vector<std::vector<Mat> >* ) patternImages.getObj();

  if( flags == DECODE_3D_UNDERWORLD )
  {
    // Computing shadows mask
    std::vector<Mat> shadowMasks;
    computeShadowMasks( blackImages, whitheImages, shadowMasks );

    int cam_width = acquired_pattern[0][0].cols;
    int cam_height = acquired_pattern[0][0].rows;

    Point projPixel;

    // Storage for the pixels of the two cams that correspond to the same pixel of the projector
    std::vector<std::vector<std::vector<Point> > > camsPixels;
    camsPixels.resize( acquired_pattern.size() );

    // TODO: parallelize for (k and j)
    for( size_t k = 0; k < acquired_pattern.size(); k++ )
    {
      camsPixels[k].resize( params.height * params.width );
      for( int i = 0; i < cam_width; i++ )
      {
        for( int j = 0; j < cam_height; j++ )
        {
          //if the pixel is not shadowed, reconstruct
          if( shadowMasks[k].at<uchar>( j, i ) )
          {
            //for a (x,y) pixel of the camera returns the corresponding projector pixel by calculating the decimal number
            bool error = getProjPixel( acquired_pattern[k], i, j, projPixel );

            if( error )
            {
              continue;
            }

            camsPixels[k][projPixel.x * params.height + projPixel.y].push_back( Point( i, j ) );
          }
        }
      }
    }

    std::vector<Point> cam1Pixs, cam2Pixs;

    Mat& disparityMap_ = *( Mat* ) disparityMap.getObj();
    disparityMap_ = Mat( cam_height, cam_width, CV_64F, double( 0 ) );

    double number_of_pixels_cam1 = 0;
    double number_of_pixels_cam2 = 0;

    for( int i = 0; i < params.width; i++ )
    {
      for( int j = 0; j < params.height; j++ )
      {
        cam1Pixs = camsPixels[0][i * params.height + j];
        cam2Pixs = camsPixels[1][i * params.height + j];

        if( cam1Pixs.size() == 0 || cam2Pixs.size() == 0 )
          continue;

        Point p1;
        Point p2;

        double sump1x = 0;
        double sump2x = 0;

        number_of_pixels_cam1 += cam1Pixs.size();
        number_of_pixels_cam2 += cam2Pixs.size();
        for( int c1 = 0; c1 < (int) cam1Pixs.size(); c1++ )
        {
          p1 = cam1Pixs[c1];
          sump1x += p1.x;
        }
        for( int c2 = 0; c2 < (int) cam2Pixs.size(); c2++ )
        {
          p2 = cam2Pixs[c2];
          sump2x += p2.x;
        }

        sump2x /= cam2Pixs.size();
        sump1x /= cam1Pixs.size();
        for( int c1 = 0; c1 < (int) cam1Pixs.size(); c1++ )
        {
          p1 = cam1Pixs[c1];
          disparityMap_.at<double>( p1.y, p1.x ) = ( double ) (sump2x - sump1x);
        }

        sump2x = 0;
        sump1x = 0;
      }
    }

    return true;
  }  // end if flags

  return false;
}
コード例 #22
0
ファイル: deriv.cpp プロジェクト: 165-goethals/opencv
static bool ocl_Laplacian5(InputArray _src, OutputArray _dst,
                           const Mat & kd, const Mat & ks, double scale, double delta,
                           int borderType, int depth, int ddepth)
{
    const size_t tileSizeX = 16;
    const size_t tileSizeYmin = 8;

    const ocl::Device dev = ocl::Device::getDefault();

    int stype = _src.type();
    int sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype), esz = CV_ELEM_SIZE(stype);

    bool doubleSupport = dev.doubleFPConfig() > 0;
    if (!doubleSupport && (sdepth == CV_64F || ddepth == CV_64F))
        return false;

    Mat kernelX = kd.reshape(1, 1);
    if (kernelX.cols % 2 != 1)
        return false;
    Mat kernelY = ks.reshape(1, 1);
    if (kernelY.cols % 2 != 1)
        return false;
    CV_Assert(kernelX.cols == kernelY.cols);

    size_t wgs = dev.maxWorkGroupSize();
    size_t lmsz = dev.localMemSize();
    size_t src_step = _src.step(), src_offset = _src.offset();
    const size_t tileSizeYmax = wgs / tileSizeX;

    // workaround for Nvidia: 3 channel vector type takes 4*elem_size in local memory
    int loc_mem_cn = dev.vendorID() == ocl::Device::VENDOR_NVIDIA && cn == 3 ? 4 : cn;

    if (((src_offset % src_step) % esz == 0) &&
        (
         (borderType == BORDER_CONSTANT || borderType == BORDER_REPLICATE) ||
         ((borderType == BORDER_REFLECT || borderType == BORDER_WRAP || borderType == BORDER_REFLECT_101) &&
          (_src.cols() >= (int) (kernelX.cols + tileSizeX) && _src.rows() >= (int) (kernelY.cols + tileSizeYmax)))
        ) &&
        (tileSizeX * tileSizeYmin <= wgs) &&
        (LAPLACIAN_LOCAL_MEM(tileSizeX, tileSizeYmin, kernelX.cols, loc_mem_cn * 4) <= lmsz)
       )
    {
        Size size = _src.size(), wholeSize;
        Point origin;
        int dtype = CV_MAKE_TYPE(ddepth, cn);
        int wdepth = CV_32F;

        size_t tileSizeY = tileSizeYmax;
        while ((tileSizeX * tileSizeY > wgs) || (LAPLACIAN_LOCAL_MEM(tileSizeX, tileSizeY, kernelX.cols, loc_mem_cn * 4) > lmsz))
        {
            tileSizeY /= 2;
        }
        size_t lt2[2] = { tileSizeX, tileSizeY};
        size_t gt2[2] = { lt2[0] * (1 + (size.width - 1) / lt2[0]), lt2[1] };

        char cvt[2][40];
        const char * const borderMap[] = { "BORDER_CONSTANT", "BORDER_REPLICATE", "BORDER_REFLECT", "BORDER_WRAP",
                                           "BORDER_REFLECT_101" };

        String opts = cv::format("-D BLK_X=%d -D BLK_Y=%d -D RADIUS=%d%s%s"
                                 " -D convertToWT=%s -D convertToDT=%s"
                                 " -D %s -D srcT1=%s -D dstT1=%s -D WT1=%s"
                                 " -D srcT=%s -D dstT=%s -D WT=%s"
                                 " -D CN=%d ",
                                 (int)lt2[0], (int)lt2[1], kernelX.cols / 2,
                                 ocl::kernelToStr(kernelX, wdepth, "KERNEL_MATRIX_X").c_str(),
                                 ocl::kernelToStr(kernelY, wdepth, "KERNEL_MATRIX_Y").c_str(),
                                 ocl::convertTypeStr(sdepth, wdepth, cn, cvt[0]),
                                 ocl::convertTypeStr(wdepth, ddepth, cn, cvt[1]),
                                 borderMap[borderType],
                                 ocl::typeToStr(sdepth), ocl::typeToStr(ddepth), ocl::typeToStr(wdepth),
                                 ocl::typeToStr(CV_MAKETYPE(sdepth, cn)),
                                 ocl::typeToStr(CV_MAKETYPE(ddepth, cn)),
                                 ocl::typeToStr(CV_MAKETYPE(wdepth, cn)),
                                 cn);

        ocl::Kernel k("laplacian", ocl::imgproc::laplacian5_oclsrc, opts);
        if (k.empty())
            return false;
        UMat src = _src.getUMat();
        _dst.create(size, dtype);
        UMat dst = _dst.getUMat();

        int src_offset_x = static_cast<int>((src_offset % src_step) / esz);
        int src_offset_y = static_cast<int>(src_offset / src_step);

        src.locateROI(wholeSize, origin);

        k.args(ocl::KernelArg::PtrReadOnly(src), (int)src_step, src_offset_x, src_offset_y,
               wholeSize.height, wholeSize.width, ocl::KernelArg::WriteOnly(dst),
               static_cast<float>(scale), static_cast<float>(delta));

        return k.run(2, gt2, lt2, false);
    }
    int iscale = cvRound(scale), idelta = cvRound(delta);
    bool floatCoeff = std::fabs(delta - idelta) > DBL_EPSILON || std::fabs(scale - iscale) > DBL_EPSILON;
    int wdepth = std::max(depth, floatCoeff ? CV_32F : CV_32S), kercn = 1;

    if (!doubleSupport && wdepth == CV_64F)
        return false;

    char cvt[2][40];
    ocl::Kernel k("sumConvert", ocl::imgproc::laplacian5_oclsrc,
                  format("-D ONLY_SUM_CONVERT "
                         "-D srcT=%s -D WT=%s -D dstT=%s -D coeffT=%s -D wdepth=%d "
                         "-D convertToWT=%s -D convertToDT=%s%s",
                         ocl::typeToStr(CV_MAKE_TYPE(depth, kercn)),
                         ocl::typeToStr(CV_MAKE_TYPE(wdepth, kercn)),
                         ocl::typeToStr(CV_MAKE_TYPE(ddepth, kercn)),
                         ocl::typeToStr(wdepth), wdepth,
                         ocl::convertTypeStr(depth, wdepth, kercn, cvt[0]),
                         ocl::convertTypeStr(wdepth, ddepth, kercn, cvt[1]),
                         doubleSupport ? " -D DOUBLE_SUPPORT" : ""));
    if (k.empty())
        return false;

    UMat d2x, d2y;
    sepFilter2D(_src, d2x, depth, kd, ks, Point(-1, -1), 0, borderType);
    sepFilter2D(_src, d2y, depth, ks, kd, Point(-1, -1), 0, borderType);

    UMat dst = _dst.getUMat();

    ocl::KernelArg d2xarg = ocl::KernelArg::ReadOnlyNoSize(d2x),
            d2yarg = ocl::KernelArg::ReadOnlyNoSize(d2y),
            dstarg = ocl::KernelArg::WriteOnly(dst, cn, kercn);

    if (wdepth >= CV_32F)
        k.args(d2xarg, d2yarg, dstarg, (float)scale, (float)delta);
    else
        k.args(d2xarg, d2yarg, dstarg, iscale, idelta);

    size_t globalsize[] = { dst.cols * cn / kercn, dst.rows };
    return k.run(2, globalsize, NULL, false);
}
コード例 #23
0
ファイル: FGExtraction.cpp プロジェクト: Kitware/VIAME
/*******************************************************************************
* Function:      subtractBGOpenDiagonal  
* Description:   BG subtraction via opening with diagonal structuring elements
* Arguments:
	inImg           -   input image
	bgsImg          -   BG subtracted image
	threshVal       -   threshold value for converting to binary image
	seLength        -   length of structuring elements
	
* Returns:       void
* Comments:
* Revision: 
*******************************************************************************/
int
FGExtraction::subtractBGOpenDiagonal(InputArray src, OutputArray dst, int threshVal, int seLength)
{
    // generate binary image by thresholding
	Mat bin;
	double thresh = threshold(src, bin, threshVal, 255, THRESH_BINARY);

	// opening by horizontal structuring element
	//Mat structElemHorizontal = Mat::ones(1, seLength, CV_8U);
	//morphologyEx(bin, dst, MORPH_OPEN, structElemHorizontal);

	// opening by vertical structuring element
	//Mat structElemVertical = Mat::ones(seLength, 1, CV_8U);
	//morphologyEx(dst, dst, MORPH_OPEN, structElemVertical);

	//imshow("src", src);
	//imshow("bin", bin);
	//waitKey(0);

    // opening by first diagonal structuring element
	Mat structElemBackSlash = Mat::eye(seLength, seLength, CV_8U);
	morphologyEx(bin, dst, MORPH_OPEN, structElemBackSlash);

	//imshow("dst1", dst);
	//waitKey(0);

    // opening by second diagonal structuring element
	Mat structElemSlash;
	flip(structElemBackSlash, structElemSlash, 0);
	morphologyEx(dst, dst, MORPH_OPEN, structElemSlash);

	//imshow("dst2", dst);
	//waitKey(0);

	// eliminate small noise
	Mat structElemEllip = getStructuringElement(MORPH_ELLIPSE, Size(seLength, seLength));
	morphologyEx(dst, dst, MORPH_OPEN, structElemEllip);

	//imshow("dst3", dst);
	//waitKey(0);


	// get object size
	Mat dstImg = dst.getMat();
	vector<vector<Point>> contours = extractContours(dstImg);
	if (contours.size()==0)
		return 1;

    Mat mask = Mat::zeros(_bgsImg.size(), CV_8U); 
	vector<int> areas(contours.size());
	int cnt = 0;
	int argMax = 0;
	int max_area = 0;
    for(vector<vector<Point> >::const_iterator it = contours.begin(); it != contours.end(); ++it){
        Rect uprightBox = boundingRect(*it);
		areas[cnt] = uprightBox.height*uprightBox.width;
		if (areas[cnt]>max_area) {
			max_area = areas[cnt];
			argMax = cnt;
		}
		cnt++;
	}
	vector<Point> largestContour = contours[argMax];	//***** only use the largest contour
	RotatedRect orientedBox = orientedBoundingBox(largestContour);

	int updateSeL = int(min(orientedBox.size.width, orientedBox.size.height)/5.0+0.5);

	// opening by first diagonal structuring element
	structElemBackSlash = Mat::eye(updateSeL, updateSeL, CV_8U);
	morphologyEx(bin, dst, MORPH_OPEN, structElemBackSlash);
	
	//imshow("dst1", dst);
	//waitKey(0);

    // opening by second diagonal structuring element
	flip(structElemBackSlash, structElemSlash, 0);
	morphologyEx(dst, dst, MORPH_OPEN, structElemSlash);

	//imshow("dst2", dst);
	//waitKey(0);

	// eliminate small noise
	structElemEllip = getStructuringElement(MORPH_ELLIPSE, Size(updateSeL, updateSeL));
	morphologyEx(dst, dst, MORPH_OPEN, structElemEllip);

	//imshow("dst3", dst);
	//waitKey(0);
	return 0;
}
コード例 #24
0
ファイル: deriv.cpp プロジェクト: 165-goethals/opencv
void cv::Laplacian( InputArray _src, OutputArray _dst, int ddepth, int ksize,
                    double scale, double delta, int borderType )
{
    int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype);
    if (ddepth < 0)
        ddepth = sdepth;
    _dst.create( _src.size(), CV_MAKETYPE(ddepth, cn) );

#ifdef HAVE_IPP
    CV_IPP_CHECK()
    {
        if ((ksize == 3 || ksize == 5) && ((borderType & BORDER_ISOLATED) != 0 || !_src.isSubmatrix()) &&
            ((stype == CV_8UC1 && ddepth == CV_16S) || (ddepth == CV_32F && stype == CV_32FC1)) && !ocl::useOpenCL())
        {
            int iscale = saturate_cast<int>(scale), idelta = saturate_cast<int>(delta);
            bool floatScale = std::fabs(scale - iscale) > DBL_EPSILON, needScale = iscale != 1;
            bool floatDelta = std::fabs(delta - idelta) > DBL_EPSILON, needDelta = delta != 0;
            int borderTypeNI = borderType & ~BORDER_ISOLATED;
            Mat src = _src.getMat(), dst = _dst.getMat();

            if (src.data != dst.data)
            {
                Ipp32s bufsize;
                IppStatus status = (IppStatus)-1;
                IppiSize roisize = { src.cols, src.rows };
                IppiMaskSize masksize = ksize == 3 ? ippMskSize3x3 : ippMskSize5x5;
                IppiBorderType borderTypeIpp = ippiGetBorderType(borderTypeNI);

#define IPP_FILTER_LAPLACIAN(ippsrctype, ippdsttype, ippfavor) \
        do \
        { \
            if (borderTypeIpp >= 0 && ippiFilterLaplacianGetBufferSize_##ippfavor##_C1R(roisize, masksize, &bufsize) >= 0) \
            { \
                Ipp8u * buffer = ippsMalloc_8u(bufsize); \
                status = ippiFilterLaplacianBorder_##ippfavor##_C1R(src.ptr<ippsrctype>(), (int)src.step, dst.ptr<ippdsttype>(), \
                                                                    (int)dst.step, roisize, masksize, borderTypeIpp, 0, buffer); \
                ippsFree(buffer); \
            } \
        } while ((void)0, 0)

                CV_SUPPRESS_DEPRECATED_START
                if (sdepth == CV_8U && ddepth == CV_16S && !floatScale && !floatDelta)
                {
                    IPP_FILTER_LAPLACIAN(Ipp8u, Ipp16s, 8u16s);

                    if (needScale && status >= 0)
                        status = ippiMulC_16s_C1IRSfs((Ipp16s)iscale, dst.ptr<Ipp16s>(), (int)dst.step, roisize, 0);
                    if (needDelta && status >= 0)
                        status = ippiAddC_16s_C1IRSfs((Ipp16s)idelta, dst.ptr<Ipp16s>(), (int)dst.step, roisize, 0);
                }
                else if (sdepth == CV_32F && ddepth == CV_32F)
                {
                    IPP_FILTER_LAPLACIAN(Ipp32f, Ipp32f, 32f);

                    if (needScale && status >= 0)
                        status = ippiMulC_32f_C1IR((Ipp32f)scale, dst.ptr<Ipp32f>(), (int)dst.step, roisize);
                    if (needDelta && status >= 0)
                        status = ippiAddC_32f_C1IR((Ipp32f)delta, dst.ptr<Ipp32f>(), (int)dst.step, roisize);
                }
                CV_SUPPRESS_DEPRECATED_END

                if (status >= 0)
                {
                    CV_IMPL_ADD(CV_IMPL_IPP);
                    return;
                }
                setIppErrorStatus();
            }
        }
コード例 #25
0
ファイル: phasecorr.cpp プロジェクト: maaskola/opencv
static void divSpectrums( InputArray _srcA, InputArray _srcB, OutputArray _dst, int flags, bool conjB)
{
    Mat srcA = _srcA.getMat(), srcB = _srcB.getMat();
    int depth = srcA.depth(), cn = srcA.channels(), type = srcA.type();
    int rows = srcA.rows, cols = srcA.cols;
    int j, k;

    CV_Assert( type == srcB.type() && srcA.size() == srcB.size() );
    CV_Assert( type == CV_32FC1 || type == CV_32FC2 || type == CV_64FC1 || type == CV_64FC2 );

    _dst.create( srcA.rows, srcA.cols, type );
    Mat dst = _dst.getMat();

    bool is_1d = (flags & DFT_ROWS) || (rows == 1 || (cols == 1 &&
             srcA.isContinuous() && srcB.isContinuous() && dst.isContinuous()));

    if( is_1d && !(flags & DFT_ROWS) )
        cols = cols + rows - 1, rows = 1;

    int ncols = cols*cn;
    int j0 = cn == 1;
    int j1 = ncols - (cols % 2 == 0 && cn == 1);

    if( depth == CV_32F )
    {
        const float* dataA = srcA.ptr<float>();
        const float* dataB = srcB.ptr<float>();
        float* dataC = dst.ptr<float>();
        float eps = FLT_EPSILON; // prevent div0 problems

        size_t stepA = srcA.step/sizeof(dataA[0]);
        size_t stepB = srcB.step/sizeof(dataB[0]);
        size_t stepC = dst.step/sizeof(dataC[0]);

        if( !is_1d && cn == 1 )
        {
            for( k = 0; k < (cols % 2 ? 1 : 2); k++ )
            {
                if( k == 1 )
                    dataA += cols - 1, dataB += cols - 1, dataC += cols - 1;
                dataC[0] = dataA[0] / (dataB[0] + eps);
                if( rows % 2 == 0 )
                    dataC[(rows-1)*stepC] = dataA[(rows-1)*stepA] / (dataB[(rows-1)*stepB] + eps);
                if( !conjB )
                    for( j = 1; j <= rows - 2; j += 2 )
                    {
                        double denom = (double)dataB[j*stepB]*dataB[j*stepB] +
                                       (double)dataB[(j+1)*stepB]*dataB[(j+1)*stepB] + (double)eps;

                        double re = (double)dataA[j*stepA]*dataB[j*stepB] +
                                    (double)dataA[(j+1)*stepA]*dataB[(j+1)*stepB];

                        double im = (double)dataA[(j+1)*stepA]*dataB[j*stepB] -
                                    (double)dataA[j*stepA]*dataB[(j+1)*stepB];

                        dataC[j*stepC] = (float)(re / denom);
                        dataC[(j+1)*stepC] = (float)(im / denom);
                    }
                else
                    for( j = 1; j <= rows - 2; j += 2 )
                    {

                        double denom = (double)dataB[j*stepB]*dataB[j*stepB] +
                                       (double)dataB[(j+1)*stepB]*dataB[(j+1)*stepB] + (double)eps;

                        double re = (double)dataA[j*stepA]*dataB[j*stepB] -
                                    (double)dataA[(j+1)*stepA]*dataB[(j+1)*stepB];

                        double im = (double)dataA[(j+1)*stepA]*dataB[j*stepB] +
                                    (double)dataA[j*stepA]*dataB[(j+1)*stepB];

                        dataC[j*stepC] = (float)(re / denom);
                        dataC[(j+1)*stepC] = (float)(im / denom);
                    }
                if( k == 1 )
                    dataA -= cols - 1, dataB -= cols - 1, dataC -= cols - 1;
            }
        }

        for( ; rows--; dataA += stepA, dataB += stepB, dataC += stepC )
        {
            if( is_1d && cn == 1 )
            {
                dataC[0] = dataA[0] / (dataB[0] + eps);
                if( cols % 2 == 0 )
                    dataC[j1] = dataA[j1] / (dataB[j1] + eps);
            }

            if( !conjB )
                for( j = j0; j < j1; j += 2 )
                {
                    double denom = (double)(dataB[j]*dataB[j] + dataB[j+1]*dataB[j+1] + eps);
                    double re = (double)(dataA[j]*dataB[j] + dataA[j+1]*dataB[j+1]);
                    double im = (double)(dataA[j+1]*dataB[j] - dataA[j]*dataB[j+1]);
                    dataC[j] = (float)(re / denom);
                    dataC[j+1] = (float)(im / denom);
                }
            else
                for( j = j0; j < j1; j += 2 )
                {
                    double denom = (double)(dataB[j]*dataB[j] + dataB[j+1]*dataB[j+1] + eps);
                    double re = (double)(dataA[j]*dataB[j] - dataA[j+1]*dataB[j+1]);
                    double im = (double)(dataA[j+1]*dataB[j] + dataA[j]*dataB[j+1]);
                    dataC[j] = (float)(re / denom);
                    dataC[j+1] = (float)(im / denom);
                }
        }
    }
    else
    {
        const double* dataA = srcA.ptr<double>();
        const double* dataB = srcB.ptr<double>();
        double* dataC = dst.ptr<double>();
        double eps = DBL_EPSILON; // prevent div0 problems

        size_t stepA = srcA.step/sizeof(dataA[0]);
        size_t stepB = srcB.step/sizeof(dataB[0]);
        size_t stepC = dst.step/sizeof(dataC[0]);

        if( !is_1d && cn == 1 )
        {
            for( k = 0; k < (cols % 2 ? 1 : 2); k++ )
            {
                if( k == 1 )
                    dataA += cols - 1, dataB += cols - 1, dataC += cols - 1;
                dataC[0] = dataA[0] / (dataB[0] + eps);
                if( rows % 2 == 0 )
                    dataC[(rows-1)*stepC] = dataA[(rows-1)*stepA] / (dataB[(rows-1)*stepB] + eps);
                if( !conjB )
                    for( j = 1; j <= rows - 2; j += 2 )
                    {
                        double denom = dataB[j*stepB]*dataB[j*stepB] +
                                       dataB[(j+1)*stepB]*dataB[(j+1)*stepB] + eps;

                        double re = dataA[j*stepA]*dataB[j*stepB] +
                                    dataA[(j+1)*stepA]*dataB[(j+1)*stepB];

                        double im = dataA[(j+1)*stepA]*dataB[j*stepB] -
                                    dataA[j*stepA]*dataB[(j+1)*stepB];

                        dataC[j*stepC] = re / denom;
                        dataC[(j+1)*stepC] = im / denom;
                    }
                else
                    for( j = 1; j <= rows - 2; j += 2 )
                    {
                        double denom = dataB[j*stepB]*dataB[j*stepB] +
                                       dataB[(j+1)*stepB]*dataB[(j+1)*stepB] + eps;

                        double re = dataA[j*stepA]*dataB[j*stepB] -
                                    dataA[(j+1)*stepA]*dataB[(j+1)*stepB];

                        double im = dataA[(j+1)*stepA]*dataB[j*stepB] +
                                    dataA[j*stepA]*dataB[(j+1)*stepB];

                        dataC[j*stepC] = re / denom;
                        dataC[(j+1)*stepC] = im / denom;
                    }
                if( k == 1 )
                    dataA -= cols - 1, dataB -= cols - 1, dataC -= cols - 1;
            }
        }

        for( ; rows--; dataA += stepA, dataB += stepB, dataC += stepC )
        {
            if( is_1d && cn == 1 )
            {
                dataC[0] = dataA[0] / (dataB[0] + eps);
                if( cols % 2 == 0 )
                    dataC[j1] = dataA[j1] / (dataB[j1] + eps);
            }

            if( !conjB )
                for( j = j0; j < j1; j += 2 )
                {
                    double denom = dataB[j]*dataB[j] + dataB[j+1]*dataB[j+1] + eps;
                    double re = dataA[j]*dataB[j] + dataA[j+1]*dataB[j+1];
                    double im = dataA[j+1]*dataB[j] - dataA[j]*dataB[j+1];
                    dataC[j] = re / denom;
                    dataC[j+1] = im / denom;
                }
            else
                for( j = j0; j < j1; j += 2 )
                {
                    double denom = dataB[j]*dataB[j] + dataB[j+1]*dataB[j+1] + eps;
                    double re = dataA[j]*dataB[j] - dataA[j+1]*dataB[j+1];
                    double im = dataA[j+1]*dataB[j] + dataA[j]*dataB[j+1];
                    dataC[j] = re / denom;
                    dataC[j+1] = im / denom;
                }
        }
    }

}
コード例 #26
0
ファイル: deriv.cpp プロジェクト: 165-goethals/opencv
static void getSobelKernels( OutputArray _kx, OutputArray _ky,
                             int dx, int dy, int _ksize, bool normalize, int ktype )
{
    int i, j, ksizeX = _ksize, ksizeY = _ksize;
    if( ksizeX == 1 && dx > 0 )
        ksizeX = 3;
    if( ksizeY == 1 && dy > 0 )
        ksizeY = 3;

    CV_Assert( ktype == CV_32F || ktype == CV_64F );

    _kx.create(ksizeX, 1, ktype, -1, true);
    _ky.create(ksizeY, 1, ktype, -1, true);
    Mat kx = _kx.getMat();
    Mat ky = _ky.getMat();

    if( _ksize % 2 == 0 || _ksize > 31 )
        CV_Error( CV_StsOutOfRange, "The kernel size must be odd and not larger than 31" );
    std::vector<int> kerI(std::max(ksizeX, ksizeY) + 1);

    CV_Assert( dx >= 0 && dy >= 0 && dx+dy > 0 );

    for( int k = 0; k < 2; k++ )
    {
        Mat* kernel = k == 0 ? &kx : &ky;
        int order = k == 0 ? dx : dy;
        int ksize = k == 0 ? ksizeX : ksizeY;

        CV_Assert( ksize > order );

        if( ksize == 1 )
            kerI[0] = 1;
        else if( ksize == 3 )
        {
            if( order == 0 )
                kerI[0] = 1, kerI[1] = 2, kerI[2] = 1;
            else if( order == 1 )
                kerI[0] = -1, kerI[1] = 0, kerI[2] = 1;
            else
                kerI[0] = 1, kerI[1] = -2, kerI[2] = 1;
        }
        else
        {
            int oldval, newval;
            kerI[0] = 1;
            for( i = 0; i < ksize; i++ )
                kerI[i+1] = 0;

            for( i = 0; i < ksize - order - 1; i++ )
            {
                oldval = kerI[0];
                for( j = 1; j <= ksize; j++ )
                {
                    newval = kerI[j]+kerI[j-1];
                    kerI[j-1] = oldval;
                    oldval = newval;
                }
            }

            for( i = 0; i < order; i++ )
            {
                oldval = -kerI[0];
                for( j = 1; j <= ksize; j++ )
                {
                    newval = kerI[j-1] - kerI[j];
                    kerI[j-1] = oldval;
                    oldval = newval;
                }
            }
        }

        Mat temp(kernel->rows, kernel->cols, CV_32S, &kerI[0]);
        double scale = !normalize ? 1. : 1./(1 << (ksize-order-1));
        temp.convertTo(*kernel, ktype, scale);
    }
}
コード例 #27
0
ファイル: deriv.cpp プロジェクト: AlexWillisson/opencv
void cv::Laplacian( InputArray _src, OutputArray _dst, int ddepth, int ksize,
                    double scale, double delta, int borderType )
{
    int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype);
    if (ddepth < 0)
        ddepth = sdepth;
    _dst.create( _src.size(), CV_MAKETYPE(ddepth, cn) );

#ifdef HAVE_TEGRA_OPTIMIZATION
    if (scale == 1.0 && delta == 0)
    {
        Mat src = _src.getMat(), dst = _dst.getMat();
        if (ksize == 1 && tegra::laplace1(src, dst, borderType))
            return;
        if (ksize == 3 && tegra::laplace3(src, dst, borderType))
            return;
        if (ksize == 5 && tegra::laplace5(src, dst, borderType))
            return;
    }
#endif

    if( ksize == 1 || ksize == 3 )
    {
        float K[2][9] =
        {
            { 0, 1, 0, 1, -4, 1, 0, 1, 0 },
            { 2, 0, 2, 0, -8, 0, 2, 0, 2 }
        };
        Mat kernel(3, 3, CV_32F, K[ksize == 3]);
        if( scale != 1 )
            kernel *= scale;
        filter2D( _src, _dst, ddepth, kernel, Point(-1, -1), delta, borderType );
    }
    else
    {
        Mat src = _src.getMat(), dst = _dst.getMat();
        const size_t STRIPE_SIZE = 1 << 14;

        int depth = src.depth();
        int ktype = std::max(CV_32F, std::max(ddepth, depth));
        int wdepth = depth == CV_8U && ksize <= 5 ? CV_16S : depth <= CV_32F ? CV_32F : CV_64F;
        int wtype = CV_MAKETYPE(wdepth, src.channels());
        Mat kd, ks;
        getSobelKernels( kd, ks, 2, 0, ksize, false, ktype );
        if( ddepth < 0 )
            ddepth = src.depth();
        int dtype = CV_MAKETYPE(ddepth, src.channels());

        int dy0 = std::min(std::max((int)(STRIPE_SIZE/(getElemSize(src.type())*src.cols)), 1), src.rows);
        Ptr<FilterEngine> fx = createSeparableLinearFilter(src.type(),
            wtype, kd, ks, Point(-1,-1), 0, borderType, borderType, Scalar() );
        Ptr<FilterEngine> fy = createSeparableLinearFilter(src.type(),
            wtype, ks, kd, Point(-1,-1), 0, borderType, borderType, Scalar() );

        int y = fx->start(src), dsty = 0, dy = 0;
        fy->start(src);
        const uchar* sptr = src.data + y*src.step;

        Mat d2x( dy0 + kd.rows - 1, src.cols, wtype );
        Mat d2y( dy0 + kd.rows - 1, src.cols, wtype );

        for( ; dsty < src.rows; sptr += dy0*src.step, dsty += dy )
        {
            fx->proceed( sptr, (int)src.step, dy0, d2x.data, (int)d2x.step );
            dy = fy->proceed( sptr, (int)src.step, dy0, d2y.data, (int)d2y.step );
            if( dy > 0 )
            {
                Mat dstripe = dst.rowRange(dsty, dsty + dy);
                d2x.rows = d2y.rows = dy; // modify the headers, which should work
                d2x += d2y;
                d2x.convertTo( dstripe, dtype, scale, delta );
            }
        }
    }
}
コード例 #28
0
ファイル: ccalib.cpp プロジェクト: D-Alex/opencv_contrib
bool CustomPattern::findPatternPass(const Mat& image, vector<Point2f>& matched_features, vector<Point3f>& pattern_points,
                                    Mat& H, vector<Point2f>& scene_corners, const double pratio, const double proj_error,
                                    const bool refine_position, const Mat& mask, OutputArray output)
{
    if (!initialized) {return false; }
    matched_features.clear();
    pattern_points.clear();

    vector<vector<DMatch> > matches;
    vector<KeyPoint> f_keypoints;
    Mat f_descriptor;

    detector->detect(image, f_keypoints, mask);
    if (refine_position) refineKeypointsPos(image, f_keypoints);

    descriptorExtractor->compute(image, f_keypoints, f_descriptor);
    descriptorMatcher->knnMatch(f_descriptor, descriptor, matches, 2); // k = 2;
    vector<DMatch> good_matches;
    vector<Point2f> obj_points;

    for(int i = 0; i < f_descriptor.rows; ++i)
    {
        if(matches[i][0].distance < pratio * matches[i][1].distance)
        {
            const DMatch& dm = matches[i][0];
            good_matches.push_back(dm);
            // "keypoints1[matches[i].queryIdx] has a corresponding point in keypoints2[matches[i].trainIdx]"
            matched_features.push_back(f_keypoints[dm.queryIdx].pt);
            pattern_points.push_back(points3d[dm.trainIdx]);
            obj_points.push_back(keypoints[dm.trainIdx].pt);
        }
    }

    if (good_matches.size() < MIN_POINTS_FOR_H) return false;

    Mat h_mask;
    H = findHomography(obj_points, matched_features, RANSAC, proj_error, h_mask);
    if (H.empty())
    {
        // cout << "findHomography() returned empty Mat." << endl;
        return false;
    }

    for(unsigned int i = 0; i < good_matches.size(); ++i)
    {
        if(!h_mask.data[i])
        {
            deleteStdVecElem(good_matches, i);
            deleteStdVecElem(matched_features, i);
            deleteStdVecElem(pattern_points, i);
        }
    }

    if (good_matches.empty()) return false;

    size_t numb_elem = good_matches.size();
    check_matches(matched_features, obj_points, good_matches, pattern_points, H);
    if (good_matches.empty() || numb_elem < good_matches.size()) return false;

    // Get the corners from the image
    scene_corners = vector<Point2f>(4);
    perspectiveTransform(obj_corners, scene_corners, H);

    // Check correctnes of H
    // Is it a convex hull?
    bool cConvex = isContourConvex(scene_corners);
    if (!cConvex) return false;

    // Is the hull too large or small?
    double scene_area = contourArea(scene_corners);
    if (scene_area < MIN_CONTOUR_AREA_PX) return false;
    double ratio = scene_area/img_roi.size().area();
    if ((ratio < MIN_CONTOUR_AREA_RATIO) ||
        (ratio > MAX_CONTOUR_AREA_RATIO)) return false;

    // Is any of the projected points outside the hull?
    for(unsigned int i = 0; i < good_matches.size(); ++i)
    {
        if(pointPolygonTest(scene_corners, f_keypoints[good_matches[i].queryIdx].pt, false) < 0)
        {
            deleteStdVecElem(good_matches, i);
            deleteStdVecElem(matched_features, i);
            deleteStdVecElem(pattern_points, i);
        }
    }

    if (output.needed())
    {
        Mat out;
        drawMatches(image, f_keypoints, img_roi, keypoints, good_matches, out);
        // Draw lines between the corners (the mapped object in the scene - image_2 )
        line(out, scene_corners[0], scene_corners[1], Scalar(0, 255, 0), 2);
        line(out, scene_corners[1], scene_corners[2], Scalar(0, 255, 0), 2);
        line(out, scene_corners[2], scene_corners[3], Scalar(0, 255, 0), 2);
        line(out, scene_corners[3], scene_corners[0], Scalar(0, 255, 0), 2);
        out.copyTo(output);
    }

    return (!good_matches.empty()); // return true if there are enough good matches
}
コード例 #29
-1
  //  Reconstruction function for API
  void
  reconstruct(InputArrayOfArrays points2d, OutputArray Ps, OutputArray points3d, InputOutputArray K,
              bool is_projective)
  {
    const int nviews = points2d.total();
    CV_Assert( nviews >= 2 );

    // OpenCV data types
    std::vector<Mat> pts2d;
    points2d.getMatVector(pts2d);
    const int depth = pts2d[0].depth();

    Matx33d Ka = K.getMat();

    // Projective reconstruction

    if (is_projective)
    {

      if ( nviews == 2 )
      {
        // Get Projection matrices
        Matx33d F;
        Matx34d P, Pp;

        normalizedEightPointSolver(pts2d[0], pts2d[1], F);
        projectionsFromFundamental(F, P, Pp);
        Ps.create(2, 1, depth);
        Mat(P).copyTo(Ps.getMatRef(0));
        Mat(Pp).copyTo(Ps.getMatRef(1));

        // Triangulate and find 3D points using inliers
        triangulatePoints(points2d, Ps, points3d);
      }
      else
      {
        std::vector<Mat> Rs, Ts;
        reconstruct(points2d, Rs, Ts, Ka, points3d, is_projective);

        // From Rs and Ts, extract Ps
        const int nviews = Rs.size();
        Ps.create(nviews, 1, depth);

        Matx34d P;
        for (size_t i = 0; i < nviews; ++i)
        {
          projectionFromKRt(Ka, Rs[i], Vec3d(Ts[i]), P);
          Mat(P).copyTo(Ps.getMatRef(i));
        }

        Mat(Ka).copyTo(K.getMat());
      }

    }


    // Affine reconstruction

    else
    {
      // TODO: implement me
      CV_Error(Error::StsNotImplemented, "Affine reconstruction not yet implemented");
    }

  }