转自:http://blog.csdn.net/byxdaz/archive/2010/06/02/5642669.aspx

细化算法通常和骨骼化、骨架化算法是相同的意思,也就是thin算法或者skeleton算法。虽然很多图像处理的教材上不是这么写的,具体原因可以看这篇论文,Louisa Lam, Seong-Whan Lee, Ching Y. Suen,“Thinning Methodologies-A Comprehensive Survey ”,IEEE TRANSACTIONS ON PATTERN ANALYSIS AND MACHINE INTELLIGENCE, VOL. 14, NO. 9, SEPTEMBER 1992 ,总结了几乎所有92年以前的经典细化算法。

函数:void cvThin( IplImage* src, IplImage* dst, int iterations=1)
功能:将IPL_DEPTH_8U型二值图像进行细化
参数:src,原始IPL_DEPTH_8U型二值图像
dst,目标存储空间,必须事先分配好,且和原图像大小类型一致
iterations,迭代次数
参考文献:T. Y. Zhang and C. Y. Suen, “A fast parallel algorithm for thinning digital patterns,” Comm. ACM, vol. 27, no. 3, pp. 236-239, 1984.

void cvThin( IplImage* src, IplImage* dst, int iterations=1)
{
 CvSize size = cvGetSize(src);

cvCopy(src, dst);
    int n = 0,i = 0,j = 0;
 for(n=0; n<iterations; n++)
 {
  IplImage* t_image = cvCloneImage(dst);
  for(i=0; i<size.height;  i++)
  {
   for(j=0; j<size.width; j++)
   {
    if(CV_IMAGE_ELEM(t_image,byte,i,j)==1)
    {
     int ap=0;
     int p2 = (i==0)?0:CV_IMAGE_ELEM(t_image,byte, i-1, j);
     int p3 = (i==0 || j==size.width-1)?0:CV_IMAGE_ELEM(t_image,byte, i-1, j+1);
     if (p2==0 && p3==1)
     {
      ap++;
     }
     int p4 = (j==size.width-1)?0:CV_IMAGE_ELEM(t_image,byte,i,j+1);
     if(p3==0 && p4==1)
     {
      ap++;
     }
     int p5 = (i==size.height-1 || j==size.width-1)?0:CV_IMAGE_ELEM(t_image,byte,i+1,j+1);
     if(p4==0 && p5==1)
     {
      ap++;
     }
     int p6 = (i==size.height-1)?0:CV_IMAGE_ELEM(t_image,byte,i+1,j);
     if(p5==0 && p6==1)
     {
      ap++;
     }
     int p7 = (i==size.height-1 || j==0)?0:CV_IMAGE_ELEM(t_image,byte,i+1,j-1);
     if(p6==0 && p7==1)
     {
      ap++;
     }
     int p8 = (j==0)?0:CV_IMAGE_ELEM(t_image,byte,i,j-1);
     if(p7==0 && p8==1)
     {
      ap++;
     }
     int p9 = (i==0 || j==0)?0:CV_IMAGE_ELEM(t_image,byte,i-1,j-1);
     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))
       {
        if(!(p4 && p6 && p8))
        {
         CV_IMAGE_ELEM(dst,byte,i,j)=0;
        }
       }
      }
     }

}
   }
  }
  cvReleaseImage(&t_image);
  t_image = cvCloneImage(dst);
  for(i=0; i<size.height;  i++)
  {
   for(int j=0; j<size.width; j++)
   {
    if(CV_IMAGE_ELEM(t_image,byte,i,j)==1)
    {
     int ap=0;
     int p2 = (i==0)?0:CV_IMAGE_ELEM(t_image,byte, i-1, j);
     int p3 = (i==0 || j==size.width-1)?0:CV_IMAGE_ELEM(t_image,byte, i-1, j+1);
     if (p2==0 && p3==1)
     {
      ap++;
     }
     int p4 = (j==size.width-1)?0:CV_IMAGE_ELEM(t_image,byte,i,j+1);
     if(p3==0 && p4==1)
     {
      ap++;
     }
     int p5 = (i==size.height-1 || j==size.width-1)?0:CV_IMAGE_ELEM(t_image,byte,i+1,j+1);
     if(p4==0 && p5==1)
     {
      ap++;
     }
     int p6 = (i==size.height-1)?0:CV_IMAGE_ELEM(t_image,byte,i+1,j);
     if(p5==0 && p6==1)
     {
      ap++;
     }
     int p7 = (i==size.height-1 || j==0)?0:CV_IMAGE_ELEM(t_image,byte,i+1,j-1);
     if(p6==0 && p7==1)
     {
      ap++;
     }
     int p8 = (j==0)?0:CV_IMAGE_ELEM(t_image,byte,i,j-1);
     if(p7==0 && p8==1)
     {
      ap++;
     }
     int p9 = (i==0 || j==0)?0:CV_IMAGE_ELEM(t_image,byte,i-1,j-1);
     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)
       {
        if(p2*p6*p8==0)
        {
         CV_IMAGE_ELEM(dst, byte,i,j)=0;
        }
       }
      }
     }                   
    }

}

}           
  cvReleaseImage(&t_image);
 }

}

