void FeatureExtractorLch3D::extractBlockHist(InputArray iBlock, OutputArray oFeature) { const static float MAX_H = 180.0f; const static float MAX_S = 255.0f; const static float MAX_V = 255.0f; Mat block = iBlock.getMat(); int w = block.size().width; int h = block.size().height; float h_step = MAX_H / _h_bin; float s_step = MAX_S / _s_bin; float v_step = MAX_V / _v_bin; int count = 0; oFeature.create(_dim, 1, CV_32FC1); Mat feature = oFeature.getMat(); feature.setTo(0); for (int y=0; y<h; ++y) { unsigned char* ptr = block.ptr<unsigned char>(y); for (int x=0; x<w; ++x) { int xx = 3 * x; unsigned char h = ptr[xx]; unsigned char s = ptr[xx + 1]; unsigned char v = ptr[xx + 2]; int hi = min((int) floor(h/h_step), _h_bin - 1); int si = min((int) floor(s/s_step), _s_bin - 1); int vi = min((int) floor(v/v_step), _v_bin - 1); int i = (vi << (_h_bit + _s_bit)) + (si << _h_bit) + hi; ++feature.at<float>(i); ++count; } } for (int i=0; i < _dim; ++i) { feature.at<float>(i) /= count; } }
void HDF5Impl::atread(OutputArray value, const String& atlabel) { if (!atexists(atlabel)) CV_Error_(Error::StsInternal, ("Attribute '%s' does not exist!", atlabel.c_str())); hid_t attr = H5Aopen(m_h5_file_id, atlabel.c_str(), H5P_DEFAULT); hid_t atype = H5Aget_type(attr); hid_t aspace = H5Aget_space(attr); int rank = H5Sget_simple_extent_ndims(aspace); vector<hsize_t> dim_vec_(rank); H5Sget_simple_extent_dims(aspace, dim_vec_.data(), NULL); vector<int> dim_vec(dim_vec_.begin(), dim_vec_.end()); int nchannels = 1; hid_t h5type; if (H5Tget_class(atype) == H5T_ARRAY) { hsize_t dims; H5Tget_array_dims(atype, &dims); nchannels = (int) dims; hid_t super_type = H5Tget_super(atype); h5type = H5Tget_native_type(super_type, H5T_DIR_ASCEND); H5Tclose(super_type); } else h5type = H5Tget_native_type(atype, H5T_DIR_ASCEND); int dtype = GetCVtype(h5type); value.create(rank, dim_vec.data(), CV_MAKETYPE(dtype, nchannels)); H5Aread(attr, atype, value.getMat().data); H5Sclose(aspace); H5Tclose(atype); H5Aclose(attr); }
void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs, OutputArray _dst, int imgToDenoiseIndex, int temporalWindowSize, float h, int templateWindowSize, int searchWindowSize) { vector<Mat> srcImgs; _srcImgs.getMatVector(srcImgs); fastNlMeansDenoisingMultiCheckPreconditions( srcImgs, imgToDenoiseIndex, temporalWindowSize, templateWindowSize, searchWindowSize ); _dst.create(srcImgs[0].size(), srcImgs[0].type()); Mat dst = _dst.getMat(); switch (srcImgs[0].type()) { case CV_8U: parallel_for_(cv::Range(0, srcImgs[0].rows), FastNlMeansMultiDenoisingInvoker<uchar>( srcImgs, imgToDenoiseIndex, temporalWindowSize, dst, templateWindowSize, searchWindowSize, h)); break; case CV_8UC2: parallel_for_(cv::Range(0, srcImgs[0].rows), FastNlMeansMultiDenoisingInvoker<cv::Vec2b>( srcImgs, imgToDenoiseIndex, temporalWindowSize, dst, templateWindowSize, searchWindowSize, h)); break; case CV_8UC3: parallel_for_(cv::Range(0, srcImgs[0].rows), FastNlMeansMultiDenoisingInvoker<cv::Vec3b>( srcImgs, imgToDenoiseIndex, temporalWindowSize, dst, templateWindowSize, searchWindowSize, h)); break; default: CV_Error(CV_StsBadArg, "Unsupported matrix format! Only uchar, Vec2b, Vec3b are supported"); } }
void Mat::copyTo( OutputArray _dst, InputArray _mask ) const { Mat mask = _mask.getMat(); if( !mask.data ) { copyTo(_dst); return; } int cn = channels(), mcn = mask.channels(); CV_Assert( mask.depth() == CV_8U && (mcn == 1 || mcn == cn) ); bool colorMask = mcn > 1; size_t esz = colorMask ? elemSize1() : elemSize(); BinaryFunc copymask = getCopyMaskFunc(esz); uchar* data0 = _dst.getMat().data; _dst.create( dims, size, type() ); Mat dst = _dst.getMat(); if( dst.data != data0 ) // do not leave dst uninitialized dst = Scalar(0); if( dims <= 2 ) { Size sz = getContinuousSize(*this, dst, mask, mcn); copymask(data, step, mask.data, mask.step, dst.data, dst.step, sz, &esz); return; } const Mat* arrays[] = { this, &dst, &mask, 0 }; uchar* ptrs[3]; NAryMatIterator it(arrays, ptrs); Size sz((int)(it.size*mcn), 1); for( size_t i = 0; i < it.nplanes; i++, ++it ) copymask(ptrs[0], 0, ptrs[2], 0, ptrs[1], 0, sz, &esz); }
void cv::fastNlMeansDenoisingColored( InputArray _src, OutputArray _dst, float h, float hForColorComponents, int templateWindowSize, int searchWindowSize) { int type = _src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type); if (type != CV_8UC3 && type != CV_8UC4) { CV_Error(Error::StsBadArg, "Type of input image should be CV_8UC3!"); return; } CV_OCL_RUN(_src.dims() <= 2 && (_dst.isUMat() || _src.isUMat()), ocl_fastNlMeansDenoisingColored(_src, _dst, h, hForColorComponents, templateWindowSize, searchWindowSize)) Mat src = _src.getMat(); _dst.create(src.size(), type); Mat dst = _dst.getMat(); Mat src_lab; cvtColor(src, src_lab, COLOR_LBGR2Lab); Mat l(src.size(), CV_8U); Mat ab(src.size(), CV_8UC2); Mat l_ab[] = { l, ab }; int from_to[] = { 0,0, 1,1, 2,2 }; mixChannels(&src_lab, 1, l_ab, 2, from_to, 3); fastNlMeansDenoising(l, l, h, templateWindowSize, searchWindowSize); fastNlMeansDenoising(ab, ab, hForColorComponents, templateWindowSize, searchWindowSize); Mat l_ab_denoised[] = { l, ab }; Mat dst_lab(src.size(), CV_MAKE_TYPE(depth, 3)); mixChannels(l_ab_denoised, 2, &dst_lab, 1, from_to, 3); cvtColor(dst_lab, dst, COLOR_Lab2LBGR, cn); }
static bool matchTemplateNaive_CCORR(InputArray _image, InputArray _templ, OutputArray _result) { int type = _image.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type); int wdepth = CV_32F, wtype = CV_MAKE_TYPE(wdepth, cn); ocl::Device dev = ocl::Device::getDefault(); int pxPerWIx = (cn==1 && dev.isIntel() && (dev.type() & ocl::Device::TYPE_GPU)) ? 4 : 1; int rated_cn = cn; int wtype1 = wtype; if (pxPerWIx!=1) { rated_cn = pxPerWIx; type = CV_MAKE_TYPE(depth, rated_cn); wtype1 = CV_MAKE_TYPE(wdepth, rated_cn); } char cvt[40]; char cvt1[40]; const char* convertToWT1 = ocl::convertTypeStr(depth, wdepth, cn, cvt); const char* convertToWT = ocl::convertTypeStr(depth, wdepth, rated_cn, cvt1); ocl::Kernel k("matchTemplate_Naive_CCORR", ocl::imgproc::match_template_oclsrc, format("-D CCORR -D T=%s -D T1=%s -D WT=%s -D WT1=%s -D convertToWT=%s -D convertToWT1=%s -D cn=%d -D PIX_PER_WI_X=%d", ocl::typeToStr(type), ocl::typeToStr(depth), ocl::typeToStr(wtype1), ocl::typeToStr(wtype), convertToWT, convertToWT1, cn, pxPerWIx)); if (k.empty()) return false; UMat image = _image.getUMat(), templ = _templ.getUMat(); _result.create(image.rows - templ.rows + 1, image.cols - templ.cols + 1, CV_32FC1); UMat result = _result.getUMat(); k.args(ocl::KernelArg::ReadOnlyNoSize(image), ocl::KernelArg::ReadOnly(templ), ocl::KernelArg::WriteOnly(result)); size_t globalsize[2] = { (result.cols+pxPerWIx-1)/pxPerWIx, result.rows}; return k.run(2, globalsize, NULL, false); }
static bool ocl_pyrDown( InputArray _src, OutputArray _dst, const Size& _dsz, int borderType) { int type = _src.type(), depth = CV_MAT_DEPTH(type), channels = CV_MAT_CN(type); if ((channels != 1 && channels != 2 && channels != 4) || borderType != BORDER_DEFAULT) return false; bool doubleSupport = ocl::Device::getDefault().doubleFPConfig() > 0; if ((depth == CV_64F) && !(doubleSupport)) return false; Size ssize = _src.size(); Size dsize = _dsz.area() == 0 ? Size((ssize.width + 1) / 2, (ssize.height + 1) / 2) : _dsz; CV_Assert( ssize.width > 0 && ssize.height > 0 && std::abs(dsize.width*2 - ssize.width) <= 2 && std::abs(dsize.height*2 - ssize.height) <= 2 ); UMat src = _src.getUMat(); _dst.create( dsize, src.type() ); UMat dst = _dst.getUMat(); int float_depth = depth == CV_64F ? CV_64F : CV_32F; char cvt[2][50]; ocl::Kernel k("pyrDown", ocl::imgproc::pyr_down_oclsrc, format("-D T=%s -D FT=%s -D convertToT=%s -D convertToFT=%s%s", ocl::typeToStr(type), ocl::typeToStr(CV_MAKETYPE(float_depth, channels)), ocl::convertTypeStr(float_depth, depth, channels, cvt[0]), ocl::convertTypeStr(depth, float_depth, channels, cvt[1]), doubleSupport ? " -D DOUBLE_SUPPORT" : "")); if (k.empty()) return false; k.args(ocl::KernelArg::ReadOnly(src), ocl::KernelArg::WriteOnly(dst)); size_t localThreads[2] = { 256, 1 }; size_t globalThreads[2] = { src.cols, dst.rows }; return k.run(2, globalThreads, localThreads, false); }
void BackgroundSubtractorMOG::operator()(InputArray _image, OutputArray _fgmask, double learningRate) { Mat image = _image.getMat(); bool needToInitialize = nframes == 0 || learningRate >= 1 || image.size() != frameSize || image.type() != frameType; if( needToInitialize ) initialize(image.size(), image.type()); CV_Assert( image.depth() == CV_8U ); _fgmask.create( image.size(), CV_8U ); Mat fgmask = _fgmask.getMat(); ++nframes; learningRate = learningRate >= 0 && nframes > 1 ? learningRate : 1./min( nframes, history ); CV_Assert(learningRate >= 0); if( image.type() == CV_8UC1 ) process8uC1( image, fgmask, learningRate, bgmodel, nmixtures, backgroundRatio, varThreshold, noiseSigma ); else if( image.type() == CV_8UC3 ) process8uC3( image, fgmask, learningRate, bgmodel, nmixtures, backgroundRatio, varThreshold, noiseSigma ); else CV_Error( CV_StsUnsupportedFormat, "Only 1- and 3-channel 8-bit images are supported in BackgroundSubtractorMOG" ); }
void removeCols(InputArray _src, OutputArray _dst, cv::Range range) { CV_Assert( range.start >= 0 && range.end < _src.getMat().cols ); Mat src = _src.getMat(); int type = src.type(); _dst.create( src.rows, src.cols - range.size() - 1, type ); Mat dst = _dst.getMat(); if(src.data != dst.data || src.step != dst.step) { for(int i = range.start; i <= range.end; ++i) { // cout << i << endl; removeCol(src, src, range.start); // cout << "src: " << endl << src << endl; } src.copyTo(dst); } return; }
/* Post: fill _err with projection errors */ void computeError( InputArray _m1, InputArray _m2, InputArray _model, OutputArray _err ) const { Mat opoints = _m1.getMat(), ipoints = _m2.getMat(), model = _model.getMat(); int i, count = opoints.checkVector(3); Mat _rvec = model.col(0); Mat _tvec = model.col(1); Mat projpoints(count, 2, CV_32FC1); projectPoints(opoints, _rvec, _tvec, cameraMatrix, distCoeffs, projpoints); const Point2f* ipoints_ptr = ipoints.ptr<Point2f>(); const Point2f* projpoints_ptr = projpoints.ptr<Point2f>(); _err.create(count, 1, CV_32FC1); float* err = _err.getMat().ptr<float>(); for ( i = 0; i < count; ++i) err[i] = (float)norm( Matx21f(ipoints_ptr[i] - projpoints_ptr[i]), NORM_L2SQR ); }
void cv::gpu::flip(InputArray _src, OutputArray _dst, int flipCode, Stream& stream) { typedef void (*func_t)(const GpuMat& src, GpuMat& dst, int flipCode, cudaStream_t stream); static const func_t funcs[6][4] = { {NppMirror<CV_8U, nppiMirror_8u_C1R>::call, 0, NppMirror<CV_8U, nppiMirror_8u_C3R>::call, NppMirror<CV_8U, nppiMirror_8u_C4R>::call}, {0,0,0,0}, {NppMirror<CV_16U, nppiMirror_16u_C1R>::call, 0, NppMirror<CV_16U, nppiMirror_16u_C3R>::call, NppMirror<CV_16U, nppiMirror_16u_C4R>::call}, {0,0,0,0}, {NppMirror<CV_32S, nppiMirror_32s_C1R>::call, 0, NppMirror<CV_32S, nppiMirror_32s_C3R>::call, NppMirror<CV_32S, nppiMirror_32s_C4R>::call}, {NppMirror<CV_32F, nppiMirror_32f_C1R>::call, 0, NppMirror<CV_32F, nppiMirror_32f_C3R>::call, NppMirror<CV_32F, nppiMirror_32f_C4R>::call} }; GpuMat src = _src.getGpuMat(); CV_Assert(src.depth() == CV_8U || src.depth() == CV_16U || src.depth() == CV_32S || src.depth() == CV_32F); CV_Assert(src.channels() == 1 || src.channels() == 3 || src.channels() == 4); _dst.create(src.size(), src.type()); GpuMat dst = _dst.getGpuMat(); funcs[src.depth()][src.channels() - 1](src, dst, flipCode, StreamAccessor::getStream(stream)); }
Vec2d EM::predict(InputArray _sample, OutputArray _probs) const { Mat sample = _sample.getMat(); CV_Assert(isTrained()); CV_Assert(!sample.empty()); if(sample.type() != CV_64FC1) { Mat tmp; sample.convertTo(tmp, CV_64FC1); sample = tmp; } sample.reshape(1, 1); Mat probs; if( _probs.needed() ) { _probs.create(1, nclusters, CV_64FC1); probs = _probs.getMat(); } return computeProbabilities(sample, !probs.empty() ? &probs : 0); }
void cv::textureFlattening(InputArray _src, InputArray _mask, OutputArray _dst, double low_threshold, double high_threshold, int kernel_size) { Mat src = _src.getMat(); Mat mask = _mask.getMat(); _dst.create(src.size(), src.type()); Mat blend = _dst.getMat(); Mat gray = Mat::zeros(mask.size(),CV_8UC1); if(mask.channels() == 3) cvtColor(mask, gray, COLOR_BGR2GRAY ); else gray = mask; Mat cs_mask = Mat::zeros(src.size(),CV_8UC3); src.copyTo(cs_mask,gray); Cloning obj; obj.texture_flatten(src,cs_mask,gray,low_threshold,high_threshold,kernel_size,blend); }
void cv::Scharr( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy, 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; int dtype = CV_MAKETYPE(ddepth, cn); _dst.create( _src.size(), dtype ); #ifdef HAVE_TEGRA_OPTIMIZATION if (scale == 1.0 && delta == 0) { Mat src = _src.getMat(), dst = _dst.getMat(); if (tegra::scharr(src, dst, dx, dy, borderType)) return; } #endif #if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) if (IPPDerivScharr(_src, _dst, ddepth, dx, dy, scale, delta, borderType)) return; #endif int ktype = std::max(CV_32F, std::max(ddepth, sdepth)); Mat kx, ky; getScharrKernels( kx, ky, dx, dy, false, ktype ); if( scale != 1 ) { // usually the smoothing part is the slowest to compute, // so try to scale it instead of the faster differenciating part if( dx == 0 ) kx *= scale; else ky *= scale; } sepFilter2D( _src, _dst, ddepth, kx, ky, Point(-1, -1), delta, borderType ); }
void FeatureExtractorLch3D::extract(InputArray iFrame, OutputArray oFeature) { _h_bin = (int) powl(2, _h_bit); _s_bin = (int) powl(2, _s_bit); _v_bin = (int) powl(2, _v_bit); _dim = _h_bin * _s_bin * _v_bin; Mat rgbImg = iFrame.getMat(); Mat hsvImg; cvtColor(rgbImg, hsvImg, CV_BGR2HSV); int w = hsvImg.size().width; int h = hsvImg.size().height; int ix = 0; int iy = 0; int sw = (int) ceil(w / (double) _num_block_x); int sh = (int) ceil(h / (double) _num_block_y); oFeature.create(_dim * _num_block_y * _num_block_x, 1, CV_32FC1); Mat hist = oFeature.getMat(); int index = 0; while (iy < h) { int begin_y = iy; int end_y = min((iy + sh), h); Mat row_block = hsvImg.rowRange(begin_y, end_y); iy = end_y; ix = 0; while (ix < w) { int begin_x = ix; int end_x = min((ix + sw), w); Mat block = row_block.colRange(begin_x, end_x); ix = end_x; Mat hist_block = hist.rowRange(index, index + _dim); extractBlockHist(block, hist_block); index += _dim; } } }
//------------------------------------------------------------------------------ // cv::elbp //------------------------------------------------------------------------------ template <typename _Tp> static inline void elbp_(InputArray _src, OutputArray _dst, int radius, int neighbors) { //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 * cos(2.0*CV_PI*n/static_cast<float>(neighbors))); float y = static_cast<float>(-radius * sin(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 = static_cast<float>(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; } } } }
void cv::gpu::transpose(InputArray _src, OutputArray _dst, Stream& _stream) { GpuMat src = _src.getGpuMat(); CV_Assert( src.elemSize() == 1 || src.elemSize() == 4 || src.elemSize() == 8 ); _dst.create( src.cols, src.rows, src.type() ); GpuMat dst = _dst.getGpuMat(); cudaStream_t stream = StreamAccessor::getStream(_stream); if (src.elemSize() == 1) { NppStreamHandler h(stream); NppiSize sz; sz.width = src.cols; sz.height = src.rows; nppSafeCall( nppiTranspose_8u_C1R(src.ptr<Npp8u>(), static_cast<int>(src.step), dst.ptr<Npp8u>(), static_cast<int>(dst.step), sz) ); if (stream == 0) cudaSafeCall( cudaDeviceSynchronize() ); } else if (src.elemSize() == 4) { arithm::transpose<int>(src, dst, stream); } else // if (src.elemSize() == 8) { if (!deviceSupports(NATIVE_DOUBLE)) CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); arithm::transpose<double>(src, dst, stream); } }
void BackgroundSubtractorKNNImpl::apply(InputArray _image, OutputArray _fgmask, double learningRate) { Mat image = _image.getMat(); bool needToInitialize = nframes == 0 || learningRate >= 1 || image.size() != frameSize || image.type() != frameType; if( needToInitialize ) initialize(image.size(), image.type()); _fgmask.create( image.size(), CV_8U ); Mat fgmask = _fgmask.getMat(); ++nframes; learningRate = learningRate >= 0 && nframes > 1 ? learningRate : 1./std::min( 2*nframes, history ); CV_Assert(learningRate >= 0); //parallel_for_(Range(0, image.rows), // KNNInvoker(image, fgmask, icvUpdatePixelBackgroundNP(image, fgmask, bgmodel, nNextLongUpdate, nNextMidUpdate, nNextShortUpdate, aModelIndexLong, aModelIndexMid, aModelIndexShort, nLongCounter, nMidCounter, nShortCounter, nN, (float)learningRate, fTb, nkNN, fTau, bShadowDetection, nShadowDetection ); }
void process(InputArrayOfArrays src, OutputArray dst, InputArray _times, InputArray input_response) { std::vector<Mat> images; src.getMatVector(images); Mat times = _times.getMat(); CV_Assert(images.size() == times.total()); checkImageDimensions(images); CV_Assert(images[0].depth() == CV_8U); int channels = images[0].channels(); int CV_32FCC = CV_MAKETYPE(CV_32F, channels); dst.create(images[0].size(), CV_32FCC); Mat result = dst.getMat(); Mat response = input_response.getMat(); if(response.empty()) { float middle = LDR_SIZE / 2.0f; response = linearResponse(channels) / middle; } CV_Assert(response.rows == LDR_SIZE && response.cols == 1 && response.channels() == channels); result = Mat::zeros(images[0].size(), CV_32FCC); Mat wsum = Mat::zeros(images[0].size(), CV_32FCC); for(size_t i = 0; i < images.size(); i++) { Mat im, w; LUT(images[i], weight, w); LUT(images[i], response, im); result += times.at<float>((int)i) * w.mul(im); wsum += times.at<float>((int)i) * times.at<float>((int)i) * w; } result = result.mul(1 / wsum); }
void cv::fastNlMeansDenoising( InputArray _src, OutputArray _dst, float h, int templateWindowSize, int searchWindowSize) { CV_OCL_RUN(_src.dims() <= 2 && (_src.isUMat() || _dst.isUMat()), ocl_fastNlMeansDenoising(_src, _dst, h, templateWindowSize, searchWindowSize)) Mat src = _src.getMat(); _dst.create(src.size(), src.type()); Mat dst = _dst.getMat(); #ifdef HAVE_TEGRA_OPTIMIZATION if(tegra::fastNlMeansDenoising(src, dst, h, templateWindowSize, searchWindowSize)) return; #endif switch (src.type()) { case CV_8U: parallel_for_(cv::Range(0, src.rows), FastNlMeansDenoisingInvoker<uchar>( src, dst, templateWindowSize, searchWindowSize, h)); break; case CV_8UC2: parallel_for_(cv::Range(0, src.rows), FastNlMeansDenoisingInvoker<cv::Vec2b>( src, dst, templateWindowSize, searchWindowSize, h)); break; case CV_8UC3: parallel_for_(cv::Range(0, src.rows), FastNlMeansDenoisingInvoker<cv::Vec3b>( src, dst, templateWindowSize, searchWindowSize, h)); break; default: CV_Error(Error::StsBadArg, "Unsupported image format! Only CV_8UC1, CV_8UC2 and CV_8UC3 are supported"); } }
void IPPE::PoseSolver::makeCanonicalObjectPoints(InputArray _objectPoints, OutputArray _canonicalObjPoints, OutputArray _MmodelPoints2Canonical) { int objType = _objectPoints.type(); assert((objType == CV_64FC3) | (objType == CV_32FC3)); size_t n = _objectPoints.rows() * _objectPoints.cols(); _canonicalObjPoints.create(1, n, CV_64FC2); _MmodelPoints2Canonical.create(4, 4, CV_64FC1); cv::Mat objectPoints = _objectPoints.getMat(); cv::Mat canonicalObjPoints = _canonicalObjPoints.getMat(); cv::Mat UZero(3, n, CV_64FC1); double xBar = 0; double yBar = 0; double zBar = 0; bool isOnZPlane = true; for (size_t i = 0; i < n; i++) { double x, y, z; if (objType == CV_32FC3) { x = static_cast<double>(objectPoints.at<Vec3f>(i)[0]); y = static_cast<double>(objectPoints.at<Vec3f>(i)[1]); z = static_cast<double>(objectPoints.at<Vec3f>(i)[2]); } else { x = objectPoints.at<Vec3d>(i)[0]; y = objectPoints.at<Vec3d>(i)[1]; z = objectPoints.at<Vec3d>(i)[2]; if (abs(z) > IPPE_SMALL) { isOnZPlane = false; } } xBar += x; yBar += y; zBar += z; UZero.at<double>(0, i) = x; UZero.at<double>(1, i) = y; UZero.at<double>(2, i) = z; } xBar = xBar / (double)n; yBar = yBar / (double)n; zBar = zBar / (double)n; for (size_t i = 0; i < n; i++) { UZero.at<double>(0, i) -= xBar; UZero.at<double>(1, i) -= yBar; UZero.at<double>(2, i) -= zBar; } cv::Mat MCenter(4, 4, CV_64FC1); MCenter.setTo(0); MCenter.at<double>(0, 0) = 1; MCenter.at<double>(1, 1) = 1; MCenter.at<double>(2, 2) = 1; MCenter.at<double>(3, 3) = 1; MCenter.at<double>(0, 3) = -xBar; MCenter.at<double>(1, 3) = -yBar; MCenter.at<double>(2, 3) = -zBar; if (isOnZPlane) { //MmodelPoints2Canonical is given by MCenter MCenter.copyTo(_MmodelPoints2Canonical); for (size_t i = 0; i < n; i++) { canonicalObjPoints.at<Vec2d>(i)[0] = UZero.at<double>(0, i); canonicalObjPoints.at<Vec2d>(i)[1] = UZero.at<double>(1, i); } } else { cv::Mat UZeroAligned(3, n, CV_64FC1); cv::Mat R; //rotation that rotates objectPoints to the plane z=0 if (!computeObjextSpaceR3Pts(objectPoints,R)) { //we could not compute R, problably because there is a duplicate point in {objectPoints(0),objectPoints(1),objectPoints(2)}. So we compute it with the SVD (which is slower): computeObjextSpaceRSvD(UZero,R); } UZeroAligned = R * UZero; for (size_t i = 0; i < n; i++) { canonicalObjPoints.at<Vec2d>(i)[0] = UZeroAligned.at<double>(0, i); canonicalObjPoints.at<Vec2d>(i)[1] = UZeroAligned.at<double>(1, i); assert(abs(UZeroAligned.at<double>(2, i))<=IPPE_SMALL); } cv::Mat MRot(4, 4, CV_64FC1); MRot.setTo(0); MRot.at<double>(3, 3) = 1; R.copyTo(MRot.colRange(0, 3).rowRange(0, 3)); cv::Mat Mb = MRot * MCenter; Mb.copyTo(_MmodelPoints2Canonical); } }
void cv::segmentMotion(InputArray _mhi, OutputArray _segmask, std::vector<Rect>& boundingRects, double timestamp, double segThresh) { Mat mhi = _mhi.getMat(); _segmask.create(mhi.size(), CV_32F); Mat segmask = _segmask.getMat(); segmask = Scalar::all(0); CV_Assert( mhi.type() == CV_32F ); CV_Assert( segThresh >= 0 ); Mat mask = Mat::zeros( mhi.rows + 2, mhi.cols + 2, CV_8UC1 ); int x, y; // protect zero mhi pixels from floodfill. for( y = 0; y < mhi.rows; y++ ) { const float* mhiptr = mhi.ptr<float>(y); uchar* maskptr = mask.ptr<uchar>(y+1) + 1; for( x = 0; x < mhi.cols; x++ ) { if( mhiptr[x] == 0 ) maskptr[x] = 1; } } float ts = (float)timestamp; float comp_idx = 1.f; for( y = 0; y < mhi.rows; y++ ) { float* mhiptr = mhi.ptr<float>(y); uchar* maskptr = mask.ptr<uchar>(y+1) + 1; for( x = 0; x < mhi.cols; x++ ) { if( mhiptr[x] == ts && maskptr[x] == 0 ) { Rect cc; floodFill( mhi, mask, Point(x,y), Scalar::all(0), &cc, Scalar::all(segThresh), Scalar::all(segThresh), FLOODFILL_MASK_ONLY + 2*256 + 4 ); for( int y1 = 0; y1 < cc.height; y1++ ) { float* segmaskptr = segmask.ptr<float>(cc.y + y1) + cc.x; uchar* maskptr1 = mask.ptr<uchar>(cc.y + y1 + 1) + cc.x + 1; for( int x1 = 0; x1 < cc.width; x1++ ) { if( maskptr1[x1] > 1 ) { maskptr1[x1] = 1; segmaskptr[x1] = comp_idx; } } } comp_idx += 1.f; boundingRects.push_back(cc); } } } }
void cv::calcMotionGradient( InputArray _mhi, OutputArray _mask, OutputArray _orientation, double delta1, double delta2, int aperture_size ) { static int runcase = 0; runcase++; Mat mhi = _mhi.getMat(); Size size = mhi.size(); _mask.create(size, CV_8U); _orientation.create(size, CV_32F); Mat mask = _mask.getMat(); Mat orient = _orientation.getMat(); if( aperture_size < 3 || aperture_size > 7 || (aperture_size & 1) == 0 ) CV_Error( Error::StsOutOfRange, "aperture_size must be 3, 5 or 7" ); if( delta1 <= 0 || delta2 <= 0 ) CV_Error( Error::StsOutOfRange, "both delta's must be positive" ); if( mhi.type() != CV_32FC1 ) CV_Error( Error::StsUnsupportedFormat, "MHI must be single-channel floating-point images" ); if( orient.data == mhi.data ) { _orientation.release(); _orientation.create(size, CV_32F); orient = _orientation.getMat(); } if( delta1 > delta2 ) std::swap(delta1, delta2); float gradient_epsilon = 1e-4f * aperture_size * aperture_size; float min_delta = (float)delta1; float max_delta = (float)delta2; Mat dX_min, dY_max; // calc Dx and Dy Sobel( mhi, dX_min, CV_32F, 1, 0, aperture_size, 1, 0, BORDER_REPLICATE ); Sobel( mhi, dY_max, CV_32F, 0, 1, aperture_size, 1, 0, BORDER_REPLICATE ); int x, y; if( mhi.isContinuous() && orient.isContinuous() && mask.isContinuous() ) { size.width *= size.height; size.height = 1; } // calc gradient for( y = 0; y < size.height; y++ ) { const float* dX_min_row = dX_min.ptr<float>(y); const float* dY_max_row = dY_max.ptr<float>(y); float* orient_row = orient.ptr<float>(y); uchar* mask_row = mask.ptr<uchar>(y); fastAtan2(dY_max_row, dX_min_row, orient_row, size.width, true); // make orientation zero where the gradient is very small for( x = 0; x < size.width; x++ ) { float dY = dY_max_row[x]; float dX = dX_min_row[x]; if( std::abs(dX) < gradient_epsilon && std::abs(dY) < gradient_epsilon ) { mask_row[x] = (uchar)0; orient_row[x] = 0.f; } else mask_row[x] = (uchar)1; } } erode( mhi, dX_min, noArray(), Point(-1,-1), (aperture_size-1)/2, BORDER_REPLICATE ); dilate( mhi, dY_max, noArray(), Point(-1,-1), (aperture_size-1)/2, BORDER_REPLICATE ); // mask off pixels which have little motion difference in their neighborhood for( y = 0; y < size.height; y++ ) { const float* dX_min_row = dX_min.ptr<float>(y); const float* dY_max_row = dY_max.ptr<float>(y); float* orient_row = orient.ptr<float>(y); uchar* mask_row = mask.ptr<uchar>(y); for( x = 0; x < size.width; x++ ) { float d0 = dY_max_row[x] - dX_min_row[x]; if( mask_row[x] == 0 || d0 < min_delta || max_delta < d0 ) { mask_row[x] = (uchar)0; orient_row[x] = 0.f; } } } }
void cv::pyrMeanShiftFiltering( InputArray _src, OutputArray _dst, double sp0, double sr, int max_level, TermCriteria termcrit ) { Mat src0 = _src.getMat(); if( src0.empty() ) return; _dst.create( src0.size(), src0.type() ); Mat dst0 = _dst.getMat(); const int cn = 3; const int MAX_LEVELS = 8; if( (unsigned)max_level > (unsigned)MAX_LEVELS ) CV_Error( CV_StsOutOfRange, "The number of pyramid levels is too large or negative" ); std::vector<cv::Mat> src_pyramid(max_level+1); std::vector<cv::Mat> dst_pyramid(max_level+1); cv::Mat mask0; int i, j, level; //uchar* submask = 0; #define cdiff(ofs0) (tab[c0-dptr[ofs0]+255] + \ tab[c1-dptr[(ofs0)+1]+255] + tab[c2-dptr[(ofs0)+2]+255] >= isr22) double sr2 = sr * sr; int isr2 = cvRound(sr2), isr22 = MAX(isr2,16); int tab[768]; if( src0.type() != CV_8UC3 ) CV_Error( CV_StsUnsupportedFormat, "Only 8-bit, 3-channel images are supported" ); if( src0.type() != dst0.type() ) CV_Error( CV_StsUnmatchedFormats, "The input and output images must have the same type" ); if( src0.size() != dst0.size() ) CV_Error( CV_StsUnmatchedSizes, "The input and output images must have the same size" ); if( !(termcrit.type & CV_TERMCRIT_ITER) ) termcrit.maxCount = 5; termcrit.maxCount = MAX(termcrit.maxCount,1); termcrit.maxCount = MIN(termcrit.maxCount,100); if( !(termcrit.type & CV_TERMCRIT_EPS) ) termcrit.epsilon = 1.f; termcrit.epsilon = MAX(termcrit.epsilon, 0.f); for( i = 0; i < 768; i++ ) tab[i] = (i - 255)*(i - 255); // 1. construct pyramid src_pyramid[0] = src0; dst_pyramid[0] = dst0; for( level = 1; level <= max_level; level++ ) { src_pyramid[level].create( (src_pyramid[level-1].rows+1)/2, (src_pyramid[level-1].cols+1)/2, src_pyramid[level-1].type() ); dst_pyramid[level].create( src_pyramid[level].rows, src_pyramid[level].cols, src_pyramid[level].type() ); cv::pyrDown( src_pyramid[level-1], src_pyramid[level], src_pyramid[level].size() ); //CV_CALL( cvResize( src_pyramid[level-1], src_pyramid[level], CV_INTER_AREA )); } mask0.create(src0.rows, src0.cols, CV_8UC1); //CV_CALL( submask = (uchar*)cvAlloc( (sp+2)*(sp+2) )); // 2. apply meanshift, starting from the pyramid top (i.e. the smallest layer) for( level = max_level; level >= 0; level-- ) { cv::Mat src = src_pyramid[level]; cv::Size size = src.size(); const uchar* sptr = src.ptr(); int sstep = (int)src.step; uchar* mask = 0; int mstep = 0; uchar* dptr; int dstep; float sp = (float)(sp0 / (1 << level)); sp = MAX( sp, 1 ); if( level < max_level ) { cv::Size size1 = dst_pyramid[level+1].size(); cv::Mat m( size.height, size.width, CV_8UC1, mask0.ptr() ); dstep = (int)dst_pyramid[level+1].step; dptr = dst_pyramid[level+1].ptr() + dstep + cn; mstep = (int)m.step; mask = m.ptr() + mstep; //cvResize( dst_pyramid[level+1], dst_pyramid[level], CV_INTER_CUBIC ); cv::pyrUp( dst_pyramid[level+1], dst_pyramid[level], dst_pyramid[level].size() ); m.setTo(cv::Scalar::all(0)); for( i = 1; i < size1.height-1; i++, dptr += dstep - (size1.width-2)*3, mask += mstep*2 ) { for( j = 1; j < size1.width-1; j++, dptr += cn ) { int c0 = dptr[0], c1 = dptr[1], c2 = dptr[2]; mask[j*2 - 1] = cdiff(-3) || cdiff(3) || cdiff(-dstep-3) || cdiff(-dstep) || cdiff(-dstep+3) || cdiff(dstep-3) || cdiff(dstep) || cdiff(dstep+3); } } cv::dilate( m, m, cv::Mat() ); mask = m.ptr(); } dptr = dst_pyramid[level].ptr(); dstep = (int)dst_pyramid[level].step; for( i = 0; i < size.height; i++, sptr += sstep - size.width*3, dptr += dstep - size.width*3, mask += mstep ) { for( j = 0; j < size.width; j++, sptr += 3, dptr += 3 ) { int x0 = j, y0 = i, x1, y1, iter; int c0, c1, c2; if( mask && !mask[j] ) continue; c0 = sptr[0], c1 = sptr[1], c2 = sptr[2]; // iterate meanshift procedure for( iter = 0; iter < termcrit.maxCount; iter++ ) { const uchar* ptr; int x, y, count = 0; int minx, miny, maxx, maxy; int s0 = 0, s1 = 0, s2 = 0, sx = 0, sy = 0; double icount; int stop_flag; //mean shift: process pixels in window (p-sigmaSp)x(p+sigmaSp) minx = cvRound(x0 - sp); minx = MAX(minx, 0); miny = cvRound(y0 - sp); miny = MAX(miny, 0); maxx = cvRound(x0 + sp); maxx = MIN(maxx, size.width-1); maxy = cvRound(y0 + sp); maxy = MIN(maxy, size.height-1); ptr = sptr + (miny - i)*sstep + (minx - j)*3; for( y = miny; y <= maxy; y++, ptr += sstep - (maxx-minx+1)*3 ) { int row_count = 0; x = minx; #if CV_ENABLE_UNROLLED for( ; x + 3 <= maxx; x += 4, ptr += 12 ) { int t0 = ptr[0], t1 = ptr[1], t2 = ptr[2]; if( tab[t0-c0+255] + tab[t1-c1+255] + tab[t2-c2+255] <= isr2 ) { s0 += t0; s1 += t1; s2 += t2; sx += x; row_count++; } t0 = ptr[3], t1 = ptr[4], t2 = ptr[5]; if( tab[t0-c0+255] + tab[t1-c1+255] + tab[t2-c2+255] <= isr2 ) { s0 += t0; s1 += t1; s2 += t2; sx += x+1; row_count++; } t0 = ptr[6], t1 = ptr[7], t2 = ptr[8]; if( tab[t0-c0+255] + tab[t1-c1+255] + tab[t2-c2+255] <= isr2 ) { s0 += t0; s1 += t1; s2 += t2; sx += x+2; row_count++; } t0 = ptr[9], t1 = ptr[10], t2 = ptr[11]; if( tab[t0-c0+255] + tab[t1-c1+255] + tab[t2-c2+255] <= isr2 ) { s0 += t0; s1 += t1; s2 += t2; sx += x+3; row_count++; } } #endif for( ; x <= maxx; x++, ptr += 3 ) { int t0 = ptr[0], t1 = ptr[1], t2 = ptr[2]; if( tab[t0-c0+255] + tab[t1-c1+255] + tab[t2-c2+255] <= isr2 ) { s0 += t0; s1 += t1; s2 += t2; sx += x; row_count++; } } count += row_count; sy += y*row_count; } if( count == 0 ) break; icount = 1./count; x1 = cvRound(sx*icount); y1 = cvRound(sy*icount); s0 = cvRound(s0*icount); s1 = cvRound(s1*icount); s2 = cvRound(s2*icount); stop_flag = (x0 == x1 && y0 == y1) || std::abs(x1-x0) + std::abs(y1-y0) + tab[s0 - c0 + 255] + tab[s1 - c1 + 255] + tab[s2 - c2 + 255] <= termcrit.epsilon; x0 = x1; y0 = y1; c0 = s0; c1 = s1; c2 = s2; if( stop_flag ) break; } dptr[0] = (uchar)c0; dptr[1] = (uchar)c1; dptr[2] = (uchar)c2; } } } }
static void create(OutputArray arr, Size submatSize, int type) { int sizes[] = {submatSize.width, submatSize.height}; arr.create(sizeof(sizes)/sizeof(sizes[0]), sizes, type); }
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 T=%s -D T1=%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; } 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_sum); } size_t globalsize[2] = { result.cols, result.rows }; return k.run(2, globalsize, NULL, false); }
static bool convolve_dft(InputArray _image, InputArray _templ, OutputArray _result) { ConvolveBuf buf; CV_Assert(_image.type() == CV_32F); CV_Assert(_templ.type() == CV_32F); buf.create(_image.size(), _templ.size()); _result.create(buf.result_size, CV_32F); UMat image = _image.getUMat(); UMat templ = _templ.getUMat(); UMat result = _result.getUMat(); Size& block_size = buf.block_size; Size& dft_size = buf.dft_size; UMat& image_block = buf.image_block; UMat& templ_block = buf.templ_block; UMat& result_data = buf.result_data; UMat& image_spect = buf.image_spect; UMat& templ_spect = buf.templ_spect; UMat& result_spect = buf.result_spect; UMat templ_roi = templ; copyMakeBorder(templ_roi, templ_block, 0, templ_block.rows - templ_roi.rows, 0, templ_block.cols - templ_roi.cols, BORDER_ISOLATED); dft(templ_block, templ_spect, 0, templ.rows); // Process all blocks of the result matrix for (int y = 0; y < result.rows; y += block_size.height) { for (int x = 0; x < result.cols; x += block_size.width) { Size image_roi_size(std::min(x + dft_size.width, image.cols) - x, std::min(y + dft_size.height, image.rows) - y); Rect roi0(x, y, image_roi_size.width, image_roi_size.height); UMat image_roi(image, roi0); copyMakeBorder(image_roi, image_block, 0, image_block.rows - image_roi.rows, 0, image_block.cols - image_roi.cols, BORDER_ISOLATED); dft(image_block, image_spect, 0); mulSpectrums(image_spect, templ_spect, result_spect, 0, true); dft(result_spect, result_data, cv::DFT_INVERSE | cv::DFT_REAL_OUTPUT | cv::DFT_SCALE); Size result_roi_size(std::min(x + block_size.width, result.cols) - x, std::min(y + block_size.height, result.rows) - y); Rect roi1(x, y, result_roi_size.width, result_roi_size.height); Rect roi2(0, 0, result_roi_size.width, result_roi_size.height); UMat result_roi(result, roi1); UMat result_block(result_data, roi2); result_block.copyTo(result_roi); } } return true; }
void IPPE::PoseSolver::computeRotations(double j00, double j01, double j10, double j11, double p, double q, OutputArray _R1, OutputArray _R2) { //This is fairly optimized code which makes it hard to understand. The matlab code is certainly easier to read. _R1.create(3, 3, CV_64FC1); _R2.create(3, 3, CV_64FC1); double a00, a01, a10, a11, ata00, ata01, ata11, b00, b01, b10, b11, binv00, binv01, binv10, binv11; //double rv00, rv01, rv02, rv10, rv11, rv12, rv20, rv21, rv22; double rtilde00, rtilde01, rtilde10, rtilde11; double rtilde00_2, rtilde01_2, rtilde10_2, rtilde11_2; double b0, b1, gamma, dtinv; double sp; Mat Rv; cv::Mat v(3,1,CV_64FC1); v.at<double>(0) = p; v.at<double>(1) = q; v.at<double>(2) = 1; rotateVec2ZAxis(v,Rv); Rv = Rv.t(); //setup the 2x2 SVD decomposition: double rv00, rv01, rv02; double rv10, rv11, rv12; double rv20, rv21, rv22; rv00 = Rv.at<double>(0,0); rv01 = Rv.at<double>(0,1); rv02 = Rv.at<double>(0,2); rv10 = Rv.at<double>(1,0); rv11 = Rv.at<double>(1,1); rv12 = Rv.at<double>(1,2); rv20 = Rv.at<double>(2,0); rv21 = Rv.at<double>(2,1); rv22 = Rv.at<double>(2,2); b00 = rv00 - p * rv20; b01 = rv01 - p * rv21; b10 = rv10 - q * rv20; b11 = rv11 - q * rv21; dtinv = 1.0 / ((b00 * b11 - b01 * b10)); binv00 = dtinv * b11; binv01 = -dtinv * b01; binv10 = -dtinv * b10; binv11 = dtinv * b00; a00 = binv00 * j00 + binv01 * j10; a01 = binv00 * j01 + binv01 * j11; a10 = binv10 * j00 + binv11 * j10; a11 = binv10 * j01 + binv11 * j11; //compute the largest singular value of A: ata00 = a00 * a00 + a01 * a01; ata01 = a00 * a10 + a01 * a11; ata11 = a10 * a10 + a11 * a11; gamma = sqrt(0.5 * (ata00 + ata11 + sqrt((ata00 - ata11) * (ata00 - ata11) + 4.0 * ata01 * ata01))); //reconstruct the full rotation matrices: rtilde00 = a00 / gamma; rtilde01 = a01 / gamma; rtilde10 = a10 / gamma; rtilde11 = a11 / gamma; rtilde00_2 = rtilde00 * rtilde00; rtilde01_2 = rtilde01 * rtilde01; rtilde10_2 = rtilde10 * rtilde10; rtilde11_2 = rtilde11 * rtilde11; b0 = sqrt(-rtilde00_2 - rtilde10_2 + 1); b1 = sqrt(-rtilde01_2 - rtilde11_2 + 1); sp = (-rtilde00 * rtilde01 - rtilde10 * rtilde11); if (sp < 0) { b1 = -b1; } //store results: Mat R1 = _R1.getMat(); Mat R2 = _R2.getMat(); R1.at<double>(0, 0) = (rtilde00)*rv00 + (rtilde10)*rv01 + (b0)*rv02; R1.at<double>(0, 1) = (rtilde01)*rv00 + (rtilde11)*rv01 + (b1)*rv02; R1.at<double>(0, 2) = (b1 * rtilde10 - b0 * rtilde11) * rv00 + (b0 * rtilde01 - b1 * rtilde00) * rv01 + (rtilde00 * rtilde11 - rtilde01 * rtilde10) * rv02; R1.at<double>(1, 0) = (rtilde00)*rv10 + (rtilde10)*rv11 + (b0)*rv12; R1.at<double>(1, 1) = (rtilde01)*rv10 + (rtilde11)*rv11 + (b1)*rv12; R1.at<double>(1, 2) = (b1 * rtilde10 - b0 * rtilde11) * rv10 + (b0 * rtilde01 - b1 * rtilde00) * rv11 + (rtilde00 * rtilde11 - rtilde01 * rtilde10) * rv12; R1.at<double>(2, 0) = (rtilde00)*rv20 + (rtilde10)*rv21 + (b0)*rv22; R1.at<double>(2, 1) = (rtilde01)*rv20 + (rtilde11)*rv21 + (b1)*rv22; R1.at<double>(2, 2) = (b1 * rtilde10 - b0 * rtilde11) * rv20 + (b0 * rtilde01 - b1 * rtilde00) * rv21 + (rtilde00 * rtilde11 - rtilde01 * rtilde10) * rv22; R2.at<double>(0, 0) = (rtilde00)*rv00 + (rtilde10)*rv01 + (-b0) * rv02; R2.at<double>(0, 1) = (rtilde01)*rv00 + (rtilde11)*rv01 + (-b1) * rv02; R2.at<double>(0, 2) = (b0 * rtilde11 - b1 * rtilde10) * rv00 + (b1 * rtilde00 - b0 * rtilde01) * rv01 + (rtilde00 * rtilde11 - rtilde01 * rtilde10) * rv02; R2.at<double>(1, 0) = (rtilde00)*rv10 + (rtilde10)*rv11 + (-b0) * rv12; R2.at<double>(1, 1) = (rtilde01)*rv10 + (rtilde11)*rv11 + (-b1) * rv12; R2.at<double>(1, 2) = (b0 * rtilde11 - b1 * rtilde10) * rv10 + (b1 * rtilde00 - b0 * rtilde01) * rv11 + (rtilde00 * rtilde11 - rtilde01 * rtilde10) * rv12; R2.at<double>(2, 0) = (rtilde00)*rv20 + (rtilde10)*rv21 + (-b0) * rv22; R2.at<double>(2, 1) = (rtilde01)*rv20 + (rtilde11)*rv21 + (-b1) * rv22; R2.at<double>(2, 2) = (b0 * rtilde11 - b1 * rtilde10) * rv20 + (b1 * rtilde00 - b0 * rtilde01) * rv21 + (rtilde00 * rtilde11 - rtilde01 * rtilde10) * rv22; }
void IPPE::PoseSolver::computeTranslation(InputArray _objectPoints, InputArray _normalizedImgPoints, InputArray _R, OutputArray _t) { //This is solved by building the linear system At = b, where t corresponds to the (unknown) translation. //This is then inverted with the associated normal equations to give t = inv(transpose(A)*A)*transpose(A)*b //For efficiency we only store the coefficients of (transpose(A)*A) and (transpose(A)*b) assert(_objectPoints.type() == CV_64FC2); assert(_normalizedImgPoints.type() == CV_64FC2); assert(_R.type() == CV_64FC1); assert((_R.rows() == 3) & (_R.cols() == 3)); assert((_objectPoints.rows() == 1) | (_objectPoints.cols() == 1)); assert((_normalizedImgPoints.rows() == 1) | (_normalizedImgPoints.cols() == 1)); size_t n = _normalizedImgPoints.rows() * _normalizedImgPoints.cols(); assert(n == static_cast<size_t>(_objectPoints.rows() * _objectPoints.cols())); cv::Mat objectPoints = _objectPoints.getMat(); cv::Mat imgPoints = _normalizedImgPoints.getMat(); _t.create(3, 1, CV_64FC1); cv::Mat R = _R.getMat(); //coefficients of (transpose(A)*A) double ATA00 = n; double ATA02 = 0; double ATA11 = n; double ATA12 = 0; double ATA20 = 0; double ATA21 = 0; double ATA22 = 0; //coefficients of (transpose(A)*b) double ATb0 = 0; double ATb1 = 0; double ATb2 = 0; //S gives inv(transpose(A)*A)/det(A)^2 double S00, S01, S02; double S10, S11, S12; double S20, S21, S22; double rx, ry, rz; double a2; double b2; double bx, by; //now loop through each point and increment the coefficients: for (size_t i = 0; i < n; i++) { rx = R.at<double>(0, 0) * objectPoints.at<Vec2d>(i)(0) + R.at<double>(0, 1) * objectPoints.at<Vec2d>(i)(1); ry = R.at<double>(1, 0) * objectPoints.at<Vec2d>(i)(0) + R.at<double>(1, 1) * objectPoints.at<Vec2d>(i)(1); rz = R.at<double>(2, 0) * objectPoints.at<Vec2d>(i)(0) + R.at<double>(2, 1) * objectPoints.at<Vec2d>(i)(1); a2 = -imgPoints.at<Vec2d>(i)(0); b2 = -imgPoints.at<Vec2d>(i)(1); ATA02 = ATA02 + a2; ATA12 = ATA12 + b2; ATA20 = ATA20 + a2; ATA21 = ATA21 + b2; ATA22 = ATA22 + a2 * a2 + b2 * b2; bx = -a2 * rz - rx; by = -b2 * rz - ry; ATb0 = ATb0 + bx; ATb1 = ATb1 + by; ATb2 = ATb2 + a2 * bx + b2 * by; } double detAInv = 1.0 / (ATA00 * ATA11 * ATA22 - ATA00 * ATA12 * ATA21 - ATA02 * ATA11 * ATA20); //construct S: S00 = ATA11 * ATA22 - ATA12 * ATA21; S01 = ATA02 * ATA21; S02 = -ATA02 * ATA11; S10 = ATA12 * ATA20; S11 = ATA00 * ATA22 - ATA02 * ATA20; S12 = -ATA00 * ATA12; S20 = -ATA11 * ATA20; S21 = -ATA00 * ATA21; S22 = ATA00 * ATA11; //solve t: Mat t = _t.getMat(); t.at<double>(0) = detAInv * (S00 * ATb0 + S01 * ATb1 + S02 * ATb2); t.at<double>(1) = detAInv * (S10 * ATb0 + S11 * ATb1 + S12 * ATb2); t.at<double>(2) = detAInv * (S20 * ATb0 + S21 * ATb1 + S22 * ATb2); }
void cv::seamlessClone(InputArray _src, InputArray _dst, InputArray _mask, Point p, OutputArray _blend, int flags) { Mat src = _src.getMat(); Mat dest = _dst.getMat(); Mat mask = _mask.getMat(); _blend.create(dest.size(), CV_8UC3); Mat blend = _blend.getMat(); int minx = INT_MAX, miny = INT_MAX, maxx = INT_MIN, maxy = INT_MIN; int h = mask.size().height; int w = mask.size().width; Mat gray = Mat(mask.size(),CV_8UC1); Mat dst_mask = Mat::zeros(dest.size(),CV_8UC1); Mat cs_mask = Mat::zeros(src.size(),CV_8UC3); Mat cd_mask = Mat::zeros(dest.size(),CV_8UC3); if(mask.channels() == 3) cvtColor(mask, gray, COLOR_BGR2GRAY ); else gray = mask; for(int i=0;i<h;i++) { for(int j=0;j<w;j++) { if(gray.at<uchar>(i,j) == 255) { minx = std::min(minx,i); maxx = std::max(maxx,i); miny = std::min(miny,j); maxy = std::max(maxy,j); } } } int lenx = maxx - minx; int leny = maxy - miny; int minxd = p.y - lenx/2; int maxxd = p.y + lenx/2; int minyd = p.x - leny/2; int maxyd = p.x + leny/2; CV_Assert(minxd >= 0 && minyd >= 0 && maxxd <= dest.rows && maxyd <= dest.cols); Rect roi_d(minyd,minxd,leny,lenx); Rect roi_s(miny,minx,leny,lenx); Mat destinationROI = dst_mask(roi_d); Mat sourceROI = cs_mask(roi_s); gray(roi_s).copyTo(destinationROI); src(roi_s).copyTo(sourceROI,gray(roi_s)); destinationROI = cd_mask(roi_d); cs_mask(roi_s).copyTo(destinationROI); Cloning obj; obj.normal_clone(dest,cd_mask,dst_mask,blend,flags); }