//顶帽去光差,radius为模板半径
    Mat moveLightDiff(Mat src,int radius){
        Mat dst;
        Mat srcclone = src.clone();
        Mat mask = Mat::zeros(radius*2,radius*2,CV_8U);
        circle(mask,Point(radius,radius),radius,Scalar(255),-1);
        //顶帽
        erode(srcclone,srcclone,mask);
        dilate(srcclone,srcclone,mask);
        dst =  src - srcclone;
        return dst;

}

算法来自于冈萨雷斯《数字图像处理教程》形态学篇章。完全按照教程实现,具备一定作用。
 
    //将 DEPTH_8U型二值图像进行细化  经典的Zhang并行快速细化算法
    //细化算法
    void thin(const Mat &src, Mat &dst, const int iterations){
        const int height =src.rows -1;
        const int width  =src.cols -1;
        //拷贝一个数组给另一个数组
        if(src.data != dst.data)
            src.copyTo(dst);
        int n = 0,i = 0,j = 0;
        Mat tmpImg;
        uchar *pU, *pC, *pD;
        bool isFinished =FALSE;
        for(n=0; n<iterations; n++){
            dst.copyTo(tmpImg); 
            isFinished =FALSE;   //一次 先行后列扫描 开始
            //扫描过程一 开始
            for(i=1; i<height;  i++) {
                pU = tmpImg.ptr<uchar>(i-1);
                pC = tmpImg.ptr<uchar>(i);
                pD = tmpImg.ptr<uchar>(i+1);
                for(int j=1; j<width; j++){
                    if(pC[j] > 0){
                        int ap=0;
                        int p2 = (pU[j] >0);
                        int p3 = (pU[j+1] >0);
                        if (p2==0 && p3==1)
                            ap++;
                        int p4 = (pC[j+1] >0);
                        if(p3==0 && p4==1)
                            ap++;
                        int p5 = (pD[j+1] >0);
                        if(p4==0 && p5==1)
                            ap++;
                        int p6 = (pD[j] >0);
                        if(p5==0 && p6==1)
                            ap++;
                        int p7 = (pD[j-1] >0);
                        if(p6==0 && p7==1)
                            ap++;
                        int p8 = (pC[j-1] >0);
                        if(p7==0 && p8==1)
                            ap++;
                        int p9 = (pU[j-1] >0);
                        if(p8==0 && p9==1)
                            ap++;
                        if(p9==0 && p2==1)
                            ap++;
                        if((p2+p3+p4+p5+p6+p7+p8+p9)>1 && (p2+p3+p4+p5+p6+p7+p8+p9)<7){
                            if(ap==1){
                                if((p2*p4*p6==0)&&(p4*p6*p8==0)){                           
                                    dst.ptr<uchar>(i)[j]=0;
                                    isFinished =TRUE;                            
                                }
                            }
                        }                    
                    }
 
                } //扫描过程一 结束
                dst.copyTo(tmpImg); 
                //扫描过程二 开始
                for(i=1; i<height;  i++){
                    pU = tmpImg.ptr<uchar>(i-1);
                    pC = tmpImg.ptr<uchar>(i);
                    pD = tmpImg.ptr<uchar>(i+1);
                    for(int j=1; j<width; j++){
                        if(pC[j] > 0){
                            int ap=0;
                            int p2 = (pU[j] >0);
                            int p3 = (pU[j+1] >0);
                            if (p2==0 && p3==1)
                                ap++;
                            int p4 = (pC[j+1] >0);
                            if(p3==0 && p4==1)
                                ap++;
                            int p5 = (pD[j+1] >0);
                            if(p4==0 && p5==1)
                                ap++;
                            int p6 = (pD[j] >0);
                            if(p5==0 && p6==1)
                                ap++;
                            int p7 = (pD[j-1] >0);
                            if(p6==0 && p7==1)
                                ap++;
                            int p8 = (pC[j-1] >0);
                            if(p7==0 && p8==1)
                                ap++;
                            int p9 = (pU[j-1] >0);
                            if(p8==0 && p9==1)
                                ap++;
                            if(p9==0 && p2==1)
                                ap++;
                            if((p2+p3+p4+p5+p6+p7+p8+p9)>1 && (p2+p3+p4+p5+p6+p7+p8+p9)<7){
                                if(ap==1){
                                    if((p2*p4*p8==0)&&(p2*p6*p8==0)){                           
                                        dst.ptr<uchar>(i)[j]=0;
                                        isFinished =TRUE;                            
                                    }
                                }
                            }                    
                        }
                    }
                } //一次 先行后列扫描完成          
                //如果在扫描过程中没有删除点,则提前退出
                if(isFinished ==FALSE)
                    break; 
            }
        }
    }

