• OpenCV图像细化的一个例子


    转自:http://blog.csdn.net/zfdxx369/article/details/9091953?utm_source=tuicool

    本文是zhang的一篇经典图像细化论文,效果很好,采用并行计算,速度非常快;

    下文是 "智慧视觉"在CSDN上对这篇论文程序的一个改造,亲测可用!

    由于OpenCV没有自带的图像细化函数,网上提供的基本是基于1.0接口的,于是乎动手搞成2.0 Mat类型接口的,方便好用。细化方法当中,当属经典的Zhang并行快速细化算法,细化之后的轮廓走势与原图保持得相对较好.

    //将 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;                            
                               }
                          
                            //   if((p2*p4*p8==0)&&(p2*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*p6==0)&&(p4*p6*p8==0))
                            //   {                           
                           //         dst.ptr<uchar>(i)[j]=0;
                           //         isFinished =TRUE;                            
                           //    }
                          
                               if((p2*p4*p8==0)&&(p2*p6*p8==0))
                               {                           
                                    dst.ptr<uchar>(i)[j]=0;
                                    isFinished =TRUE;                            
                               }
                           
                         }
                    }                    
                }
    
               }
    
              } //一次 先行后列扫描完成          
            //如果在扫描过程中没有删除点,则提前退出
             if(isFinished ==FALSE)
             {
                break; 
             }
            }
    
        }
    }
    
  • 相关阅读:
    工作总结系列---【端口被占用,如何取消端口进程】
    封装工具系列---【封装H5页面管理机构和证件类型下拉框数据处理的方法】
    工作总结系列---【vue页面实现导出表格效果】
    vscode---【内网开发下,离线安装vscode插件vsix文件】
    工作总结系列---【IDE深色背景下,鼠标移动也变成黑色,看不清怎么解决???】
    node系列---【为什么要设置镜像源?怎么配置?】
    git系列---【如何在本地修改别人的代码图解】
    git系列---【git如何回退到上一个版本??】
    封装工具系列---【补零操作】
    封装的各类工具系列---【时间格式化为YYYY-MM-DD格式 】
  • 原文地址:https://www.cnblogs.com/meadow-glog/p/4675521.html
Copyright © 2020-2023  润新知