下载 >  开发技术 >  C++ > 基于索引表的图像细化程序有详细注解

基于索引表的图像细化程序有详细注解 评分:

// XiHua.cpp : 定义控制台应用程序的入口点。 // //基于索引表的图像细化算法 //#include "stdafx.h" #include "highgui.h" #include "cv.h"//包含cvCreateStructuringElementEx();颜色空间转换函数cvCvtColor()需要 //#include "cxcore.h" //#pragma comment(lib, "opencv_core249.lib")//opencv_core249.lib取代cv.lib等---(不懂以后再一一对应) //#pragm a comment(lib,"opencv_highgui249.lib") //#pragma comment(lib,"opencv_imgproc249.lib") #include <stdlib.h> #include <string.h> //基于索引表的细化细化算法 //功能:对图象进行细化 //参数:lpDIBBits:代表图象的一维数组 // lWidth:图象高度 // lHeight:图象宽度 // 代表图象的一维数组 图象宽度 图象高度 bool ThiningDIBSkeleton(unsigned char* imagedata, int lWidth, int lHeight) { /* unsigned char* imagedata; imagedata = new uchar[sizeof(char) * src->width * src->height](); */ /* deletemark[256]为前人据8领域总结的是否可以被删除的256种情况 不可以删除用0来表示,能被删除的用1来表示 */ unsigned char deletemark[256] = { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0 };//索引表 //循环变量 //long i; //long j; unsigned char p0, p1, p2, p3, p4, p5, p6, p7; unsigned char *pmid, *vergeMark; // pmid 用来指向二值图像 vergeMark用来指向存放是否为边缘 unsigned char sum; bool bStart = true; //动态创建一个长度为sizeof(char) * src->width * src->height的数组 //并且初始化把数组元素都设置为0 //长度与imagedata长度一样 long lLength; lLength = lWidth * lHeight; //数组长度 unsigned char *pTemp = new uchar[sizeof(unsigned char) * lLength](); // P0 P1 P2 // P7 P3 // P6 P5 P4 while (bStart) { bStart = false; //每次循环pTemp所有元素都置0 memset(pTemp, 0, lLength);//初始化pTemp指向的lLength空间全部初始化为0 /*---------------首先求边缘点----------------*/ pmid = (unsigned char *)imagedata + lWidth + 1; // pmid 用来指向二值图像矩阵的第二行 +1 表示不考虑图像第一行 vergeMark = (unsigned char *)pTemp + lWidth + 1; //pmidtemp用来指向存放是否为边缘 如果是边缘点 则将其设为1 for (int i = 1; i < lHeight - 1; i++) //lHeight -1表示不考虑图像最后一行 第一列 { for (int j = 1; j < lWidth - 1; j++) //lWidth - 1表示不考虑图像最后一列 { //图像已经是01化,如果是0我们不考虑 if (*pmid == 0) { pmid++; vergeMark++; continue; } //如果是1,是我们考虑的点 我们需要对周围8个进行判断是否边缘 p0 = *(pmid - lWidth - 1); p1 = *(pmid - lWidth); // P0 P1 P2 p2 = *(pmid + 1 - lWidth); // P7 P3 p3 = *(pmid + 1); // P6 P5 P4 p4 = *(pmid + lWidth + 1); p5 = *(pmid + lWidth); p6 = *(pmid + lWidth - 1); p7 = *(pmid - 1); //p0--到---p7的值不是0就是1 sum = p0 & p1 & p2 & p3 & p4 & p5 & p6 & p7;//如果是边缘,肯定周围的P0P1P2P3P4P5P6P7 中一定至少有一个为0 if (sum == 0) { *vergeMark = 1;// 表记边缘 } pmid++; vergeMark++; } pmid++;//跳过图像最后一列,不考虑 vergeMark++; pmid++;//跳过图像第一列,不考虑 vergeMark++; } /*---------------沿着边缘现在开始删除----------------*/ pmid = (unsigned char *)imagedata + lWidth + 1; vergeMark = (unsigned char *)pTemp + lWidth + 1; for (long i = 1; i < lHeight - 1; i++) // 不考虑图像第一行 第一列 最后一行 最后一列 { for (long j = 1; j < lWidth - 1; j++) { //*vergeMark=0表示这个点不是边缘,即不进行删除 if (*vergeMark == 0) { pmid++; vergeMark++; continue; } //如果是1,是我们考虑的点 我们需要对周围8个进行判断 //判断一个点是否能去掉, 要根据它的八个相邻点的情况来判断 p0 = *(pmid - lWidth - 1); p1 = *(pmid - lWidth); // P0 P1 P2 p2 = *(pmid - lWidth + 1 ); // P7 P3 p3 = *(pmid + 1); // P6 P5 P4 p4 = *(pmid + lWidth + 1); p5 = *(pmid + lWidth); p6 = *(pmid + lWidth - 1); p7 = *(pmid - 1); /*根据它的八个相邻点的情况形成的索引表进行删除操作 * * 经过预处理后得到待细化的图像是0、1二值图像。 * 像素值为1的是需要细化的部分,像素值为0的是背景区域。 * * 基于索引表的算法就是"依据一定的判断依据",所做出的一张表, * 因为一个像素的8个邻域,我们可以用8位二进制表示,共有256中可能情况, * 因此,索引表的大小一般为256。 * 根据索引值对应表中的位置存0或1, * 当前像素不能删除存为0, * 可以删除存为1。 * * 然后根据要细化的点的八个邻域的在索引表中情况查询, * 若表中元素是1,则删除该点(改为背景) * 若是0则保留。 * * * ---------------------------------------- * |p7 | p6 | p5 | p4 | p3 | p2 | p1 | p0 |---索引值对应表中的位置-----》共有256中可能情况 * ---------------------------------------- (位置1)0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0(位置256) */ //此时p0--到---p7的值不是0就是1 p1 *= 2; p2 *= 4; p3 *= 8; p4 *= 16; p5 *= 32; p6 *= 64; p7 *= 128; sum = p0 | p1 | p2 | p3 | p4 | p5 | p6 | p7; // sum = p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7; if (deletemark[sum] == 1)//可以删除 { *pmid = 0; bStart = true; // 表明本次扫描进行了细化 } pmid++; vergeMark++; } pmid++;//跳过图像最后一列,不考虑 vergeMark++; pmid++;//跳过图像第一列,不考虑 vergeMark++; } } //循环结束说明没有可以继续细化的点了,则为细化结束 delete[]pTemp; return true; } int main(int argc, char* argv[]) { //加载原图像 IplImage* src = cvLoadImage("F:\\zhengning\\QtOpencv\\Images\\xihua.PNG", 0); //---------------------------预处理二值化------------------------------------ //对原图像进行二值化 阈值 cvThreshold(src, src, 100, 255, CV_THRESH_BINARY); /* 图像二值化就是将图像上的像素点的灰度值设置为0或255, 也就是将整个图像呈现出明显的黑白效果 CV_THRESH_BINARY 意思为: if src(x,y) > 100 src(x,y)=255 else src(x,y)=-0 原图像由0到255---->0或255 */ cvNamedWindow("s", 0); cvShowImage("s", src); //-----------------------------预处理0/1化------------------------------------- /* 将imagedata指向的与原图像大小一下的数组空间进行0或1赋值 二值图有原来的0或255----->------0或1 */ //动态创建一个长度为sizeof(char) * src->width * src->height的字符数组 //并且初始化把数组元素都设置为0 unsigned char* imagedata; imagedata = new uchar[sizeof(char) * src->width * src->height](); int x, y; for (y = 0; y<src->height; y++) { /* widthStep表示存储一行像素需要的字节数 偏移到第y行 */ unsigned char* ptr = (unsigned char*)(src->imageData + y*src->widthStep); for (x = 0; x<src->width; x++) { /* 判断第y行第x列的元素值是否大于0 大于0时将数组对应的位置元素设置为1 不大于0则设置为0 imagedata数组里面不是0就时1 */ imagedata[y*src->width + x] = ptr[x] > 0 ? 1 : 0; //经过预处理后得到待细化的图像是0、1二值图像。 } } //----------------------------细化----------------------------------------- //经过预处理后得到待细化的图像是0、1二值图像。 //细化一次,和细化多次,由于索引表不变,每次细化效果都一样,想采用多次细化无法消除毛刺 ThiningDIBSkeleton(imagedata, src->width, src->height); //--------------------对细化后的0/1图二值化(0/255)----------------------------- /* 将ptr指向的与原图像大小一下的数组空间进行0或255赋值 */ for (y = 0; y<src->height; y++) { /* widthStep表示存储一行像素需要的字节数 偏移到第y行 */ unsigned char* ptr = (unsigned char*)(src->imageData + y*src->widthStep); for (x = 0; x<src->width; x++) { /* 判断第y行第x列的元素值是否大于0 大于0时将数组对应的位置元素设置为1 不大于0则设置为0 ptr指向的空间的值不是0就是255 也就是细化之后再次变为二值图 */ ptr[x] = imagedata[y*src->width + x]>0 ? 255 : 0; } } //------------------------------------------------------------------------- cvNamedWindow("src", 0); cvShowImage("src", src); cvWaitKey(0); delete[]imagedata; return 0; }
...展开详情收缩
2016-01-31 上传大小:13KB
分享
收藏 举报
索引表
基于索引表的二值化图像细化算法
细化算法
二值图像快速细化算法
Opencv——基于索引表的图像细化
opencv 骨架提取算法 (查表索引法)