#end of thin

细化算法,在处理毛笔字一类的时候效果很好。使用的过程中,注意需要保留的部分要处理为白色,也就是scalar(255)
 

【20160924】GOCVHelper 图像增强部分(3)的更多相关文章

  1. 【20160924】GOCVHelper 图像增强部分(4)

    //使得rect区域半透明     Mat translucence(Mat src,Rect rect,int idepth){         Mat dst = src.clone();     ...

  2. 【20160924】GOCVHelper 图像增强部分(1)

    图像增强是图像处理的第一步.这里集成了一些实际使用过程中有用的函数.   //读取灰度或彩色图片到灰度     Mat imread2gray(string path){         Mat sr ...

  3. 【20160924】GOCVHelper 图像增强部分(5)

    // Multiply 正片叠底 void Multiply(Mat& src1, Mat& src2, Mat& dst) {     for(int index_row=0 ...

  4. 【20160924】GOCVHelper 图像增强部分(2)

       //填充孔洞     //fillholes     Mat fillHoles(Mat src){         Mat dst = getInnerHoles(src);          ...

  5. 基于Opencv和Mfc的图像处理增强库GOCVHelper(索引)

    GOCVHelper(GreenOpen Computer Version Helper )是我在这几年编写图像处理程序的过程中积累下来的函数库.主要是对Opencv的适当扩展和在实现Mfc程序时候的 ...

  6. 【20160924】GOCVHelper综述

    GOCVHelper(GreenOpen Computer Version Helper )是我在这几年编写图像处理程序的过程中积累下来的函数库.主要是对Opencv的适当扩展和在实现Mfc程序时候的 ...

  7. 【20160924】GOCVHelper MFC增强算法(4)

    //string替换     void string_replace(string & strBig, const string & strsrc, const string & ...

  8. 【20160924】GOCVHelper 图像处理部分(3)

    //根据轮廓的圆的特性进行选择     vector<VP> selectShapeCircularity(Mat src,Mat& draw,vector<VP> c ...

  9. 【20160924】GOCVHelper 图像处理部分(2)

    //根据轮廓的面积大小进行选择     vector<VP>  selectShapeArea(Mat src,Mat& draw,vector<VP> contour ...

随机推荐

  1. 【java开发系列】—— JDK安装

    前言 作为一个java开发者,安装JDK是不可避免的,但是配置路径却总是记不住,百度也有很多参考例子.这里仅仅当做以后参考的笔记记录. 说到JDK,就不得不提JRE.他们到底是什么呢? 通常我们进行j ...

  2. SLF4J环境变量配置

    因部分程序需要,需要把SLF4J加入到环境变量中. 添加位置:CLASSPATH 添加信息如下: C:\slf4j-1.7.19\slf4j-nop-1.7.19.jar;

  3. [原创]java WEB学习笔记55:Struts2学习之路---详解struts2 中 Action,如何访问web 资源,解耦方式(使用 ActionContext,实现 XxxAware 接口),耦合方式(通过ServletActionContext,通过实现 ServletRequestAware, ServletContextAware 等接口的方式)

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  4. 认识javascript

    javascript小知识 www.phonegap.com(跨平台开发框架) Cocos2d-Html5(WebGL渲染  javascript语言) creatjs.com(融合了flash动画的 ...

  5. 判断java中两个对象是否相等

    java中的基本数据类型判断是否相等,直接使用"=="就行了,相等返回true,否则,返回false. 但是java中的引用类型的对象比较变态,假设有两个引用对象obj1,obj2 ...

  6. hibernate 表配置文件如何设置表字段的默认值

    修改对应实体类的配置文件,比如说 public class User{ private int age; //setter //getter } 配置文件 <property name=&quo ...

  7. Mysql 的存储引擎,myisam和innodb的区别

    MyISAM 是非事务的存储引擎,innodb是支持事务的存储引擎. innodb的引擎比较适合于插入和更新操作比较多的应用,而MyISAM 则适合用于频繁查询的应用 . MyISAM --表锁,in ...

  8. jQuery触发<a>标签的点击事件后URL不跳转的解决办法

    有HTML代码如下: <a id="workFrame" href="pages/work.html" target="FrameBox&quo ...

  9. Test Android with QTP

    by Yaron Assa I have recently come across a plug-in to QTP that enables to automate tests on Android ...

  10. 三层架构中bll层把datatable转换为实体model的理解

    看了很多人的项目,很多都是用到三层架构,其中BLL层中有一种将DataTable转换为实体的方法.一直没有明白为啥要这样做,今天特意去搜索了一下,如果没有答案我是准备提问,寻求解答了.还好找到一个相关 ...