参考的三种边缘检测算子其一,未完待续。。灰度或结构等信息的突变位置是图像的边缘,图像的边缘有幅度和方向属性,沿边缘方向像素变化缓慢,垂直边缘方向像素变化剧烈。因此,边缘上的变化能通过梯度计算出来。

同理:

#include "precomp.hpp"
#include "opencl_kernels_imgproc.hpp"#include "opencv2/core/openvx/ovx_defs.hpp"
#include "filter.hpp"
/****************************************************************************************\Sobel & Scharr Derivative Filters
\****************************************************************************************/namespace cv
{static void getScharrKernels( OutputArray _kx, OutputArray _ky,int dx, int dy, bool normalize, int ktype )
{const int ksize = 3;CV_Assert( ktype == CV_32F || ktype == CV_64F );_kx.create(ksize, 1, ktype, -1, true);_ky.create(ksize, 1, ktype, -1, true);Mat kx = _kx.getMat();Mat ky = _ky.getMat();CV_Assert( dx >= 0 && dy >= 0 && dx+dy == 1 );for( int k = 0; k < 2; k++ ){Mat* kernel = k == 0 ? &kx : &ky;int order = k == 0 ? dx : dy;int kerI[3];if( order == 0 )kerI[0] = 3, kerI[1] = 10, kerI[2] = 3;else if( order == 1 )kerI[0] = -1, kerI[1] = 0, kerI[2] = 1;Mat temp(kernel->rows, kernel->cols, CV_32S, &kerI[0]);double scale = !normalize || order == 1 ? 1. : 1./32;temp.convertTo(*kernel, ktype, scale);}
}static void getSobelKernels( OutputArray _kx, OutputArray _ky,int dx, int dy, int _ksize, bool normalize, int ktype )
{int i, j, ksizeX = _ksize, ksizeY = _ksize;if( ksizeX == 1 && dx > 0 )ksizeX = 3;if( ksizeY == 1 && dy > 0 )ksizeY = 3;CV_Assert( ktype == CV_32F || ktype == CV_64F );_kx.create(ksizeX, 1, ktype, -1, true);_ky.create(ksizeY, 1, ktype, -1, true);Mat kx = _kx.getMat();Mat ky = _ky.getMat();if( _ksize % 2 == 0 || _ksize > 31 )CV_Error( CV_StsOutOfRange, "The kernel size must be odd and not larger than 31" );std::vector<int> kerI(std::max(ksizeX, ksizeY) + 1);CV_Assert( dx >= 0 && dy >= 0 && dx+dy > 0 );for( int k = 0; k < 2; k++ ){Mat* kernel = k == 0 ? &kx : &ky;int order = k == 0 ? dx : dy;int ksize = k == 0 ? ksizeX : ksizeY;CV_Assert( ksize > order );if( ksize == 1 )kerI[0] = 1;else if( ksize == 3 ){if( order == 0 )kerI[0] = 1, kerI[1] = 2, kerI[2] = 1;else if( order == 1 )kerI[0] = -1, kerI[1] = 0, kerI[2] = 1;elsekerI[0] = 1, kerI[1] = -2, kerI[2] = 1;}else{int oldval, newval;kerI[0] = 1;for( i = 0; i < ksize; i++ )kerI[i+1] = 0;for( i = 0; i < ksize - order - 1; i++ ){oldval = kerI[0];for( j = 1; j <= ksize; j++ ){newval = kerI[j]+kerI[j-1];kerI[j-1] = oldval;oldval = newval;}}for( i = 0; i < order; i++ ){oldval = -kerI[0];for( j = 1; j <= ksize; j++ ){newval = kerI[j-1] - kerI[j];kerI[j-1] = oldval;oldval = newval;}}}Mat temp(kernel->rows, kernel->cols, CV_32S, &kerI[0]);double scale = !normalize ? 1. : 1./(1 << (ksize-order-1));temp.convertTo(*kernel, ktype, scale);}
}}void cv::getDerivKernels( OutputArray kx, OutputArray ky, int dx, int dy,int ksize, bool normalize, int ktype )
{if( ksize <= 0 )getScharrKernels( kx, ky, dx, dy, normalize, ktype );elsegetSobelKernels( kx, ky, dx, dy, ksize, normalize, ktype );
}cv::Ptr<cv::FilterEngine> cv::createDerivFilter(int srcType, int dstType,int dx, int dy, int ksize, int borderType )
{Mat kx, ky;getDerivKernels( kx, ky, dx, dy, ksize, false, CV_32F );return createSeparableLinearFilter(srcType, dstType,kx, ky, Point(-1,-1), 0, borderType );
}#ifdef HAVE_OPENVX
namespace cv
{namespace ovx {template <> inline bool skipSmallImages<VX_KERNEL_SOBEL_3x3>(int w, int h) { return w*h < 320 * 240; }}static bool openvx_sobel(InputArray _src, OutputArray _dst,int dx, int dy, int ksize,double scale, double delta, int borderType){if (_src.type() != CV_8UC1 || _dst.type() != CV_16SC1 ||ksize != 3 || scale != 1.0 || delta != 0.0 ||(dx | dy) != 1 || (dx + dy) != 1 ||_src.cols() < ksize || _src.rows() < ksize ||ovx::skipSmallImages<VX_KERNEL_SOBEL_3x3>(_src.cols(), _src.rows()))return false;Mat src = _src.getMat();Mat dst = _dst.getMat();if ((borderType & BORDER_ISOLATED) == 0 && src.isSubmatrix())return false; //Process isolated borders onlyvx_enum border;switch (borderType & ~BORDER_ISOLATED){case BORDER_CONSTANT:border = VX_BORDER_CONSTANT;break;case BORDER_REPLICATE:
//            border = VX_BORDER_REPLICATE;
//            break;default:return false;}try{ivx::Context ctx = ovx::getOpenVXContext();//if ((vx_size)ksize > ctx.convolutionMaxDimension())//    return false;Mat a;if (dst.data != src.data)a = src;elsesrc.copyTo(a);ivx::Imageia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,ivx::Image::createAddressing(a.cols, a.rows, 1, (vx_int32)(a.step)), a.data),ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_S16,ivx::Image::createAddressing(dst.cols, dst.rows, 2, (vx_int32)(dst.step)), dst.data);//ATTENTION: VX_CONTEXT_IMMEDIATE_BORDER attribute change could lead to strange issues in multi-threaded environments//since OpenVX standard says nothing about thread-safety for nowivx::border_t prevBorder = ctx.immediateBorder();ctx.setImmediateBorder(border, (vx_uint8)(0));if(dx)ivx::IVX_CHECK_STATUS(vxuSobel3x3(ctx, ia, ib, NULL));elseivx::IVX_CHECK_STATUS(vxuSobel3x3(ctx, ia, NULL, ib));ctx.setImmediateBorder(prevBorder);}catch (const ivx::RuntimeError & e){VX_DbgThrow(e.what());}catch (const ivx::WrapperError & e){VX_DbgThrow(e.what());}return true;}
}
#endif#if 0 //defined HAVE_IPP
namespace cv
{static bool ipp_Deriv(InputArray _src, OutputArray _dst, int dx, int dy, int ksize, double scale, double delta, int borderType)
{
#ifdef HAVE_IPP_IWCV_INSTRUMENT_REGION_IPP();::ipp::IwiSize size(_src.size().width, _src.size().height);IppDataType   srcType   = ippiGetDataType(_src.depth());IppDataType   dstType   = ippiGetDataType(_dst.depth());int           channels  = _src.channels();bool          useScale  = false;bool          useScharr = false;if(channels != _dst.channels() || channels > 1)return false;if(fabs(delta) > FLT_EPSILON || fabs(scale-1) > FLT_EPSILON)useScale = true;if(ksize <= 0){ksize     = 3;useScharr = true;}IppiMaskSize maskSize = ippiGetMaskSize(ksize, ksize);if((int)maskSize < 0)return false;#if IPP_VERSION_X100 <= 201703// Bug with mirror wrapif(borderType == BORDER_REFLECT_101 && (ksize/2+1 > size.width || ksize/2+1 > size.height))return false;
#endifIwiDerivativeType derivType = ippiGetDerivType(dx, dy, (useScharr)?false:true);if((int)derivType < 0)return false;// Acquire data and begin processingtry{Mat src = _src.getMat();Mat dst = _dst.getMat();::ipp::IwiImage iwSrc      = ippiGetImage(src);::ipp::IwiImage iwDst      = ippiGetImage(dst);::ipp::IwiImage iwSrcProc  = iwSrc;::ipp::IwiImage iwDstProc  = iwDst;::ipp::IwiBorderSize  borderSize(maskSize);::ipp::IwiBorderType  ippBorder(ippiGetBorder(iwSrc, borderType, borderSize));if(!ippBorder)return false;if(srcType == ipp8u && dstType == ipp8u){iwDstProc.Alloc(iwDst.m_size, ipp16s, channels);useScale = true;}else if(srcType == ipp8u && dstType == ipp32f){iwSrc -= borderSize;iwSrcProc.Alloc(iwSrc.m_size, ipp32f, channels);CV_INSTRUMENT_FUN_IPP(::ipp::iwiScale, iwSrc, iwSrcProc, 1, 0, ::ipp::IwiScaleParams(ippAlgHintFast));iwSrcProc += borderSize;}if(useScharr)CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterScharr, iwSrcProc, iwDstProc, derivType, maskSize, ::ipp::IwDefault(), ippBorder);elseCV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterSobel, iwSrcProc, iwDstProc, derivType, maskSize, ::ipp::IwDefault(), ippBorder);if(useScale)CV_INSTRUMENT_FUN_IPP(::ipp::iwiScale, iwDstProc, iwDst, scale, delta, ::ipp::IwiScaleParams(ippAlgHintFast));}catch (const ::ipp::IwException &){return false;}return true;
#elseCV_UNUSED(_src); CV_UNUSED(_dst); CV_UNUSED(dx); CV_UNUSED(dy); CV_UNUSED(ksize); CV_UNUSED(scale); CV_UNUSED(delta); CV_UNUSED(borderType);return false;
#endif
}
}
#endif#ifdef HAVE_OPENCL
namespace cv
{
static bool ocl_sepFilter3x3_8UC1(InputArray _src, OutputArray _dst, int ddepth,InputArray _kernelX, InputArray _kernelY, double delta, int borderType)
{const ocl::Device & dev = ocl::Device::getDefault();int type = _src.type(), sdepth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);if ( !(dev.isIntel() && (type == CV_8UC1) && (ddepth == CV_8U) &&(_src.offset() == 0) && (_src.step() % 4 == 0) &&(_src.cols() % 16 == 0) && (_src.rows() % 2 == 0)) )return false;Mat kernelX = _kernelX.getMat().reshape(1, 1);if (kernelX.cols % 2 != 1)return false;Mat kernelY = _kernelY.getMat().reshape(1, 1);if (kernelY.cols % 2 != 1)return false;if (ddepth < 0)ddepth = sdepth;Size size = _src.size();size_t globalsize[2] = { 0, 0 };size_t localsize[2] = { 0, 0 };globalsize[0] = size.width / 16;globalsize[1] = size.height / 2;const char * const borderMap[] = { "BORDER_CONSTANT", "BORDER_REPLICATE", "BORDER_REFLECT", 0, "BORDER_REFLECT_101" };char build_opts[1024];sprintf(build_opts, "-D %s %s%s", borderMap[borderType],ocl::kernelToStr(kernelX, CV_32F, "KERNEL_MATRIX_X").c_str(),ocl::kernelToStr(kernelY, CV_32F, "KERNEL_MATRIX_Y").c_str());ocl::Kernel kernel("sepFilter3x3_8UC1_cols16_rows2", cv::ocl::imgproc::sepFilter3x3_oclsrc, build_opts);if (kernel.empty())return false;UMat src = _src.getUMat();_dst.create(size, CV_MAKETYPE(ddepth, cn));if (!(_dst.offset() == 0 && _dst.step() % 4 == 0))return false;UMat dst = _dst.getUMat();int idxArg = kernel.set(0, ocl::KernelArg::PtrReadOnly(src));idxArg = kernel.set(idxArg, (int)src.step);idxArg = kernel.set(idxArg, ocl::KernelArg::PtrWriteOnly(dst));idxArg = kernel.set(idxArg, (int)dst.step);idxArg = kernel.set(idxArg, (int)dst.rows);idxArg = kernel.set(idxArg, (int)dst.cols);idxArg = kernel.set(idxArg, static_cast<float>(delta));return kernel.run(2, globalsize, (localsize[0] == 0) ? NULL : localsize, false);
}
}
#endifvoid cv::Sobel( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy,int ksize, double scale, double delta, int borderType )
{CV_INSTRUMENT_REGION();CV_Assert(!_src.empty());int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype);if (ddepth < 0)ddepth = sdepth;int dtype = CV_MAKE_TYPE(ddepth, cn);_dst.create( _src.size(), dtype );int ktype = std::max(CV_32F, std::max(ddepth, sdepth));Mat kx, ky;getDerivKernels( kx, ky, dx, dy, ksize, false, ktype );if( scale != 1 ){// usually the smoothing part is the slowest to compute,// so try to scale it instead of the faster differentiating partif( dx == 0 )kx *= scale;elseky *= scale;}CV_OCL_RUN(ocl::isOpenCLActivated() && _dst.isUMat() && _src.dims() <= 2 && ksize == 3 &&(size_t)_src.rows() > ky.total() && (size_t)_src.cols() > kx.total(),ocl_sepFilter3x3_8UC1(_src, _dst, ddepth, kx, ky, delta, borderType));CV_OCL_RUN(ocl::isOpenCLActivated() && _dst.isUMat() && _src.dims() <= 2 && (size_t)_src.rows() > kx.total() && (size_t)_src.cols() > kx.total(),ocl_sepFilter2D(_src, _dst, ddepth, kx, ky, Point(-1, -1), delta, borderType))Mat src = _src.getMat();Mat dst = _dst.getMat();Point ofs;Size wsz(src.cols, src.rows);if(!(borderType & BORDER_ISOLATED))src.locateROI( wsz, ofs );CALL_HAL(sobel, cv_hal_sobel, src.ptr(), src.step, dst.ptr(), dst.step, src.cols, src.rows, sdepth, ddepth, cn,ofs.x, ofs.y, wsz.width - src.cols - ofs.x, wsz.height - src.rows - ofs.y, dx, dy, ksize, scale, delta, borderType&~BORDER_ISOLATED);CV_OVX_RUN(true,openvx_sobel(src, dst, dx, dy, ksize, scale, delta, borderType))//CV_IPP_RUN_FAST(ipp_Deriv(src, dst, dx, dy, ksize, scale, delta, borderType));sepFilter2D(src, dst, ddepth, kx, ky, Point(-1, -1), delta, borderType );
}void cv::Scharr( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy,double scale, double delta, int borderType )
{CV_INSTRUMENT_REGION();CV_Assert(!_src.empty());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 );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 differentiating partif( dx == 0 )kx *= scale;elseky *= scale;}CV_OCL_RUN(ocl::isOpenCLActivated() && _dst.isUMat() && _src.dims() <= 2 &&(size_t)_src.rows() > ky.total() && (size_t)_src.cols() > kx.total(),ocl_sepFilter3x3_8UC1(_src, _dst, ddepth, kx, ky, delta, borderType));CV_OCL_RUN(ocl::isOpenCLActivated() && _dst.isUMat() && _src.dims() <= 2 &&(size_t)_src.rows() > kx.total() && (size_t)_src.cols() > kx.total(),ocl_sepFilter2D(_src, _dst, ddepth, kx, ky, Point(-1, -1), delta, borderType))Mat src = _src.getMat();Mat dst = _dst.getMat();Point ofs;Size wsz(src.cols, src.rows);if(!(borderType & BORDER_ISOLATED))src.locateROI( wsz, ofs );CALL_HAL(scharr, cv_hal_scharr, src.ptr(), src.step, dst.ptr(), dst.step, src.cols, src.rows, sdepth, ddepth, cn,ofs.x, ofs.y, wsz.width - src.cols - ofs.x, wsz.height - src.rows - ofs.y, dx, dy, scale, delta, borderType&~BORDER_ISOLATED);//CV_IPP_RUN_FAST(ipp_Deriv(src, dst, dx, dy, 0, scale, delta, borderType));sepFilter2D( src, dst, ddepth, kx, ky, Point(-1, -1), delta, borderType );
}#ifdef HAVE_OPENCLnamespace cv {#define LAPLACIAN_LOCAL_MEM(tileX, tileY, ksize, elsize) (((tileX) + 2 * (int)((ksize) / 2)) * (3 * (tileY) + 2 * (int)((ksize) / 2)) * elsize)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;CV_Assert(src_step != 0 && esz != 0);// workaround for NVIDIA: 3 channel vector type takes 4*elem_size in local memoryint 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)&& OCL_PERFORMANCE_CHECK(!dev.isAMD())  // TODO FIXIT 2018: Problem with AMDGPU on Linux (2482.3)){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);elsek.args(d2xarg, d2yarg, dstarg, iscale, idelta);size_t globalsize[] = { (size_t)dst.cols * cn / kercn, (size_t)dst.rows };return k.run(2, globalsize, NULL, false);
}static bool ocl_Laplacian3_8UC1(InputArray _src, OutputArray _dst, int ddepth,InputArray _kernel, double delta, int borderType)
{const ocl::Device & dev = ocl::Device::getDefault();int type = _src.type(), sdepth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);if ( !(dev.isIntel() && (type == CV_8UC1) && (ddepth == CV_8U) &&(borderType != BORDER_WRAP) &&(_src.offset() == 0) && (_src.step() % 4 == 0) &&(_src.cols() % 16 == 0) && (_src.rows() % 2 == 0)) )return false;Mat kernel = _kernel.getMat().reshape(1, 1);if (ddepth < 0)ddepth = sdepth;Size size = _src.size();size_t globalsize[2] = { 0, 0 };size_t localsize[2] = { 0, 0 };globalsize[0] = size.width / 16;globalsize[1] = size.height / 2;const char * const borderMap[] = { "BORDER_CONSTANT", "BORDER_REPLICATE", "BORDER_REFLECT", 0, "BORDER_REFLECT_101" };char build_opts[1024];sprintf(build_opts, "-D %s %s", borderMap[borderType],ocl::kernelToStr(kernel, CV_32F, "KERNEL_MATRIX").c_str());ocl::Kernel k("laplacian3_8UC1_cols16_rows2", cv::ocl::imgproc::laplacian3_oclsrc, build_opts);if (k.empty())return false;UMat src = _src.getUMat();_dst.create(size, CV_MAKETYPE(ddepth, cn));if (!(_dst.offset() == 0 && _dst.step() % 4 == 0))return false;UMat dst = _dst.getUMat();int idxArg = k.set(0, ocl::KernelArg::PtrReadOnly(src));idxArg = k.set(idxArg, (int)src.step);idxArg = k.set(idxArg, ocl::KernelArg::PtrWriteOnly(dst));idxArg = k.set(idxArg, (int)dst.step);idxArg = k.set(idxArg, (int)dst.rows);idxArg = k.set(idxArg, (int)dst.cols);idxArg = k.set(idxArg, static_cast<float>(delta));return k.run(2, globalsize, (localsize[0] == 0) ? NULL : localsize, false);
}}
#endif#if defined(HAVE_IPP)
namespace cv
{static bool ipp_Laplacian(InputArray _src, OutputArray _dst, int ksize, double scale, double delta, int borderType)
{
#ifdef HAVE_IPP_IWCV_INSTRUMENT_REGION_IPP();::ipp::IwiSize size(_src.size().width, _src.size().height);IppDataType   srcType   = ippiGetDataType(_src.depth());IppDataType   dstType   = ippiGetDataType(_dst.depth());int           channels  = _src.channels();bool          useScale  = false;if(channels != _dst.channels() || channels > 1)return false;if(fabs(delta) > FLT_EPSILON || fabs(scale-1) > FLT_EPSILON)useScale = true;IppiMaskSize maskSize = ippiGetMaskSize(ksize, ksize);if((int)maskSize < 0)return false;// Acquire data and begin processingtry{Mat src = _src.getMat();Mat dst = _dst.getMat();::ipp::IwiImage iwSrc      = ippiGetImage(src);::ipp::IwiImage iwDst      = ippiGetImage(dst);::ipp::IwiImage iwSrcProc  = iwSrc;::ipp::IwiImage iwDstProc  = iwDst;::ipp::IwiBorderSize  borderSize(maskSize);::ipp::IwiBorderType  ippBorder(ippiGetBorder(iwSrc, borderType, borderSize));if(!ippBorder)return false;if(srcType == ipp8u && dstType == ipp8u){iwDstProc.Alloc(iwDst.m_size, ipp16s, channels);useScale = true;}else if(srcType == ipp8u && dstType == ipp32f){iwSrc -= borderSize;iwSrcProc.Alloc(iwSrc.m_size, ipp32f, channels);CV_INSTRUMENT_FUN_IPP(::ipp::iwiScale, iwSrc, iwSrcProc, 1, 0);iwSrcProc += borderSize;}CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterLaplacian, iwSrcProc, iwDstProc, maskSize, ::ipp::IwDefault(), ippBorder);if(useScale)CV_INSTRUMENT_FUN_IPP(::ipp::iwiScale, iwDstProc, iwDst, scale, delta);}catch (const ::ipp::IwException &){return false;}return true;
#elseCV_UNUSED(_src); CV_UNUSED(_dst); CV_UNUSED(ksize); CV_UNUSED(scale); CV_UNUSED(delta); CV_UNUSED(borderType);return false;
#endif
}
}
#endifvoid cv::Laplacian( InputArray _src, OutputArray _dst, int ddepth, int ksize,double scale, double delta, int borderType )
{CV_INSTRUMENT_REGION();CV_Assert(!_src.empty());int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype);if (ddepth < 0)ddepth = sdepth;_dst.create( _src.size(), CV_MAKETYPE(ddepth, cn) );if( ksize == 1 || ksize == 3 ){float K[2][9] ={{ 0, 1, 0, 1, -4, 1, 0, 1, 0 },{ 2, 0, 2, 0, -8, 0, 2, 0, 2 }};Mat kernel(3, 3, CV_32F, K[ksize == 3]);if( scale != 1 )kernel *= scale;CV_OCL_RUN(_dst.isUMat() && _src.dims() <= 2,ocl_Laplacian3_8UC1(_src, _dst, ddepth, kernel, delta, borderType));}CV_IPP_RUN(!(cv::ocl::isOpenCLActivated() && _dst.isUMat()), ipp_Laplacian(_src, _dst, ksize, scale, delta, borderType));if( ksize == 1 || ksize == 3 ){float K[2][9] ={{ 0, 1, 0, 1, -4, 1, 0, 1, 0 },{ 2, 0, 2, 0, -8, 0, 2, 0, 2 }};Mat kernel(3, 3, CV_32F, K[ksize == 3]);if( scale != 1 )kernel *= scale;filter2D( _src, _dst, ddepth, kernel, Point(-1, -1), delta, borderType );}else{int ktype = std::max(CV_32F, std::max(ddepth, sdepth));int wdepth = sdepth == CV_8U && ksize <= 5 ? CV_16S : sdepth <= CV_32F ? CV_32F : CV_64F;int wtype = CV_MAKETYPE(wdepth, cn);Mat kd, ks;getSobelKernels( kd, ks, 2, 0, ksize, false, ktype );CV_OCL_RUN(_dst.isUMat(),ocl_Laplacian5(_src, _dst, kd, ks, scale,delta, borderType, wdepth, ddepth))Mat src = _src.getMat(), dst = _dst.getMat();Point ofs;Size wsz(src.cols, src.rows);if(!(borderType&BORDER_ISOLATED))src.locateROI( wsz, ofs );borderType = (borderType&~BORDER_ISOLATED);const size_t STRIPE_SIZE = 1 << 14;Ptr<FilterEngine> fx = createSeparableLinearFilter(stype,wtype, kd, ks, Point(-1,-1), 0, borderType, borderType, Scalar() );Ptr<FilterEngine> fy = createSeparableLinearFilter(stype,wtype, ks, kd, Point(-1,-1), 0, borderType, borderType, Scalar() );int y = fx->start(src, wsz, ofs), dsty = 0, dy = 0;fy->start(src, wsz, ofs);const uchar* sptr = src.ptr() + src.step[0] * y;int dy0 = std::min(std::max((int)(STRIPE_SIZE/(CV_ELEM_SIZE(stype)*src.cols)), 1), src.rows);Mat d2x( dy0 + kd.rows - 1, src.cols, wtype );Mat d2y( dy0 + kd.rows - 1, src.cols, wtype );for( ; dsty < src.rows; sptr += dy0*src.step, dsty += dy ){fx->proceed( sptr, (int)src.step, dy0, d2x.ptr(), (int)d2x.step );dy = fy->proceed( sptr, (int)src.step, dy0, d2y.ptr(), (int)d2y.step );if( dy > 0 ){Mat dstripe = dst.rowRange(dsty, dsty + dy);d2x.rows = d2y.rows = dy; // modify the headers, which should workd2x += d2y;d2x.convertTo( dstripe, ddepth, scale, delta );}}}
}CV_IMPL void
cvSobel( const void* srcarr, void* dstarr, int dx, int dy, int aperture_size )
{cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr);CV_Assert( src.size() == dst.size() && src.channels() == dst.channels() );cv::Sobel( src, dst, dst.depth(), dx, dy, aperture_size, 1, 0, cv::BORDER_REPLICATE );if( CV_IS_IMAGE(srcarr) && ((IplImage*)srcarr)->origin && dy % 2 != 0 )dst *= -1;
}CV_IMPL void
cvLaplace( const void* srcarr, void* dstarr, int aperture_size )
{cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr);CV_Assert( src.size() == dst.size() && src.channels() == dst.channels() );cv::Laplacian( src, dst, dst.depth(), aperture_size, 1, 0, cv::BORDER_REPLICATE );
}/* End of file. */