利用查表索引法提取并细化骨架,Mat类型实现、iplimage类型实现

立即下载
基于索引表的细化算法 程序源码

本程序基于VC++,读取BMP数据(建议256色),通过基于索引表的细化算法进行细化操作。数据必须使用二值图像数据,背景为白色,线数据为黑色。不支持PNG、JPG图像。

立即下载
图像细化C++代码

图像细化的传统算法的c++代码 Hilditch细化算法 Pavlidis细化算法 Rosenfeld细化算法 基于索引表的细化细化算法

立即下载
四种不同的图像细化算法的VC++源码

四种不同的图像细化算法的VC++源码: 1.Hilditch细化算法 2.Pavlidis细化算法 3.Rosenfeld细化算法 4.基于索引表的细化细化算法

立即下载
基于索引表的细化算法

本算法先查找边缘点,再查表删除,精度较高

立即下载
图像细化 + 图像细化 Canny边缘检测

是源代码,可以直接运行,有Canny边缘检测,其中包括高斯滤波,梯度计算,非极大值抑制,边缘跟踪,图像细化包括Rosenfeld和索引表细化,有详细注释

立即下载
图像骨架提取(细化

Matlab 资源代码,该资源是图像处理中对图形进行二值化处理然后进行骨架提取(图像细化)。

立即下载
MATLAB 变灰度图像索引图像、二值图像

matlab代码,用于图像处理放向研究。把图像变成变灰度图像,索引图像或二值图像。

立即下载
VB 指令、函数 索引表.VB 指令、函数 索引表.

VB 指令、函数 索引表.VB 指令、函数 索引表.VB 指令、函数 索引表.VB 指令、函数 索引表.VB 指令、函数 索引表.

立即下载
基于表驱动法的三种实现方法

表驱动法分为直接访问,索引访问,阶梯访问三种方式,分别对应相应代码,代码里有详细注释

立即下载
索引类型-说明(索引文件有数据文件和索引表文件组成)

索引类型-说明 索引文件有数据文件和索引表文件组成。 索引表中存放记录的关键字和记录在文件中的位置。 多级索引。

立即下载
指纹图像二值化和细化源代码

索引表细化算法,固定阈值二值化算法,只能打开BMP图片,用CDIB类实现的。

立即下载
opencv 图像分割、边缘提取、骨架提取

改代码主要涉及到灰度图像的分割,包括均值聚类,ostu两个算法,以及图像的边缘提取,和骨架提取,同时涉及到奶牛乳腺面积密度的计算等等。

立即下载
真彩色和256色索引图的相互转换

真彩色和256色索引图的相互转换,除去matlab自带函数外还附带kmeans算法

立即下载
Oracle在线建立超大表的索引

Oracle在线建立超大表的索引,为在线生产系统某核心大表建立索引

立即下载

热点文章

img

spring mvc+mybatis+mysql+maven+bootstrap 整合实现增删查改简单实例.zip

资源所需积分/C币 当前拥有积分 当前拥有C币
5 0 0
点击完成任务获取下载码
输入下载码
为了良好体验,不建议使用迅雷下载
img

基于索引表的图像细化程序有详细注解

会员到期时间: 剩余下载个数: 剩余C币: 剩余积分:0
为了良好体验,不建议使用迅雷下载
VIP下载
您今日下载次数已达上限(为了良好下载体验及使用,每位用户24小时之内最多可下载20个资源)

积分不足!

资源所需积分/C币 当前拥有积分
您可以选择
开通VIP
4000万
程序员的必选
600万
绿色安全资源
现在开通
立省522元
或者
购买C币兑换积分 C币抽奖
img

资源所需积分/C币 当前拥有积分 当前拥有C币
5 4 45
为了良好体验,不建议使用迅雷下载
确认下载
img

资源所需积分/C币 当前拥有积分 当前拥有C币
3 0 0
为了良好体验,不建议使用迅雷下载
VIP和C币套餐优惠
img

资源所需积分/C币 当前拥有积分 当前拥有C币
5 4 45
您的积分不足,将扣除 10 C币
为了良好体验,不建议使用迅雷下载
确认下载
下载
您还未下载过该资源
无法举报自己的资源

兑换成功

你当前的下载分为234开始下载资源
你还不是VIP会员
开通VIP会员权限,免积分下载
立即开通

你下载资源过于频繁,请输入验证码

您因违反CSDN下载频道规则而被锁定帐户,如有疑问,请联络:webmaster@csdn.net!

举报

  • 举报人:
  • 被举报人:
  • *类型:
    • *投诉人姓名:
    • *投诉人联系方式:
    • *版权证明:
  • *详细原因: