OpenCV : 基于切线方向的边缘增强算法
来源:互联网 发布:淘宝怎么进淘宝客 编辑:程序博客网 时间:2024/05/20 01:34
使用切线方法,对切线方向上的边缘进行强化:
参考连接:图像锐化和边缘检测
代码:
//在种子点方向上寻找合适的梯度,用于寻找边缘//对low_Gray, high_gray之间的点寻找边缘void FindBestGradient( cv::Mat &_src, cv::Mat &_dst,cv::Point2f &seed,float low_Gray,float high_gray,int aperture_size, bool oPenEnhence ){//角度矩阵cv::Mat df = cv::Mat::zeros( _src.rows,_src.cols, CV_32FC1 );//梯度矩阵cv::Mat dg = cv::Mat::zeros( _src.rows,_src.cols, CV_32FC1 );//原始图像cv::Mat ds = _src.clone();//目标图像 uchar型cv::Mat dd = _src.clone();//1.根据角度计算梯度//得到梯度矩阵//使用N*1的算子int n = aperture_size;//必须为奇数//对每个柱进行初始化//搜索柱:在射线方向上搜索l_Search 个像素;宽度为 int l_Search = n;int w_Search = 1;std::vector<std::vector<std::pair<cv::Point ,float> > > beam;beam.resize( l_Search );for (int i=0;i< beam.size();++i){beam[i].resize(w_Search);}//初始化柱//设定系数//生成模板double gap = 2.0/ (n-1);std::vector< double > mask(l_Search);for (int i=0;i< mask.size();++i){mask[i] = -1 + i*gap ;}//2.生成角度图像//在射线方向上寻找//方法不是太好,但是没有寻找到简单有效的方法for ( int y=0 ;y< ds.rows;++y ){float* ptr = (float*)( df.data + y * df.step);unsigned char* pS = ( unsigned char* )( ds.data + y * ds.step);for ( int x=0; x< ds.cols; ++x ){//计算角度if ( (int)(*pS) > low_Gray && (int)(*pS) <high_gray ){*ptr = (float)(cvWish::cosCv(seed,cv::Point2f( x,y ) ) );} else{*ptr = 0.00000000000f;}++ptr;++pS;}}//计算差值-导数for (int y=0 ;y< ds.rows;++y){float* pf = (float*)( df.data + y * df.step);float* pg = (float*)( dg.data + y * dg.step);unsigned char* pd = (unsigned char*)( dd.data + y * dd.step);for (int x=0;x< ds.cols;++x ){//计算角度if ( abs((float)(*pf)) > 0.00000001 ){//cvWish::BeamInit(l_Search,w_Search,cv::Point2f( x,y ),df.at<float >(y,x),beam,0);//0表示从中部开始搜索cvWish::BeamInit(l_Search,w_Search,cv::Point2f( x,y ), *pf ,beam,0);//0表示从中部开始搜索cvWish::BeamNormal(dg.cols, dg.rows , beam);*pg = 0;for ( int k =0; k< l_Search; ++k ){*pg += (float)( mask[k]* ds.at<unsigned char>(beam[k][0].first.y,beam[k][0].first.x) );}int s = abs ( ( (int)(*pg ) )%255 ) ;*pd = (unsigned char) (s);}else{*pd = (unsigned char) (0);}++pf;++pg;++pd;}}cv::Mat edgeMat = dd;cv::Mat angleMat= df;int maskSize = 5;if ( oPenEnhence ){ int num = 1;for (int i=0;i< num;++i){EnhanceEdgeByTangent( edgeMat ,angleMat, maskSize);}} else{}_dst = edgeMat.clone();return;}
边缘强化函数:
//使用边缘增强--沿切线方向增强//方向性,边缘限制void EnhanceEdgeByTangent( cv::Mat &edgeMat ,cv::Mat &angleMat, int maskSize){cv::Mat ds = edgeMat;cv::Mat dd = edgeMat.clone();cv::Mat df = angleMat;cv::Mat dg = angleMat.clone();//导数图,最终转化为 灰度图 ddconst int l_Search = maskSize;const int w_Search = 1;//初始化柱std::vector<std::vector<std::pair<cv::Point ,float> > > beam;beam.resize( l_Search );for (int i=0;i< beam.size();++i){beam[i].resize(w_Search);}//初始化柱//设定系数//生成模板double gap = 2.0/ ( l_Search - 1);std::vector< double > mask(l_Search);for (int i=0;i< mask.size();++i){mask[i] =abs( 1- abs( -1 + i*gap ) );}//强化边缘for (int y=0 ;y< ds.rows;++y){float* pf = (float*)( df.data + y * df.step);float* pg = (float*)( dg.data + y * dg.step);unsigned char* pd = (unsigned char*)( dd.data + y * dd.step);for ( int x=0; x< ds.cols; ++x ){//计算角度if ( abs((float)(*pf)) > 0.00000001 ){float angle = *pf + PI_1_2 ;//切线方向,加 PI_1_2angle = angle>=PI_4_2? angle - PI_4_2:angle;cvWish::BeamInit( l_Search, w_Search, cv::Point2f( x,y ), angle , beam, 0 );cvWish::BeamNormal(dg.cols, dg.rows , beam);*pg = 0;const int gl= ds.at<unsigned char>(y,x) ;//当前像素值int vvv = dd.at<unsigned char>(y,x);for ( int k =0; k< l_Search; ++k ){vvv += gl* mask[k];}if ( vvv>255 ){vvv=255 ;} dd.at<unsigned char>(y,x) = vvv;//*pd = (unsigned char) (s);}else{*pd = (unsigned char) (0);}++pf;++pg;++pd;}}edgeMat = dd.clone();return ;}
图片效果:
0 0
- OpenCV : 基于切线方向的边缘增强算法
- 基于opencv的边缘检测
- 物体运动的切线方向
- 基于opencv的多种边缘算子的边缘检测
- 基于opencv 的Canny边缘检测算法原理及其VC实现详解
- OpenCV_基于Laplacian算子的图像边缘增强
- OpenCV_基于Laplacian算子的图像边缘增强
- 为什么梯度的方向与等高线切线方向垂直?
- OpenCV实现边缘算法
- 基于canny的边缘检测算法:
- 基于Qualcomm FastCv的边缘检测算法
- 基于边缘的图像分割——分水岭算法(watershed)算法分析(附opencv源码分析)
- OpenCV 基于RGB三原色的基本线性变换 改变图像颜色和亮度 对比度增强算法
- OpenCV,常用图像增强算法的实现
- 基于OpenCV的canny边缘检测的MFC实现
- 基于OPENCV的CANNY边缘检测算子详细代码实现
- OpenCV实现基于Zernike矩的亚像素边缘检测
- OpenCV实现基于Zernike矩的亚像素边缘检测
- 设计模式分类及介绍
- 添加重启和飞行模式
- Graham's Scan法求凸包
- 解析QT多线程程序详细设计之QObject可重入性 下篇
- 自定义dialog的方式,以及需要注意事项
- OpenCV : 基于切线方向的边缘增强算法
- react
- [Linux] 内核的 /proc 文件系统介绍及使用方法
- 05 简单的字符设备驱动操作
- 输入任意正整数a,b,c,返回最大值
- Java Serialization/序列化/反序列化 及 transient Java关键字详解
- eclipse自动调整代码格式
- 专题四1011
- mongo 更新数组 键值对