//使用举例

#include "cxcore.h"
#include "cv.h"
#include "highgui.h"

int main(int argc, char* argv[])
{
 if(argc!=2)
 {
  return 0;
 }
 IplImage *pSrc = NULL,*pDst = NULL,*pTmp = NULL;

//传入一个灰度图像
 pSrc = cvLoadImage(argv[1],CV_LOAD_IMAGE_GRAYSCALE);
 if(!pSrc)
 {
  return 0;
 }
 pTmp = cvCloneImage(pSrc);
    pDst = cvCreateImage(cvGetSize(pSrc),pSrc->depth,pSrc->nChannels);
 cvZero(pDst);
 cvThreshold(pSrc,pTmp,128,1,CV_THRESH_BINARY_INV);//做二值处理,将图像转换成0,1格式
 //cvSaveImage("c://Threshold.bmp",pTmp,0);
 cvThin(pTmp,pDst,8);//细化,通过修改iterations参数进一步细化
 cvNamedWindow("src",1);
 cvNamedWindow("dst",1);
 cvShowImage("src",pSrc);
 //将二值图像转换成灰度,以便显示
 int i = 0,j = 0;
 CvSize size = cvGetSize(pDst);
 for(i=0; i<size.height;  i++)
 {
  for(j=0; j<size.width; j++)
  {
   if(CV_IMAGE_ELEM(pDst,uchar,i,j)==1)
   {
    CV_IMAGE_ELEM(pDst,uchar,i,j) = 0;
   }
   else
   {
    CV_IMAGE_ELEM(pDst,uchar,i,j) = 255;
   }
  }
 }
 //cvSaveImage("c://thin.bmp",pDst);
 cvShowImage("dst",pDst);
 cvWaitKey(0);
    cvReleaseImage(&pSrc);
 cvReleaseImage(&pDst);
 cvReleaseImage(&pTmp);
 cvDestroyWindow("src");
 cvDestroyWindow("dst");
 return 0;
}

