void convertToVASurface(InputArray src, VASurfaceID surface, Size size) { (void)src; (void)surface; (void)size; #if !defined(HAVE_VAAPI) NO_VAAPI_SUPPORT_ERROR; #elif !defined(HAVE_OPENCL) NO_OPENCL_SUPPORT_ERROR; #else if (!contextInitialized) CV_Error(cv::Error::OpenCLInitError, "OpenCL: Context for VA-API interop hasn't been created"); const int stype = CV_8UC4; int srcType = src.type(); CV_Assert(srcType == stype); Size srcSize = src.size(); CV_Assert(srcSize.width == size.width && srcSize.height == size.height); UMat u = src.getUMat(); // TODO Add support for roi CV_Assert(u.offset == 0); CV_Assert(u.isContinuous()); cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ); using namespace cv::ocl; Context& ctx = Context::getDefault(); cl_context context = (cl_context)ctx.ptr(); cl_int status = 0; cl_mem clImageY = clCreateFromVA_APIMediaSurfaceINTEL(context, CL_MEM_WRITE_ONLY, &surface, 0, &status); if (status != CL_SUCCESS) CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromVA_APIMediaSurfaceINTEL failed (Y plane)"); cl_mem clImageUV = clCreateFromVA_APIMediaSurfaceINTEL(context, CL_MEM_WRITE_ONLY, &surface, 1, &status); if (status != CL_SUCCESS) CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromVA_APIMediaSurfaceINTEL failed (UV plane)"); cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr(); cl_mem images[2] = { clImageY, clImageUV }; status = clEnqueueAcquireVA_APIMediaSurfacesINTEL(q, 2, images, 0, NULL, NULL); if (status != CL_SUCCESS) CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireVA_APIMediaSurfacesINTEL failed"); if (!ocl::ocl_convert_bgr_to_nv12(clBuffer, (int)u.step[0], u.cols, u.rows, clImageY, clImageUV)) CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: ocl_convert_bgr_to_nv12 failed"); clEnqueueReleaseVA_APIMediaSurfacesINTEL(q, 2, images, 0, NULL, NULL); if (status != CL_SUCCESS) CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseVA_APIMediaSurfacesINTEL failed"); status = clFinish(q); // TODO Use events if (status != CL_SUCCESS) CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed"); status = clReleaseMemObject(clImageY); // TODO RAII if (status != CL_SUCCESS) CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed (Y plane)"); status = clReleaseMemObject(clImageUV); if (status != CL_SUCCESS) CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed (UV plane)"); #endif }
bool OCL4DNNPool<Dtype>::Forward(const UMat& bottom, UMat& top, UMat& top_mask) { bool ret = true; size_t global[] = { 128 * 128 }; size_t local[] = { 128 }; // support 2D case switch (pool_method_) { case LIBDNN_POOLING_METHOD_MAX: { bool haveMask = !top_mask.empty(); ocl::Kernel oclk_max_pool_forward( haveMask ? CL_KERNEL_SELECT("max_pool_forward_mask") : CL_KERNEL_SELECT("max_pool_forward"), ocl::dnn::ocl4dnn_pooling_oclsrc, format("-D KERNEL_MAX_POOL=1 -D KERNEL_W=%d -D KERNEL_H=%d" " -D STRIDE_W=%d -D STRIDE_H=%d" " -D PAD_W=%d -D PAD_H=%d%s", kernel_w_, kernel_h_, stride_w_, stride_h_, pad_w_, pad_h_, haveMask ? " -D HAVE_MASK=1" : "" )); if (oclk_max_pool_forward.empty()) return false; oclk_max_pool_forward.args( count_, ocl::KernelArg::PtrReadOnly(bottom), channels_, height_, width_, pooled_height_, pooled_width_, ocl::KernelArg::PtrWriteOnly(top), ocl::KernelArg::PtrWriteOnly(top_mask) ); ret = oclk_max_pool_forward.run(1, global, local, false); } break; case LIBDNN_POOLING_METHOD_AVE: { CV_Assert(top_mask.empty()); ocl::Kernel oclk_ave_pool_forward(CL_KERNEL_SELECT("ave_pool_forward"), ocl::dnn::ocl4dnn_pooling_oclsrc, format("-D KERNEL_AVE_POOL=1 -D KERNEL_W=%d -D KERNEL_H=%d" " -D STRIDE_W=%d -D STRIDE_H=%d" " -D PAD_W=%d -D PAD_H=%d%s", kernel_w_, kernel_h_, stride_w_, stride_h_, pad_w_, pad_h_, avePoolPaddedArea ? " -D AVE_POOL_PADDING_AREA" : "" )); if (oclk_ave_pool_forward.empty()) return false; oclk_ave_pool_forward.args( count_, ocl::KernelArg::PtrReadOnly(bottom), channels_, height_, width_, pooled_height_, pooled_width_, ocl::KernelArg::PtrWriteOnly(top) ); ret = oclk_ave_pool_forward.run(1, global, local, false); } break; case LIBDNN_POOLING_METHOD_STO: { CV_Assert(top_mask.empty()); ocl::Kernel oclk_sto_pool_forward(CL_KERNEL_SELECT("sto_pool_forward_test"), ocl::dnn::ocl4dnn_pooling_oclsrc, format("-D KERNEL_STO_POOL=1 -D KERNEL_W=%d -D KERNEL_H=%d" " -D STRIDE_W=%d -D STRIDE_H=%d", kernel_w_, kernel_h_, stride_w_, stride_h_ )); if (oclk_sto_pool_forward.empty()) return false; oclk_sto_pool_forward.args( count_, ocl::KernelArg::PtrReadOnly(bottom), channels_, height_, width_, pooled_height_, pooled_width_, ocl::KernelArg::PtrWriteOnly(top) ); ret = oclk_sto_pool_forward.run(1, global, local, false); } break; default: { ret = false; LOG(FATAL)<< "Unknown pooling method."; } } return ret; }
void UMatToVector(const UMat & um, std::vector<Point2f> & v) const { v.resize(um.size().area()); um.copyTo(Mat(um.size(), CV_32FC2, &v[0])); }
int main(int argc, char** argv) { const char* keys = "{ i input | | specify input image }" "{ h help | | print help message }"; cv::CommandLineParser args(argc, argv, keys); if (args.has("help")) { cout << "Usage : " << argv[0] << " [options]" << endl; cout << "Available options:" << endl; args.printMessage(); return EXIT_SUCCESS; } cv::ocl::Context ctx = cv::ocl::Context::getDefault(); if (!ctx.ptr()) { cerr << "OpenCL is not available" << endl; return 1; } cv::ocl::Device device = cv::ocl::Device::getDefault(); if (!device.compilerAvailable()) { cerr << "OpenCL compiler is not available" << endl; return 1; } UMat src; { string image_file = args.get<string>("i"); if (!image_file.empty()) { Mat image = imread(image_file); if (image.empty()) { cout << "error read image: " << image_file << endl; return 1; } cvtColor(image, src, COLOR_BGR2GRAY); } else { Mat frame(cv::Size(640, 480), CV_8U, Scalar::all(128)); Point p(frame.cols / 2, frame.rows / 2); line(frame, Point(0, frame.rows / 2), Point(frame.cols, frame.rows / 2), 1); circle(frame, p, 200, Scalar(32, 32, 32), 8, LINE_AA); string str = "OpenCL"; int baseLine = 0; Size box = getTextSize(str, FONT_HERSHEY_COMPLEX, 2, 5, &baseLine); putText(frame, str, Point((frame.cols - box.width) / 2, (frame.rows - box.height) / 2 + baseLine), FONT_HERSHEY_COMPLEX, 2, Scalar(255, 255, 255), 5, LINE_AA); frame.copyTo(src); } } cv::String module_name; // empty to disable OpenCL cache { cout << "OpenCL program source: " << endl; cout << "======================================================================================================" << endl; cout << opencl_kernel_src << endl; cout << "======================================================================================================" << endl; //! [Define OpenCL program source] cv::ocl::ProgramSource source(module_name, "simple", opencl_kernel_src, ""); //! [Define OpenCL program source] //! [Compile/build OpenCL for current OpenCL device] cv::String errmsg; cv::ocl::Program program(source, "", errmsg); if (program.ptr() == NULL) { cerr << "Can't compile OpenCL program:" << endl << errmsg << endl; return 1; } //! [Compile/build OpenCL for current OpenCL device] if (!errmsg.empty()) { cout << "OpenCL program build log:" << endl << errmsg << endl; } //! [Get OpenCL kernel by name] cv::ocl::Kernel k("magnutude_filter_8u", program); if (k.empty()) { cerr << "Can't get OpenCL kernel" << endl; return 1; } //! [Get OpenCL kernel by name] UMat result(src.size(), CV_8UC1); //! [Define kernel parameters and run] size_t globalSize[2] = {(size_t)src.cols, (size_t)src.rows}; size_t localSize[2] = {8, 8}; bool executionResult = k .args( cv::ocl::KernelArg::ReadOnlyNoSize(src), // size is not used (similar to 'dst' size) cv::ocl::KernelArg::WriteOnly(result), (float)2.0 ) .run(2, globalSize, localSize, true); if (!executionResult) { cerr << "OpenCL kernel launch failed" << endl; return 1; } //! [Define kernel parameters and run] imshow("Source", src); imshow("Result", result); for (;;) { int key = waitKey(); if (key == 27/*ESC*/ || key == 'q' || key == 'Q') break; } } return 0; }
bool BTVL1_Base::ocl_process(InputArrayOfArrays _src, OutputArray _dst, InputArrayOfArrays _forwardMotions, InputArrayOfArrays _backwardMotions, int baseIdx) { std::vector<UMat> & src = *(std::vector<UMat> *)_src.getObj(), & forwardMotions = *(std::vector<UMat> *)_forwardMotions.getObj(), & backwardMotions = *(std::vector<UMat> *)_backwardMotions.getObj(); // update blur filter and btv weights if (!filter_ || 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_); Mat(btvWeights_, true).copyTo(ubtvWeights_); curBtvKernelSize_ = btvKernelSize_; curAlpha_ = alpha_; } // calc high res motions calcRelativeMotions(forwardMotions, backwardMotions, ulowResForwardMotions_, ulowResBackwardMotions_, baseIdx, src[0].size()); upscaleMotions(ulowResForwardMotions_, uhighResForwardMotions_, scale_); upscaleMotions(ulowResBackwardMotions_, uhighResBackwardMotions_, scale_); uforwardMaps_.resize(uhighResForwardMotions_.size()); ubackwardMaps_.resize(uhighResForwardMotions_.size()); for (size_t i = 0; i < uhighResForwardMotions_.size(); ++i) buildMotionMaps(uhighResForwardMotions_[i], uhighResBackwardMotions_[i], uforwardMaps_[i], ubackwardMaps_[i]); // initial estimation const Size lowResSize = src[0].size(); const Size highResSize(lowResSize.width * scale_, lowResSize.height * scale_); resize(src[baseIdx], uhighRes_, highResSize, 0, 0, INTER_LINEAR); // TODO // iterations udiffTerm_.create(highResSize, uhighRes_.type()); ua_.create(highResSize, uhighRes_.type()); ub_.create(highResSize, uhighRes_.type()); uc_.create(lowResSize, uhighRes_.type()); for (int i = 0; i < iterations_; ++i) { udiffTerm_.setTo(Scalar::all(0)); for (size_t k = 0; k < src.size(); ++k) { // a = M * Ih remap(uhighRes_, ua_, ubackwardMaps_[k], noArray(), INTER_NEAREST); // b = HM * Ih GaussianBlur(ua_, ub_, Size(blurKernelSize_, blurKernelSize_), blurSigma_); // c = DHM * Ih resize(ub_, uc_, lowResSize, 0, 0, INTER_NEAREST); diffSign(src[k], uc_, uc_); // a = Dt * diff upscale(uc_, ua_, scale_); // b = HtDt * diff GaussianBlur(ua_, ub_, Size(blurKernelSize_, blurKernelSize_), blurSigma_); // a = MtHtDt * diff remap(ub_, ua_, uforwardMaps_[k], noArray(), INTER_NEAREST); add(udiffTerm_, ua_, udiffTerm_); } if (lambda_ > 0) { calcBtvRegularization(uhighRes_, uregTerm_, btvKernelSize_, btvWeights_, ubtvWeights_); addWeighted(udiffTerm_, 1.0, uregTerm_, -lambda_, 0.0, udiffTerm_); } addWeighted(uhighRes_, 1.0, udiffTerm_, tau_, 0.0, uhighRes_); } Rect inner(btvKernelSize_, btvKernelSize_, uhighRes_.cols - 2 * btvKernelSize_, uhighRes_.rows - 2 * btvKernelSize_); uhighRes_(inner).copyTo(_dst); return true; }
static const Mat get(const UMat& m) { return m.getMat(ACCESS_READ); }
int cv::meanShift( InputArray _probImage, Rect& window, TermCriteria criteria ) { CV_INSTRUMENT_REGION() Size size; int cn; Mat mat; UMat umat; bool isUMat = _probImage.isUMat(); if (isUMat) umat = _probImage.getUMat(), cn = umat.channels(), size = umat.size(); else mat = _probImage.getMat(), cn = mat.channels(), size = mat.size(); Rect cur_rect = window; CV_Assert( cn == 1 ); if( window.height <= 0 || window.width <= 0 ) CV_Error( Error::StsBadArg, "Input window has non-positive sizes" ); window = window & Rect(0, 0, size.width, size.height); double eps = (criteria.type & TermCriteria::EPS) ? std::max(criteria.epsilon, 0.) : 1.; eps = cvRound(eps*eps); int i, niters = (criteria.type & TermCriteria::MAX_ITER) ? std::max(criteria.maxCount, 1) : 100; for( i = 0; i < niters; i++ ) { cur_rect = cur_rect & Rect(0, 0, size.width, size.height); if( cur_rect == Rect() ) { cur_rect.x = size.width/2; cur_rect.y = size.height/2; } cur_rect.width = std::max(cur_rect.width, 1); cur_rect.height = std::max(cur_rect.height, 1); Moments m = isUMat ? moments(umat(cur_rect)) : moments(mat(cur_rect)); // Calculating center of mass if( fabs(m.m00) < DBL_EPSILON ) break; int dx = cvRound( m.m10/m.m00 - window.width*0.5 ); int dy = cvRound( m.m01/m.m00 - window.height*0.5 ); int nx = std::min(std::max(cur_rect.x + dx, 0), size.width - cur_rect.width); int ny = std::min(std::max(cur_rect.y + dy, 0), size.height - cur_rect.height); dx = nx - cur_rect.x; dy = ny - cur_rect.y; cur_rect.x = nx; cur_rect.y = ny; // Check for coverage centers mass & window if( dx*dx + dy*dy < eps ) break; } window = cur_rect; return i; }
int main(int argc, char** argv) { const char* keys = "{ i input | ../data/pic1.png | specify input image }" "{ o output | squares_output.jpg | specify output save path}" "{ h help | | print help message }" "{ m cpu_mode | | run without OpenCL }"; CommandLineParser cmd(argc, argv, keys); if(cmd.has("help")) { cout << "Usage : squares [options]" << endl; cout << "Available options:" << endl; cmd.printMessage(); return EXIT_SUCCESS; } if (cmd.has("cpu_mode")) { ocl::setUseOpenCL(false); std::cout << "OpenCL was disabled" << std::endl; } string inputName = cmd.get<string>("i"); string outfile = cmd.get<string>("o"); int iterations = 10; namedWindow( wndname, WINDOW_AUTOSIZE ); vector<vector<Point> > squares; UMat image; imread(inputName, 1).copyTo(image); if( image.empty() ) { cout << "Couldn't load " << inputName << endl; cmd.printMessage(); return EXIT_FAILURE; } int j = iterations; int64 t_cpp = 0; //warm-ups cout << "warming up ..." << endl; findSquares(image, squares); do { int64 t_start = cv::getTickCount(); findSquares(image, squares); t_cpp += cv::getTickCount() - t_start; t_start = cv::getTickCount(); cout << "run loop: " << j << endl; } while(--j); cout << "average time: " << 1000.0f * (double)t_cpp / getTickFrequency() / iterations << "ms" << endl; UMat result = drawSquaresBoth(image, squares); imshow(wndname, result); imwrite(outfile, result); waitKey(0); return EXIT_SUCCESS; }
static bool ocl_Canny(InputArray _src, const UMat& dx_, const UMat& dy_, OutputArray _dst, float low_thresh, float high_thresh, int aperture_size, bool L2gradient, int cn, const Size & size) { CV_INSTRUMENT_REGION_OPENCL() UMat map; const ocl::Device &dev = ocl::Device::getDefault(); int max_wg_size = (int)dev.maxWorkGroupSize(); int lSizeX = 32; int lSizeY = max_wg_size / 32; if (lSizeY == 0) { lSizeX = 16; lSizeY = max_wg_size / 16; } if (lSizeY == 0) { lSizeY = 1; } if (aperture_size == 7) { low_thresh = low_thresh / 16.0f; high_thresh = high_thresh / 16.0f; } if (L2gradient) { low_thresh = std::min(32767.0f, low_thresh); high_thresh = std::min(32767.0f, high_thresh); if (low_thresh > 0) low_thresh *= low_thresh; if (high_thresh > 0) high_thresh *= high_thresh; } int low = cvFloor(low_thresh), high = cvFloor(high_thresh); if (!useCustomDeriv && aperture_size == 3 && !_src.isSubmatrix()) { /* stage1_with_sobel: Sobel operator Calc magnitudes Non maxima suppression Double thresholding */ char cvt[40]; ocl::Kernel with_sobel("stage1_with_sobel", ocl::imgproc::canny_oclsrc, format("-D WITH_SOBEL -D cn=%d -D TYPE=%s -D convert_floatN=%s -D floatN=%s -D GRP_SIZEX=%d -D GRP_SIZEY=%d%s", cn, ocl::memopTypeToStr(_src.depth()), ocl::convertTypeStr(_src.depth(), CV_32F, cn, cvt), ocl::typeToStr(CV_MAKE_TYPE(CV_32F, cn)), lSizeX, lSizeY, L2gradient ? " -D L2GRAD" : "")); if (with_sobel.empty()) return false; UMat src = _src.getUMat(); map.create(size, CV_32S); with_sobel.args(ocl::KernelArg::ReadOnly(src), ocl::KernelArg::WriteOnlyNoSize(map), (float) low, (float) high); size_t globalsize[2] = { (size_t)size.width, (size_t)size.height }, localsize[2] = { (size_t)lSizeX, (size_t)lSizeY }; if (!with_sobel.run(2, globalsize, localsize, false)) return false; } else { /* stage1_without_sobel: Calc magnitudes Non maxima suppression Double thresholding */ double scale = 1.0; if (aperture_size == 7) { scale = 1 / 16.0; } UMat dx, dy; if (!useCustomDeriv) { Sobel(_src, dx, CV_16S, 1, 0, aperture_size, scale, 0, BORDER_REPLICATE); Sobel(_src, dy, CV_16S, 0, 1, aperture_size, scale, 0, BORDER_REPLICATE); } else { dx = dx_; dy = dy_; } ocl::Kernel without_sobel("stage1_without_sobel", ocl::imgproc::canny_oclsrc, format("-D WITHOUT_SOBEL -D cn=%d -D GRP_SIZEX=%d -D GRP_SIZEY=%d%s", cn, lSizeX, lSizeY, L2gradient ? " -D L2GRAD" : "")); if (without_sobel.empty()) return false; map.create(size, CV_32S); without_sobel.args(ocl::KernelArg::ReadOnlyNoSize(dx), ocl::KernelArg::ReadOnlyNoSize(dy), ocl::KernelArg::WriteOnly(map), low, high); size_t globalsize[2] = { (size_t)size.width, (size_t)size.height }, localsize[2] = { (size_t)lSizeX, (size_t)lSizeY }; if (!without_sobel.run(2, globalsize, localsize, false)) return false; } int PIX_PER_WI = 8; /* stage2: hysteresis (add weak edges if they are connected with strong edges) */ int sizey = lSizeY / PIX_PER_WI; if (sizey == 0) sizey = 1; size_t globalsize[2] = { (size_t)size.width, ((size_t)size.height + PIX_PER_WI - 1) / PIX_PER_WI }, localsize[2] = { (size_t)lSizeX, (size_t)sizey }; ocl::Kernel edgesHysteresis("stage2_hysteresis", ocl::imgproc::canny_oclsrc, format("-D STAGE2 -D PIX_PER_WI=%d -D LOCAL_X=%d -D LOCAL_Y=%d", PIX_PER_WI, lSizeX, sizey)); if (edgesHysteresis.empty()) return false; edgesHysteresis.args(ocl::KernelArg::ReadWrite(map)); if (!edgesHysteresis.run(2, globalsize, localsize, false)) return false; // get edges ocl::Kernel getEdgesKernel("getEdges", ocl::imgproc::canny_oclsrc, format("-D GET_EDGES -D PIX_PER_WI=%d", PIX_PER_WI)); if (getEdgesKernel.empty()) return false; _dst.create(size, CV_8UC1); UMat dst = _dst.getUMat(); getEdgesKernel.args(ocl::KernelArg::ReadOnly(map), ocl::KernelArg::WriteOnlyNoSize(dst)); return getEdgesKernel.run(2, globalsize, NULL, false); }
cv::RotatedRect cv::CamShift( InputArray _probImage, Rect& window, TermCriteria criteria ) { CV_INSTRUMENT_REGION() const int TOLERANCE = 10; Size size; Mat mat; UMat umat; bool isUMat = _probImage.isUMat(); if (isUMat) umat = _probImage.getUMat(), size = umat.size(); else mat = _probImage.getMat(), size = mat.size(); meanShift( _probImage, window, criteria ); window.x -= TOLERANCE; if( window.x < 0 ) window.x = 0; window.y -= TOLERANCE; if( window.y < 0 ) window.y = 0; window.width += 2 * TOLERANCE; if( window.x + window.width > size.width ) window.width = size.width - window.x; window.height += 2 * TOLERANCE; if( window.y + window.height > size.height ) window.height = size.height - window.y; // Calculating moments in new center mass Moments m = isUMat ? moments(umat(window)) : moments(mat(window)); double m00 = m.m00, m10 = m.m10, m01 = m.m01; double mu11 = m.mu11, mu20 = m.mu20, mu02 = m.mu02; if( fabs(m00) < DBL_EPSILON ) return RotatedRect(); double inv_m00 = 1. / m00; int xc = cvRound( m10 * inv_m00 + window.x ); int yc = cvRound( m01 * inv_m00 + window.y ); double a = mu20 * inv_m00, b = mu11 * inv_m00, c = mu02 * inv_m00; // Calculating width & height double square = std::sqrt( 4 * b * b + (a - c) * (a - c) ); // Calculating orientation double theta = atan2( 2 * b, a - c + square ); // Calculating width & length of figure double cs = cos( theta ); double sn = sin( theta ); double rotate_a = cs * cs * mu20 + 2 * cs * sn * mu11 + sn * sn * mu02; double rotate_c = sn * sn * mu20 - 2 * cs * sn * mu11 + cs * cs * mu02; double length = std::sqrt( rotate_a * inv_m00 ) * 4; double width = std::sqrt( rotate_c * inv_m00 ) * 4; // In case, when tetta is 0 or 1.57... the Length & Width may be exchanged if( length < width ) { std::swap( length, width ); std::swap( cs, sn ); theta = CV_PI*0.5 - theta; } // Saving results int _xc = cvRound( xc ); int _yc = cvRound( yc ); int t0 = cvRound( fabs( length * cs )); int t1 = cvRound( fabs( width * sn )); t0 = MAX( t0, t1 ) + 2; window.width = MIN( t0, (size.width - _xc) * 2 ); t0 = cvRound( fabs( length * sn )); t1 = cvRound( fabs( width * cs )); t0 = MAX( t0, t1 ) + 2; window.height = MIN( t0, (size.height - _yc) * 2 ); window.x = MAX( 0, _xc - window.width / 2 ); window.y = MAX( 0, _yc - window.height / 2 ); window.width = MIN( size.width - window.x, window.width ); window.height = MIN( size.height - window.y, window.height ); RotatedRect box; box.size.height = (float)length; box.size.width = (float)width; box.angle = (float)((CV_PI*0.5+theta)*180./CV_PI); while(box.angle < 0) box.angle += 360; while(box.angle >= 360) box.angle -= 360; if(box.angle >= 180) box.angle -= 180; box.center = Point2f( window.x + window.width*0.5f, window.y + window.height*0.5f); return box; }
void ICPImpl::getAb<UMat>(const UMat& oldPts, const UMat& oldNrm, const UMat& newPts, const UMat& newNrm, Affine3f pose, int level, Matx66f &A, Vec6f &b) const { CV_TRACE_FUNCTION(); Size oldSize = oldPts.size(), newSize = newPts.size(); CV_Assert(oldSize == oldNrm.size()); CV_Assert(newSize == newNrm.size()); // calculate 1x7 vector ab to produce b and upper triangle of A: // [A|b] = ab*(ab^t) // and then reduce it across work groups cv::String errorStr; ocl::ProgramSource source = ocl::rgbd::icp_oclsrc; cv::String options = "-cl-fast-relaxed-math -cl-mad-enable"; ocl::Kernel k; k.create("getAb", source, options, &errorStr); if(k.empty()) throw std::runtime_error("Failed to create kernel: " + errorStr); size_t globalSize[2]; globalSize[0] = (size_t)newPts.cols; globalSize[1] = (size_t)newPts.rows; const ocl::Device& device = ocl::Device::getDefault(); // workaround for Intel's integrated GPU size_t wgsLimit = device.isIntel() ? 64 : device.maxWorkGroupSize(); size_t memSize = device.localMemSize(); // local memory should keep upperTriangles for all threads in group for reduce const size_t ltsz = UTSIZE*sizeof(float); const size_t lcols = 32; size_t lrows = min(memSize/ltsz, wgsLimit)/lcols; // round lrows down to 2^n lrows = roundDownPow2(lrows); size_t localSize[2] = {lcols, lrows}; Size ngroups((int)divUp(globalSize[0], (unsigned int)localSize[0]), (int)divUp(globalSize[1], (unsigned int)localSize[1])); // size of local buffer for group-wide reduce size_t lsz = localSize[0]*localSize[1]*ltsz; Intr::Projector proj = intrinsics.scale(level).makeProjector(); Vec2f fxy(proj.fx, proj.fy), cxy(proj.cx, proj.cy); UMat& groupedSumGpu = groupedSumBuffers[level]; groupedSumGpu.create(Size(ngroups.width*UTSIZE, ngroups.height), CV_32F); groupedSumGpu.setTo(0); // TODO: optimization possible: // samplers instead of oldPts/oldNrm (mask needed) k.args(ocl::KernelArg::ReadOnlyNoSize(oldPts), ocl::KernelArg::ReadOnlyNoSize(oldNrm), oldSize, ocl::KernelArg::ReadOnlyNoSize(newPts), ocl::KernelArg::ReadOnlyNoSize(newNrm), newSize, ocl::KernelArg::Constant(pose.matrix.val, sizeof(pose.matrix.val)), fxy.val, cxy.val, distanceThreshold*distanceThreshold, cos(angleThreshold), //TODO: replace by KernelArg::Local(lsz) ocl::KernelArg(ocl::KernelArg::LOCAL, 0, 1, 1, 0, lsz), ocl::KernelArg::WriteOnlyNoSize(groupedSumGpu) ); if(!k.run(2, globalSize, localSize, true)) throw std::runtime_error("Failed to run kernel"); float upperTriangle[UTSIZE]; for(int i = 0; i < UTSIZE; i++) upperTriangle[i] = 0; Mat groupedSumCpu = groupedSumGpu.getMat(ACCESS_READ); for(int y = 0; y < ngroups.height; y++) { const float* rowr = groupedSumCpu.ptr<float>(y); for(int x = 0; x < ngroups.width; x++) { const float* p = rowr + x*UTSIZE; for(int j = 0; j < UTSIZE; j++) { upperTriangle[j] += p[j]; } } } groupedSumCpu.release(); ABtype sumAB = ABtype::zeros(); int pos = 0; for(int i = 0; i < 6; i++) { for(int j = i; j < 7; j++) { sumAB(i, j) = upperTriangle[pos++]; } } // splitting AB matrix to A and b for(int i = 0; i < 6; i++) { // augment lower triangle of A by symmetry for(int j = i; j < 6; j++) { A(i, j) = A(j, i) = sumAB(i, j); } b(i) = sumAB(i, 6); } }
Mosaic::Status Mosaic::composePanorama(InputArrayOfArrays images, OutputArray pano) { LOGLN("Warping images (auxiliary)... "); std::vector<UMat> imgs; images.getUMatVector(imgs); if (!imgs.empty()) { CV_Assert(imgs.size() == imgs_.size()); UMat img; seam_est_imgs_.resize(imgs.size()); for (size_t i = 0; i < imgs.size(); ++i) { imgs_[i] = imgs[i]; resize(imgs[i], img, Size(), seam_scale_, seam_scale_); seam_est_imgs_[i] = img.clone(); } std::vector<UMat> seam_est_imgs_subset; std::vector<UMat> imgs_subset; for (size_t i = 0; i < indices_.size(); ++i) { imgs_subset.push_back(imgs_[indices_[i]]); seam_est_imgs_subset.push_back(seam_est_imgs_[indices_[i]]); } seam_est_imgs_ = seam_est_imgs_subset; imgs_ = imgs_subset; } UMat pano_; #if ENABLE_LOG int64 t = getTickCount(); #endif std::vector<Point> corners(imgs_.size()); std::vector<UMat> masks_warped(imgs_.size()); std::vector<UMat> images_warped(imgs_.size()); std::vector<Size> sizes(imgs_.size()); std::vector<UMat> masks(imgs_.size()); // Prepare image masks for (size_t i = 0; i < imgs_.size(); ++i) { masks[i].create(seam_est_imgs_[i].size(), CV_8U); masks[i].setTo(Scalar::all(255)); } // Warp images and their masks Ptr<detail::TranslationWarper> w = warper_->create(float(warped_image_scale_ * seam_work_aspect_)); for (size_t i = 0; i < imgs_.size(); ++i) { Mat_<float> K; cameras_[i].K().convertTo(K, CV_32F); K(0, 0) *= (float) seam_work_aspect_; K(0, 2) *= (float) seam_work_aspect_; K(1, 1) *= (float) seam_work_aspect_; K(1, 2) *= (float) seam_work_aspect_; corners[i] = w->warp(seam_est_imgs_[i], K, cameras_[i].R, cameras_[i].t, INTER_LANCZOS4, BORDER_REFLECT, images_warped[i]); sizes[i] = images_warped[i].size(); w->warp(masks[i], K, cameras_[i].R, cameras_[i].t, INTER_NEAREST, BORDER_CONSTANT, masks_warped[i]); } std::vector<UMat> images_warped_f(imgs_.size()); for (size_t i = 0; i < imgs_.size(); ++i) images_warped[i].convertTo(images_warped_f[i], CV_32F); LOGLN("Warping images, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec"); // Find seams exposure_comp_->feed(corners, images_warped, masks_warped); seam_finder_->find(images_warped_f, corners, masks_warped); // Release unused memory seam_est_imgs_.clear(); images_warped.clear(); images_warped_f.clear(); masks.clear(); LOGLN("Compositing..."); #if ENABLE_LOG t = getTickCount(); #endif UMat img_warped, img_warped_s; UMat dilated_mask, seam_mask, mask, mask_warped; //double compose_seam_aspect = 1; double compose_work_aspect = 1; bool is_blender_prepared = false; double compose_scale = 1; bool is_compose_scale_set = false; UMat full_img, img; for (size_t img_idx = 0; img_idx < imgs_.size(); ++img_idx) { LOGLN("Compositing image #" << indices_[img_idx] + 1); #if ENABLE_LOG int64 compositing_t = getTickCount(); #endif // Read image and resize it if necessary full_img = imgs_[img_idx]; if (!is_compose_scale_set) { if (compose_resol_ > 0) compose_scale = std::min(1.0, std::sqrt(compose_resol_ * 1e6 / full_img.size().area())); is_compose_scale_set = true; // Compute relative scales //compose_seam_aspect = compose_scale / seam_scale_; compose_work_aspect = compose_scale / work_scale_; // Update warped image scale warped_image_scale_ *= static_cast<float>(compose_work_aspect); w = warper_->create((float) warped_image_scale_); // Update corners and sizes for (size_t i = 0; i < imgs_.size(); ++i) { // Update intrinsics cameras_[i].focal *= compose_work_aspect; cameras_[i].ppx *= compose_work_aspect; cameras_[i].ppy *= compose_work_aspect; // Update corner and size Size sz = full_img_sizes_[i]; if (std::abs(compose_scale - 1) > 1e-1) { sz.width = cvRound(full_img_sizes_[i].width * compose_scale); sz.height = cvRound(full_img_sizes_[i].height * compose_scale); } Mat K; cameras_[i].K().convertTo(K, CV_32F); Rect roi = w->warpRoi(sz, K, cameras_[i].R, cameras_[i].t); corners[i] = roi.tl(); sizes[i] = roi.size(); } } if (std::abs(compose_scale - 1) > 1e-1) { #if ENABLE_LOG int64 resize_t = getTickCount(); #endif resize(full_img, img, Size(), compose_scale, compose_scale); LOGLN(" resize time: " << ((getTickCount() - resize_t) / getTickFrequency()) << " sec"); } else img = full_img; full_img.release(); Size img_size = img.size(); LOGLN(" after resize time: " << ((getTickCount() - compositing_t) / getTickFrequency()) << " sec"); Mat K; cameras_[img_idx].K().convertTo(K, CV_32F); #if ENABLE_LOG int64 pt = getTickCount(); #endif // Warp the current image w->warp(img, K, cameras_[img_idx].R, cameras_[img_idx].t, INTER_LANCZOS4, BORDER_REFLECT, img_warped); LOGLN(" warp the current image: " << ((getTickCount() - pt) / getTickFrequency()) << " sec"); #if ENABLE_LOG pt = getTickCount(); #endif // Warp the current image mask mask.create(img_size, CV_8U); mask.setTo(Scalar::all(255)); w->warp(mask, K, cameras_[img_idx].R, cameras_[img_idx].t, INTER_NEAREST, BORDER_CONSTANT, mask_warped); LOGLN(" warp the current image mask: " << ((getTickCount() - pt) / getTickFrequency()) << " sec"); #if ENABLE_LOG pt = getTickCount(); #endif // Compensate exposure exposure_comp_->apply((int) img_idx, corners[img_idx], img_warped, mask_warped); LOGLN(" compensate exposure: " << ((getTickCount() - pt) / getTickFrequency()) << " sec"); #if ENABLE_LOG pt = getTickCount(); #endif img_warped.convertTo(img_warped_s, CV_16S); img_warped.release(); img.release(); mask.release(); // Make sure seam mask has proper size dilate(masks_warped[img_idx], dilated_mask, Mat()); resize(dilated_mask, seam_mask, mask_warped.size()); bitwise_and(seam_mask, mask_warped, mask_warped); LOGLN(" other: " << ((getTickCount() - pt) / getTickFrequency()) << " sec"); #if ENABLE_LOG pt = getTickCount(); #endif if (!is_blender_prepared) { blender_->prepare(corners, sizes); is_blender_prepared = true; } LOGLN(" other2: " << ((getTickCount() - pt) / getTickFrequency()) << " sec"); LOGLN(" feed..."); #if ENABLE_LOG int64 feed_t = getTickCount(); #endif // Blend the current image blender_->feed(img_warped_s, mask_warped, corners[img_idx]); LOGLN(" feed time: " << ((getTickCount() - feed_t) / getTickFrequency()) << " sec"); LOGLN("Compositing ## time: " << ((getTickCount() - compositing_t) / getTickFrequency()) << " sec"); } #if ENABLE_LOG int64 blend_t = getTickCount(); #endif UMat result, result_mask; blender_->blend(result, result_mask); LOGLN("blend time: " << ((getTickCount() - blend_t) / getTickFrequency()) << " sec"); LOGLN("Compositing, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec"); // Preliminary result is in CV_16SC3 format, but all values are in [0,255] range, // so convert it to avoid user confusing result.convertTo(pano, CV_8U); return OK; }
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); }
int main(int argc, const char** argv) { // declare capture engine that can read images from camera or file VideoCapture cap; // if no cmd-line arguments other than the app name then camera flag is raised bool camera = (1==argc); if(camera) // call open(int) method to init capture engine to read from camera // In case of many cameras the index of camera can be passed as argument. cap.open(0); else // call open(char*) method to init capture engine to read images from file // the argument is file name that will be opened for reading // it can be name of video file or still image cap.open(argv[1]); // check that capture engine open source (camera or file) successfully if (!cap.isOpened()) { printf("can not open %s\n",camera?"camera":argv[1]); printf("trying to open test.jpg\n"); // in case of fail try to open simple test file to be able check pipeline working cap.open("test.jpg"); if (!cap.isOpened()) { printf("can not open test.jpg\n"); return EXIT_FAILURE; } } // prepare for processing images // declare mat objects to store input, intermediate and output images // this is main loop over all input frames for (;;) { // get next frame from input stream //cap >> imgInp; imgInp = imread(cap, CV_LOAD_IMAGE_ANYDEPTH); // check read result // in case of reading from file the loop will be break after last frame is read and processed // in case of camera this condition is always false until something wrong with camera if (imgInp.empty()) { // wait until user press any key and the break the loop // we need to wait to ge waitKey(0); break; } // show the input image on the screen using opencv function // this call creates window named "Input" and draws imgInp inside the window imshow("Input", imgInp); // convert input image into intermediate grayscale image if (imgInp.channels() > 1) { printf("Preceding with blanks: %10d \n", imgInp.channels()); cvtColor(imgInp, imgGray, COLOR_BGR2GRAY); Mat spl; split(imgInp, spl); imshow("spl1", spl[0]);//b imshow("spl2", spl[1]);//g imshow("spl3", spl[2]);//r } else{ imgGray = imgInp; } /// Initialize values alpha_slider = 0; p2_slider = 0; // run canny processing on grayscale image //Canny(imgGray, imgOut, 50, 150); // show the result on the screen using opencv function // this call creates window named "Canny" and draw imgOut inside the window //imshow("Canny", imgOut); /// Create Windows namedWindow("Linear Blend",WINDOW_NORMAL); /// Create Trackbars char TrackbarName[50]; char TrackbarName2[50]; sprintf(TrackbarName, "Thresh#1 /n x %d", alpha_slider_max); sprintf(TrackbarName2, "Thresh#2 /n 2 x %d", alpha_slider_max); //createTrackbar(TrackbarName, "Linear Blend", &alpha_slider, alpha_slider_max, on_trackbar); createTrackbar(TrackbarName, "Linear Blend", &alpha_slider, alpha_slider_max, on_trackbar_Canny); createTrackbar(TrackbarName2, "Linear Blend", &p2_slider, p2_slider_max, on_trackbar_Canny); ps_array[0] = alpha_slider; ps_array[1] = p2_slider; /// Show some stuff on_trackbar_Canny(0,0); //on_trackbar(alpha_slider, 0); // the waitKey function is called for 2 reasons // 1. detect when ESC key is pressed // 2. to allow "Input" and "Canny" windows to plumb messages. It allows user to manipulate with "Input" and "Canny" windows // 10ms param is passed to spend only 10ms inside the waitKey function and then go to further processing int key = waitKey(100); //exit if ESC is pressed if (key == 27) break; } return EXIT_SUCCESS; }
int main(int argc, char** argv) { CV_TRACE_FUNCTION(); cv::CommandLineParser parser(argc, argv, "{help h ? | | help message}" "{n | 100 | number of frames to process }" "{@video | 0 | video filename or cameraID }" ); if (parser.has("help")) { parser.printMessage(); return 0; } VideoCapture capture; std::string video = parser.get<string>("@video"); if (video.size() == 1 && isdigit(video[0])) capture.open(parser.get<int>("@video")); else capture.open(video); int nframes = 0; if (capture.isOpened()) { nframes = (int)capture.get(CAP_PROP_FRAME_COUNT); cout << "Video " << video << ": width=" << capture.get(CAP_PROP_FRAME_WIDTH) << ", height=" << capture.get(CAP_PROP_FRAME_HEIGHT) << ", nframes=" << nframes << endl; } else { cout << "Could not initialize video capturing...\n"; return -1; } int N = parser.get<int>("n"); if (nframes > 0 && N > nframes) N = nframes; cout << "Start processing..." << endl << "Press ESC key to terminate" << endl; UMat frame; for (int i = 0; N > 0 ? (i < N) : true; i++) { CV_TRACE_REGION("FRAME"); // OpenCV Trace macro for named "scope" region { CV_TRACE_REGION("read"); capture.read(frame); if (frame.empty()) { cerr << "Can't capture frame: " << i << std::endl; break; } // OpenCV Trace macro for NEXT named region in the same C++ scope // Previous "read" region will be marked complete on this line. // Use this to eliminate unnecessary curly braces. CV_TRACE_REGION_NEXT("process"); process_frame(frame); CV_TRACE_REGION_NEXT("delay"); if (waitKey(1) == 27/*ESC*/) break; } } return 0; }
UMat Mat::getUMat(int accessFlags, UMatUsageFlags usageFlags) const { UMat hdr; if(!data) return hdr; if (data != datastart) { Size wholeSize; Point ofs; locateROI(wholeSize, ofs); Size sz(cols, rows); if (ofs.x != 0 || ofs.y != 0) { Mat src = *this; int dtop = ofs.y; int dbottom = wholeSize.height - src.rows - ofs.y; int dleft = ofs.x; int dright = wholeSize.width - src.cols - ofs.x; src.adjustROI(dtop, dbottom, dleft, dright); return src.getUMat(accessFlags, usageFlags)(cv::Rect(ofs.x, ofs.y, sz.width, sz.height)); } } CV_Assert(data == datastart); accessFlags |= ACCESS_RW; UMatData* new_u = NULL; { MatAllocator *a = allocator, *a0 = getDefaultAllocator(); if(!a) a = a0; new_u = a->allocate(dims, size.p, type(), data, step.p, accessFlags, usageFlags); } bool allocated = false; try { allocated = UMat::getStdAllocator()->allocate(new_u, accessFlags, usageFlags); } catch (const cv::Exception& e) { fprintf(stderr, "Exception: %s\n", e.what()); } if (!allocated) { allocated = getDefaultAllocator()->allocate(new_u, accessFlags, usageFlags); CV_Assert(allocated); } if (u != NULL) { #ifdef HAVE_OPENCL if (ocl::useOpenCL() && new_u->currAllocator == ocl::getOpenCLAllocator()) { CV_Assert(new_u->tempUMat()); } #endif new_u->originalUMatData = u; CV_XADD(&(u->refcount), 1); CV_XADD(&(u->urefcount), 1); } hdr.flags = flags; setSize(hdr, dims, size.p, step.p); finalizeHdr(hdr); hdr.u = new_u; hdr.offset = 0; //data - datastart; hdr.addref(); return hdr; }
/* dst = src */ void Mat::copyTo( OutputArray _dst ) const { int dtype = _dst.type(); if( _dst.fixedType() && dtype != type() ) { CV_Assert( channels() == CV_MAT_CN(dtype) ); convertTo( _dst, dtype ); return; } if( empty() ) { _dst.release(); return; } if( _dst.isUMat() ) { _dst.create( dims, size.p, type() ); UMat dst = _dst.getUMat(); size_t i, sz[CV_MAX_DIM], dstofs[CV_MAX_DIM], esz = elemSize(); for( i = 0; i < (size_t)dims; i++ ) sz[i] = size.p[i]; sz[dims-1] *= esz; dst.ndoffset(dstofs); dstofs[dims-1] *= esz; dst.u->currAllocator->upload(dst.u, data, dims, sz, dstofs, dst.step.p, step.p); return; } if( dims <= 2 ) { _dst.create( rows, cols, type() ); Mat dst = _dst.getMat(); if( data == dst.data ) return; if( rows > 0 && cols > 0 ) { const uchar* sptr = data; uchar* dptr = dst.data; Size sz = getContinuousSize(*this, dst); size_t len = sz.width*elemSize(); for( ; sz.height--; sptr += step, dptr += dst.step ) memcpy( dptr, sptr, len ); } return; } _dst.create( dims, size, type() ); Mat dst = _dst.getMat(); if( data == dst.data ) return; if( total() != 0 ) { const Mat* arrays[] = { this, &dst }; uchar* ptrs[2]; NAryMatIterator it(arrays, ptrs, 2); size_t sz = it.size*elemSize(); for( size_t i = 0; i < it.nplanes; i++, ++it ) memcpy(ptrs[1], ptrs[0], sz); } }
// returns sequence of squares detected on the image. // the sequence is stored in the specified memory storage static void findSquares( const UMat& image, vector<vector<Point> >& squares ) { squares.clear(); UMat pyr, timg, gray0(image.size(), CV_8U), gray; // down-scale and upscale the image to filter out the noise pyrDown(image, pyr, Size(image.cols/2, image.rows/2)); pyrUp(pyr, timg, image.size()); vector<vector<Point> > contours; // find squares in every color plane of the image for( int c = 0; c < 3; c++ ) { int ch[] = {c, 0}; mixChannels(timg, gray0, ch, 1); // try several threshold levels for( int l = 0; l < N; l++ ) { // hack: use Canny instead of zero threshold level. // Canny helps to catch squares with gradient shading if( l == 0 ) { // apply Canny. Take the upper threshold from slider // and set the lower to 0 (which forces edges merging) Canny(gray0, gray, 0, thresh, 5); // dilate canny output to remove potential // holes between edge segments dilate(gray, gray, UMat(), Point(-1,-1)); } else { // apply threshold if l!=0: // tgray(x,y) = gray(x,y) < (l+1)*255/N ? 255 : 0 cv::threshold(gray0, gray, (l+1)*255/N, 255, THRESH_BINARY); } // find contours and store them all as a list findContours(gray, contours, RETR_LIST, CHAIN_APPROX_SIMPLE); vector<Point> approx; // test each contour for( size_t i = 0; i < contours.size(); i++ ) { // approximate contour with accuracy proportional // to the contour perimeter approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true); // square contours should have 4 vertices after approximation // relatively large area (to filter out noisy contours) // and be convex. // Note: absolute value of an area is used because // area may be positive or negative - in accordance with the // contour orientation if( approx.size() == 4 && fabs(contourArea(Mat(approx))) > 1000 && isContourConvex(Mat(approx)) ) { double maxCosine = 0; for( int j = 2; j < 5; j++ ) { // find the maximum cosine of the angle between joint edges double cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1])); maxCosine = MAX(maxCosine, cosine); } // if cosines of all angles are small // (all angles are ~90 degree) then write quandrange // vertices to resultant sequence if( maxCosine < 0.3 ) squares.push_back(approx); } } } } }
static bool ocl_moments( InputArray _src, Moments& m) { const int TILE_SIZE = 32; const int K = 10; ocl::Kernel k("moments", ocl::imgproc::moments_oclsrc, format("-D TILE_SIZE=%d", TILE_SIZE)); if( k.empty() ) return false; UMat src = _src.getUMat(); Size sz = src.size(); int xtiles = (sz.width + TILE_SIZE-1)/TILE_SIZE; int ytiles = (sz.height + TILE_SIZE-1)/TILE_SIZE; int ntiles = xtiles*ytiles; UMat umbuf(1, ntiles*K, CV_32S); size_t globalsize[] = {xtiles, sz.height}, localsize[] = {1, TILE_SIZE}; bool ok = k.args(ocl::KernelArg::ReadOnly(src), ocl::KernelArg::PtrWriteOnly(umbuf), xtiles).run(2, globalsize, localsize, true); if(!ok) return false; Mat mbuf = umbuf.getMat(ACCESS_READ); for( int i = 0; i < ntiles; i++ ) { double x = (i % xtiles)*TILE_SIZE, y = (i / xtiles)*TILE_SIZE; const int* mom = mbuf.ptr<int>() + i*K; double xm = x * mom[0], ym = y * mom[0]; // accumulate moments computed in each tile // + m00 ( = m00' ) m.m00 += mom[0]; // + m10 ( = m10' + x*m00' ) m.m10 += mom[1] + xm; // + m01 ( = m01' + y*m00' ) m.m01 += mom[2] + ym; // + m20 ( = m20' + 2*x*m10' + x*x*m00' ) m.m20 += mom[3] + x * (mom[1] * 2 + xm); // + m11 ( = m11' + x*m01' + y*m10' + x*y*m00' ) m.m11 += mom[4] + x * (mom[2] + ym) + y * mom[1]; // + m02 ( = m02' + 2*y*m01' + y*y*m00' ) m.m02 += mom[5] + y * (mom[2] * 2 + ym); // + m30 ( = m30' + 3*x*m20' + 3*x*x*m10' + x*x*x*m00' ) m.m30 += mom[6] + x * (3. * mom[3] + x * (3. * mom[1] + xm)); // + m21 ( = m21' + x*(2*m11' + 2*y*m10' + x*m01' + x*y*m00') + y*m20') m.m21 += mom[7] + x * (2 * (mom[4] + y * mom[1]) + x * (mom[2] + ym)) + y * mom[3]; // + m12 ( = m12' + y*(2*m11' + 2*x*m01' + y*m10' + x*y*m00') + x*m02') m.m12 += mom[8] + y * (2 * (mom[4] + x * mom[2]) + y * (mom[1] + xm)) + x * mom[5]; // + m03 ( = m03' + 3*y*m02' + 3*y*y*m01' + y*y*y*m00' ) m.m03 += mom[9] + y * (3. * mom[5] + y * (3. * mom[2] + ym)); } return true; }
void MultiBandBlender::feed(InputArray _img, InputArray mask, Point tl) { #if ENABLE_LOG int64 t = getTickCount(); #endif UMat img = _img.getUMat(); CV_Assert(img.type() == CV_16SC3 || img.type() == CV_8UC3); CV_Assert(mask.type() == CV_8U); // Keep source image in memory with small border int gap = 3 * (1 << num_bands_); Point tl_new(std::max(dst_roi_.x, tl.x - gap), std::max(dst_roi_.y, tl.y - gap)); Point br_new(std::min(dst_roi_.br().x, tl.x + img.cols + gap), std::min(dst_roi_.br().y, tl.y + img.rows + gap)); // Ensure coordinates of top-left, bottom-right corners are divided by (1 << num_bands_). // After that scale between layers is exactly 2. // // We do it to avoid interpolation problems when keeping sub-images only. There is no such problem when // image is bordered to have size equal to the final image size, but this is too memory hungry approach. tl_new.x = dst_roi_.x + (((tl_new.x - dst_roi_.x) >> num_bands_) << num_bands_); tl_new.y = dst_roi_.y + (((tl_new.y - dst_roi_.y) >> num_bands_) << num_bands_); int width = br_new.x - tl_new.x; int height = br_new.y - tl_new.y; width += ((1 << num_bands_) - width % (1 << num_bands_)) % (1 << num_bands_); height += ((1 << num_bands_) - height % (1 << num_bands_)) % (1 << num_bands_); br_new.x = tl_new.x + width; br_new.y = tl_new.y + height; int dy = std::max(br_new.y - dst_roi_.br().y, 0); int dx = std::max(br_new.x - dst_roi_.br().x, 0); tl_new.x -= dx; br_new.x -= dx; tl_new.y -= dy; br_new.y -= dy; int top = tl.y - tl_new.y; int left = tl.x - tl_new.x; int bottom = br_new.y - tl.y - img.rows; int right = br_new.x - tl.x - img.cols; // Create the source image Laplacian pyramid UMat img_with_border; copyMakeBorder(_img, img_with_border, top, bottom, left, right, BORDER_REFLECT); LOGLN(" Add border to the source image, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec"); #if ENABLE_LOG t = getTickCount(); #endif std::vector<UMat> src_pyr_laplace; if (can_use_gpu_ && img_with_border.depth() == CV_16S) createLaplacePyrGpu(img_with_border, num_bands_, src_pyr_laplace); else createLaplacePyr(img_with_border, num_bands_, src_pyr_laplace); LOGLN(" Create the source image Laplacian pyramid, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec"); #if ENABLE_LOG t = getTickCount(); #endif // Create the weight map Gaussian pyramid UMat weight_map; std::vector<UMat> weight_pyr_gauss(num_bands_ + 1); if(weight_type_ == CV_32F) { mask.getUMat().convertTo(weight_map, CV_32F, 1./255.); } else // weight_type_ == CV_16S { mask.getUMat().convertTo(weight_map, CV_16S); UMat add_mask; compare(mask, 0, add_mask, CMP_NE); add(weight_map, Scalar::all(1), weight_map, add_mask); } copyMakeBorder(weight_map, weight_pyr_gauss[0], top, bottom, left, right, BORDER_CONSTANT); for (int i = 0; i < num_bands_; ++i) pyrDown(weight_pyr_gauss[i], weight_pyr_gauss[i + 1]); LOGLN(" Create the weight map Gaussian pyramid, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec"); #if ENABLE_LOG t = getTickCount(); #endif int y_tl = tl_new.y - dst_roi_.y; int y_br = br_new.y - dst_roi_.y; int x_tl = tl_new.x - dst_roi_.x; int x_br = br_new.x - dst_roi_.x; // Add weighted layer of the source image to the final Laplacian pyramid layer for (int i = 0; i <= num_bands_; ++i) { Rect rc(x_tl, y_tl, x_br - x_tl, y_br - y_tl); #ifdef HAVE_OPENCL if ( !cv::ocl::useOpenCL() || !ocl_MultiBandBlender_feed(src_pyr_laplace[i], weight_pyr_gauss[i], dst_pyr_laplace_[i](rc), dst_band_weights_[i](rc)) ) #endif { Mat _src_pyr_laplace = src_pyr_laplace[i].getMat(ACCESS_READ); Mat _dst_pyr_laplace = dst_pyr_laplace_[i](rc).getMat(ACCESS_RW); Mat _weight_pyr_gauss = weight_pyr_gauss[i].getMat(ACCESS_READ); Mat _dst_band_weights = dst_band_weights_[i](rc).getMat(ACCESS_RW); if(weight_type_ == CV_32F) { for (int y = 0; y < rc.height; ++y) { const Point3_<short>* src_row = _src_pyr_laplace.ptr<Point3_<short> >(y); Point3_<short>* dst_row = _dst_pyr_laplace.ptr<Point3_<short> >(y); const float* weight_row = _weight_pyr_gauss.ptr<float>(y); float* dst_weight_row = _dst_band_weights.ptr<float>(y); for (int x = 0; x < rc.width; ++x) { dst_row[x].x += static_cast<short>(src_row[x].x * weight_row[x]); dst_row[x].y += static_cast<short>(src_row[x].y * weight_row[x]); dst_row[x].z += static_cast<short>(src_row[x].z * weight_row[x]); dst_weight_row[x] += weight_row[x]; } } } else // weight_type_ == CV_16S { for (int y = 0; y < y_br - y_tl; ++y) { const Point3_<short>* src_row = _src_pyr_laplace.ptr<Point3_<short> >(y); Point3_<short>* dst_row = _dst_pyr_laplace.ptr<Point3_<short> >(y); const short* weight_row = _weight_pyr_gauss.ptr<short>(y); short* dst_weight_row = _dst_band_weights.ptr<short>(y); for (int x = 0; x < x_br - x_tl; ++x) { dst_row[x].x += short((src_row[x].x * weight_row[x]) >> 8); dst_row[x].y += short((src_row[x].y * weight_row[x]) >> 8); dst_row[x].z += short((src_row[x].z * weight_row[x]) >> 8); dst_weight_row[x] += weight_row[x]; } } } } #ifdef HAVE_OPENCL else {
void detectAndDraw( UMat& img, Mat& canvas, CascadeClassifier& cascade, double scale0) { if( ProfileTracker x = ProfileTrackParams(184, 0)) { int i = 0; double t = 0, scale=1; vector<Rect> faces, faces2; const static Scalar colors[] = { Scalar(0,0,255), Scalar(0,128,255), Scalar(0,255,255), Scalar(0,255,0), Scalar(255,128,0), Scalar(255,255,0), Scalar(255,0,0), Scalar(255,0,255) }; static UMat gray, smallImg; t = (double)getTickCount(); resize( img, smallImg, Size(), scale0, scale0, INTER_LINEAR ); cvtColor( smallImg, gray, COLOR_BGR2GRAY ); equalizeHist( gray, gray ); cascade.detectMultiScale( gray, faces, 1.1, 3, 0 //|CASCADE_FIND_BIGGEST_OBJECT //|CASCADE_DO_ROUGH_SEARCH |CASCADE_SCALE_IMAGE, Size(30, 30) ); flip(gray, gray, 1); cascade.detectMultiScale( gray, faces2, 1.1, 2, 0 //|CASCADE_FIND_BIGGEST_OBJECT //|CASCADE_DO_ROUGH_SEARCH |CASCADE_SCALE_IMAGE , Size(30, 30) ); for( vector<Rect>::const_iterator r = faces2.begin(); r !=faces2.end(); r++ ) faces.push_back(Rect(smallImg.cols - r->x - r->width, r->y,r->width, r->height)); t = (double)getTickCount() - t; smallImg.copyTo(canvas); for( vector<Rect>::const_iterator r = faces.begin(); r !=faces.end(); r++, i++ ) { Point center; Scalar color = colors[i%8]; int radius; double aspect_ratio = (double)r->width/r->height; if( 0.75 < aspect_ratio && aspect_ratio < 1.3 ) { center.x = cvRound((r->x + r->width*0.5)*scale); center.y = cvRound((r->y + r->height*0.5)*scale); radius = cvRound((r->width + r->height)*0.25*scale); circle( canvas, center, radius, color, 3, 8, 0 ); } else rectangle( canvas, Point(cvRound(r->x*scale), cvRound(r->y*scale)), Point(cvRound((r->x + r->width-1)*scale),cvRound((r->y + r->height-1)*scale)), color, 3, 8, 0); } } }
bool OCRTess::detectAndRecog() { UMat grey = UMat::zeros(this->img.rows + 2, this->img.cols + 2, CV_8UC1); cvtColor(this->img.clone(), grey, COLOR_RGB2GRAY); vector<UMat> channels; channels.clear(); channels.push_back(grey); Mat m = 255 - grey.getMat(ACCESS_READ | ACCESS_WRITE); channels.push_back(m.getUMat(ACCESS_READ)); vector<vector<ERStat>> regions(2); regions[0].clear(); regions[1].clear(); switch (this->REGION) { case REG_CSER: { parallel_for_(Range(0, (int) channels.size()), Parallel_extractCSER(channels, regions, this->erf1, this->erf2)); break; } case REG_MSER: { vector<vector<Point> > contours; vector<Rect> bboxes; Ptr<MSER> mser = MSER::create(21, (int) (0.00002 * grey.cols * grey.rows), (int) (0.05 * grey.cols * grey.rows), 1, 0.7); mser->detectRegions(grey, contours, bboxes); if (contours.size() > 0) MSERsToERStats(grey, contours, regions); break; } default: { break; } } /*Text Recognition (OCR)*/ vector<vector<Vec2i> > nm_region_groups; vector<Rect> nm_boxes; switch (this->GROUP) { case 0: erGrouping(this->img, channels, regions, nm_region_groups, nm_boxes, ERGROUPING_ORIENTATION_HORIZ); break; case 1: default: erGrouping(this->img, channels, regions, nm_region_groups, nm_boxes, ERGROUPING_ORIENTATION_ANY, DIR + TR_GRP, 0.5); break; } if (!nm_boxes.size() || nm_boxes.size() > 1) return false; vector<string> words_detection; float min_confidence1 = 51.f, min_confidence2 = 60.f; vector<UMat> detections; for (int i = 0; i < (int) nm_boxes.size(); i++) { // rectangle(this->out, nm_boxes[i].tl(), nm_boxes[i].br(), Scalar(255, 255, 0), 3); UMat group_img = UMat::zeros(this->img.rows + 2, this->img.cols + 2, CV_8UC1); er_draw(channels, regions, nm_region_groups[i], group_img); group_img = group_img(nm_boxes[i]); copyMakeBorder(group_img.clone(), group_img, 15, 15, 15, 15, BORDER_CONSTANT, Scalar(0)); detections.push_back(group_img); } vector<string> outputs((int) detections.size()); vector<vector<Rect> > boxes((int) detections.size()); vector<vector<string> > words((int) detections.size()); vector<vector<float> > confidences((int) detections.size()); if (!detections.size() || detections.size() > 1) return false; for (int i = 0; i < (int) detections.size(); i = i + this->num) { Range r; if (i + this->num <= (int) detections.size()) r = Range(i, i + this->num); else r = Range(i, (int) detections.size()); parallel_for_(r, Parallel_OCR<OCRTesseract>(detections, outputs, boxes, words, confidences, this->ocrs)); } for (int i = 0; i < (int) detections.size(); i++) { outputs[i].erase(remove(outputs[i].begin(), outputs[i].end(), '\n'), outputs[i].end()); if (outputs[i].size() < 3) { continue; } for (int j = 0; j < (int) boxes[i].size(); j++) { boxes[i][j].x += nm_boxes[i].x - 15; boxes[i][j].y += nm_boxes[i].y - 15; if ((words[i][j].size() < 2) || (confidences[i][j] < min_confidence1) || ((words[i][j].size() == 2) && (words[i][j][0] == words[i][j][1])) || ((words[i][j].size() < 4) && (confidences[i][j] < min_confidence2)) || isRepetitive(words[i][j])) continue; words_detection.push_back(words[i][j]); // rectangle(this->out, boxes[i][j].tl(), boxes[i][j].br(), Scalar(255, 0, 255), 3); // Size word_size = getTextSize(words[i][j], FONT_HERSHEY_SIMPLEX, (double) scale_font, (int) (3 * scale_font), NULL); // rectangle(this->out, boxes[i][j].tl() - Point(3, word_size.height + 3), boxes[i][j].tl() + Point(word_size.width, 0), Scalar(255, 0, 255), -1); // putText(this->out, words[i][j], boxes[i][j].tl() - Point(1, 1), FONT_HERSHEY_SIMPLEX, scale_font, Scalar(255, 255, 255), (int) (3 * scale_font)); } } if (!words_detection.size() || words_detection.size() > 1) return false; return (words_detection[0].compare(WORD) == 0); }
bool SURF_OCL::computeDescriptors(const UMat &keypoints, OutputArray _descriptors) { int dsize = params->descriptorSize(); int nFeatures = keypoints.cols; if (nFeatures == 0) { _descriptors.release(); return true; } _descriptors.create(nFeatures, dsize, CV_32F); UMat descriptors; if( _descriptors.isUMat() ) descriptors = _descriptors.getUMat(); else descriptors.create(nFeatures, dsize, CV_32F); ocl::Kernel kerCalcDesc, kerNormDesc; if( dsize == 64 ) { kerCalcDesc.create("SURF_computeDescriptors64", ocl::xfeatures2d::surf_oclsrc, kerOpts); kerNormDesc.create("SURF_normalizeDescriptors64", ocl::xfeatures2d::surf_oclsrc, kerOpts); } else { CV_Assert(dsize == 128); kerCalcDesc.create("SURF_computeDescriptors128", ocl::xfeatures2d::surf_oclsrc, kerOpts); kerNormDesc.create("SURF_normalizeDescriptors128", ocl::xfeatures2d::surf_oclsrc, kerOpts); } size_t localThreads[] = {6, 6}; size_t globalThreads[] = {nFeatures*localThreads[0], localThreads[1]}; if(haveImageSupport) { kerCalcDesc.args(imgTex, img_rows, img_cols, ocl::KernelArg::ReadOnlyNoSize(keypoints), ocl::KernelArg::WriteOnlyNoSize(descriptors)); } else { kerCalcDesc.args(ocl::KernelArg::ReadOnlyNoSize(img), img_rows, img_cols, ocl::KernelArg::ReadOnlyNoSize(keypoints), ocl::KernelArg::WriteOnlyNoSize(descriptors)); } if(!kerCalcDesc.run(2, globalThreads, localThreads, true)) return false; size_t localThreads_n[] = {dsize, 1}; size_t globalThreads_n[] = {nFeatures*localThreads_n[0], localThreads_n[1]}; globalThreads[0] = nFeatures * localThreads[0]; globalThreads[1] = localThreads[1]; bool ok = kerNormDesc.args(ocl::KernelArg::ReadWriteNoSize(descriptors)). run(2, globalThreads_n, localThreads_n, true); if(ok && !_descriptors.isUMat()) descriptors.copyTo(_descriptors); return ok; }
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); }
int main(int argc, const char** argv) { // get next frame from input stream //cap >> imgInp; src = imread(argv[1], CV_LOAD_IMAGE_ANYDEPTH); src.convertTo(imgInp, CV_8UC1, 0.00390625); //src.copyTo(imgInp); std::istringstream iss(argv[1]); std::vector<std::string> tokens; std::string token; while (std::getline(iss, token, '.')) { if (!token.empty()) tokens.push_back(token); } // check read result // in case of reading from file the loop will be break after last frame is read and processed // in case of camera this condition is always false until something wrong with camera // show the input image on the screen using opencv function // this call creates window named "Input" and draws imgInp inside the window imshow("Input", imgInp); // convert input image into intermediate grayscale image if (imgInp.channels() > 1) { printf("Preceding with blanks: %10d \n", imgInp.channels()); cvtColor(imgInp, imgGray, COLOR_BGR2GRAY); Mat spl; split(imgInp, spl); //imshow("spl1", spl[0]);//b //imshow("spl2", spl[1]);//g // imshow("spl3", spl[2]);//r } else { printf("Preceding with blanks: %10d \n", imgInp.channels()); imgGray = imgInp; } /// Initialize values alpha_slider = 0; p2_slider = 0; // run canny processing on grayscale image //Canny(imgGray, imgOut, 50, 150); // show the result on the screen using opencv function // this call creates window named "Canny" and draw imgOut inside the window //imshow("Canny", imgOut); /// Create Windows namedWindow("Linear Blend",WINDOW_NORMAL); /// Create Trackbars char TrackbarName[50]; char TrackbarName2[50]; sprintf(TrackbarName, "Thresh#1 /n x %d", alpha_slider_max); sprintf(TrackbarName2, "Thresh#2 /n 2 x %d", alpha_slider_max); //createTrackbar(TrackbarName, "Linear Blend", &alpha_slider, alpha_slider_max, on_trackbar); createTrackbar(TrackbarName, "Linear Blend", &alpha_slider, alpha_slider_max, on_trackbar_Canny); createTrackbar(TrackbarName2, "Linear Blend", &p2_slider, p2_slider_max, on_trackbar_Canny); ps_array[0] = alpha_slider; ps_array[1] = p2_slider; for (;;) { /// Show some stuff on_trackbar_Canny(0, 0); //on_trackbar(alpha_slider, 0); // the waitKey function is called for 2 reasons // 1. detect when ESC key is pressed // 2. to allow "Input" and "Canny" windows to plumb messages. It allows user to manipulate with "Input" and "Canny" windows // 10ms param is passed to spend only 10ms inside the waitKey function and then go to further processing int key = waitKey(100); //exit if ESC is pressed if (key == 27) break; } return EXIT_SUCCESS; }