免责申明,转载转转,。

/*M///
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                        Intel License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Copyright (C) 2014, Itseez, Inc, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of Intel Corporation may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

逐渐的走向开源是个好事。。

openCV的sobel算子的深度学习卷积网络部分的C语言源码相关推荐

  1. 计算机视觉研究院手把手教你深度学习的部署(手势识别,源码已开源)

    计算机视觉研究院专栏 作者:Edison_G 今天我们继续基于姿态估计的运动计数APP开发! 公众号ID|ComputerVisionGzq 学习群|扫码在主页获取加入方式 关注并星标 从此不迷路 计 ...

  2. 李沐d2l《动手学深度学习》第二版——风格迁移源码详解

    本文是对李沐Dive to DL<动手学深度学习>第二版13.12节风格迁移的源码详解,整体由Jupyter+VSCode完成,几乎所有重要代码均给出了注释,一看就懂.需要的同学可以在文末 ...

  3. 深度学习OSSIM关联分析(附源码注解)

    从海量安全事件中挖掘有用的威胁信息与情报是当今讨论的热门话题,同时这也是一个难点?怎么实现呢?这里用到一种技术叫做关联分析,他也是SIEM(Security  Information Event Ma ...

  4. 想知道深度学习卷积在GPU上如何优化吗?“大神”赵开勇带你深入浅出

    想知道深度学习卷积在GPU上如何优化吗?"大神"赵开勇带你深入浅出 2016-08-19 11:54 转载 陈杨英杰 0条评论 雷锋网(搜索"雷锋网"公众号关注 ...

  5. 深度学习 卷积神经网络-Pytorch手写数字识别

    深度学习 卷积神经网络-Pytorch手写数字识别 一.前言 二.代码实现 2.1 引入依赖库 2.2 加载数据 2.3 数据分割 2.4 构造数据 2.5 迭代训练 三.测试数据 四.参考资料 一. ...

  6. 毕设 深度学习卷积神经网络的花卉识别

    文章目录 0 前言 1 项目背景 2 花卉识别的基本原理 3 算法实现 3.1 预处理 3.2 特征提取和选择 3.3 分类器设计和决策 3.4 卷积神经网络基本原理 4 算法实现 4.1 花卉图像数 ...

  7. 深度学习 卷积神经网络原理

    深度学习 卷积神经网络原理 一.前言 二.全连接层的局限性 三.卷积层 3.1 如何进行卷积运算? 3.2 偏置 3.3 填充 3.4 步长 3.5 卷积运算是如何保留图片特征的? 3.6 三维卷积 ...

  8. 毕业设计 - 题目:基于深度学习卷积神经网络的花卉识别 - 深度学习 机器视觉

    文章目录 0 前言 1 项目背景 2 花卉识别的基本原理 3 算法实现 3.1 预处理 3.2 特征提取和选择 3.3 分类器设计和决策 3.4 卷积神经网络基本原理 4 算法实现 4.1 花卉图像数 ...

  9. 终于有人把OpenCV、人脸识别与深度学习讲明白了

    导读:今天聊OpenCV,我想从人脸识别讲起. 作者:木羊同学 来源:华章计算机(hzbook_jsj) 这几年人脸识别技术在国内发展飞速,给生活带了很多便利,这个大家应该都有体会.早几年进高铁站还比 ...

最新文章

  1. TCP/IP反码求和校验
  2. 什么是事务(transaction)?它有什么好处
  3. isp 图像算法(四)之white balance gain control 就是对 r,gr,gb,b 进行加权
  4. WebStrom如何设置字体?
  5. 吃了一辈子大米,你还在相信水稻种水里是因为喜欢水?
  6. 愚人节谁最皮?华为宣布攻克兽语,小米6复刻版官宣,微信发万元红包...
  7. jQuery标题文字淡入淡出显示效果
  8. linux 设开机默认启动
  9. 佳能Canon imageCLASS MF742Cdw 一体机驱动
  10. open modelica RLC仿真
  11. 高等数学 - 两平面的夹角
  12. Si5395/94/92时钟芯片配置步骤
  13. 区分微信开发平台和公众平台(小程序)
  14. 统计文件中元音字母的数量
  15. 微软推出Azure Sphere漏洞奖励计划,最高奖金10万美元
  16. delphi盒子希腊打开潘多拉魔盒?债务重组或是唯一出
  17. SX1278超时设置与计算
  18. 人工智能的主要应用领域
  19. js判断wifi_js判断手机是wifi还是流量
  20. 华为手机计算机如何表达平方,华为手机郑平方:荣耀成功源于共享质量体系

热门文章

  1. arcgis不闭合线转面_如何将ArcGIS不闭合线转化为面
  2. 2021服务器品牌前十大排名
  3. vue之实现移动端的复制粘贴功能(两种写法)
  4. 电子产品21个权威认证
  5. 视音频数据处理入门:H.264视频码流解析(java)
  6. [单片机框架] [drivers] [hc4051] 8路模拟分流器
  7. 个人微信开发API协议接口
  8. HART通讯协议及应用
  9. centeros 7 安装kafka
  10. python最优化算法实战---线性规划之内点法