opencv实现二值图像细化的算法相关推荐

  1. OpenCV学习(14) 细化算法(2)

    前面一篇教程中,我们实现了Zhang的快速并行细化算法,从算法原理上,我们可以知道,算法是基于像素8邻域的形状来决定是否删除当前像素.还有很多与此算法相似的细化算法,只是判断的条件不一样.在综述文章, ...

  2. 【opencv】图像细化

    [opencv]图像细化 [opencv]图像细化 2014-02-17 21:03 5404人阅读 评论(14) 收藏 举报  分类: opencv(1)  版权声明:本文为博主原创文章,未经博主允 ...

  3. 使用Python,OpenCV的Meanshift 和 Camshift 算法来查找和跟踪视频中的对象

    使用Python,OpenCV的Meanshift 和 Camshift 算法来查找和跟踪视频中的对象 1. 效果图 2. 源码 2.1 MeanShift 2.2 Camshift(Continuo ...

  4. OpenCV中直方图反向投影算法详解与实现

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达本文转自:opencv学堂 一:直方图交叉 OpenCV中直方图反向 ...

  5. OpenCV均值漂移meanshift algorithm算法的实例(附完整代码)

    OpenCV均值漂移meanshift algorithm算法的实例 OpenCV均值漂移meanshift algorithm算法的实例 OpenCV均值漂移meanshift algorithm算 ...

  6. OpenCV支持向量机SVM和SDG算法的实例(附完整代码)

    OpenCV支持向量机SVM和SDG算法的实例 OpenCV支持向量机SVM和SDG算法的实例 OpenCV支持向量机SVM和SDG算法的实例 #include "opencv2/core. ...

  7. OpenCV实现图像对齐ECC算法(附完整代码)

    OpenCV实现图像对齐ECC算法 OpenCV实现图像对齐ECC算法 OpenCV实现图像对齐ECC算法 #include <opencv2/imgcodecs.hpp> #includ ...

  8. OpenCV实现最大最小距离聚类算法

    OpenCV实现最大最小距离聚类算法 [尊重原创,转载请注明出处]https://blog.csdn.net/guyuealian/article/details/80255524 本博客提供多版本的 ...

  9. Win8 Metro(C#)数字图像处理--2.40二值图像轮廓提取算法

    Win8 Metro(C#)数字图像处理--2.40二值图像轮廓提取算法 原文:Win8 Metro(C#)数字图像处理--2.40二值图像轮廓提取算法  [函数名称] 二值图像轮廓提取      ...

最新文章

  1. BCH阵营对立将导致共识失败?Cobra有话说!
  2. soapui + groovy 接口自动化测试 第八章
  3. php mysql odbc_PHP Database ODBC
  4. java项目红叉_完美解决Eclipse导入的项目上有个红叉,但不影响项目运行的问题
  5. C语言经典算法100例-002-数轴的使用
  6. Java\学习——字符串
  7. 使用Windows远程桌面工具来远程连接控制Ubuntu系统
  8. 如何仅对文档项目在ECB中应用自定义操作
  9. Tomcat无法启动:Server Tomcat v8.5 Server at localhost failed to start
  10. 值得收藏!中国金融体系主要指标大全
  11. 小菜找实习——阿里3月27日场笔试第一题
  12. 照片放大不清晰怎么处理?用嗨格式图片无损放大器
  13. 1688-API接口安全详解
  14. ATX电源接口, 服务器插拔电源接口
  15. Nature:进化新方式?线粒体DNA会插入我们的基因组
  16. 龙卷风路径_【龙卷风的防范措施】龙卷风的易发地点_龙卷风如何分级 - 妈妈网百科...
  17. java实现中文数字与阿拉伯数字互相转换
  18. C. Get an Even String
  19. fiddler安卓模拟器与ios手机抓包
  20. 关于Kaggle入门,看这一篇就够了

热门文章

  1. FPGA(4)晶振与计数器 -- 实现定时器(led定时闪烁、蜂鸣器频率控制(单响)、蜂鸣器报警(频带控制,多响))
  2. raw格式图片读取与显示C++,opencv
  3. 面向固态激光雷达和惯导的里程计和建图
  4. 在CentOS 6.8 x86_64上安装nghttp2最新版及让curl具有http2特性
  5. Blender从头开始装配和动画制作低多边形风格的FPS手臂
  6. f-free 查看系统中空闲和使用的内存
  7. fedora装机后要运行的脚本(原创)
  8. React navtive
  9. 报表性能优化方案之报表服务器优化基础讲解
  10. 如果asp.net mvc中某个action被执行了两次,请检查是不是以下的原因