博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《图像处理实例》 之 中轴线提取
阅读量:6597 次
发布时间:2019-06-24

本文共 6563 字,大约阅读时间需要 21 分钟。

 

 


 

中轴线算法

这是的作者原创,我只是对其理解之后改进和说明,欢迎大家使用这个小软件!

如果有需要C++版本的朋友,可以博文结尾留邮箱!

 


 

首先上效果图:

 

 

算法的流程:

    

      第一步:

          距离变换

      第二步:

          把距离变换的图像进行像素值的排列(排列返回像素的位置信息)

      第二步:

          从小到大进行像素的查表操作

 

      注释:这里为什么叫中轴线提取?因为提取的过程是绝对的按照对称来的,距离变换的结果就是前景到背景的距离,所以结果是绝对的集合中心。

 

 

 

 

Python代码:

 

1 import numpy as np 2 from skimage.data import horse, camera 3 import matplotlib.pyplot as plt 4 import scipy.ndimage as ndimg 5 from numba import jit 6 import cv2 7 from scipy.ndimage import label, generate_binary_structure 8  9 strc = np.ones((3, 3), dtype=np.bool)10 11 12 # check whether this pixcel can be removed13 def check(n):14     a = [(n >> i) & 1 for i in range(8)]15     a.insert(4, 0)  # make the 3x3 unit16     # if up, down, left, right all are 1, you cannot make a hole17     # if a[1] & a[3] & a[5] & a[7]:return False18     a = np.array(a).reshape((3, 3))19     # segments20     n = label(a, strc)[1]21     # if sum is 0, it is a isolate point, you cannot remove it.22     # if number of segments > 2, you cannot split them.23     return n < 224     return a.sum() > 1 and n < 225     if a.sum() == 1 or n > 2: return 226     if a.sum() > 1 and n < 2: return 127     return 028 29 30 lut = np.array([check(n) for n in range(256)])31 lut = np.dot(lut.reshape((-1, 8)), [1, 2, 4, 8, 16, 32, 64, 128]).astype(np.uint8)32 '''33 lut = np.array([200, 206, 220, 204, 0, 207, 0, 204, 0, 207, 221, 51, 1, 207, 221, 51,34        0, 0, 221, 204, 0, 0, 0, 204, 1, 207, 221, 51, 1, 207, 221, 51], dtype=np.int8)35 '''36 37 38 @jit39 def skel2dp(data, idx, lup):40     h, w = data.shape41     data = data.ravel()     42     for id in idx:          43 44         if data[id] == 0: continue  45         i2 = id - w46         i8 = id + w47         i1 = i2 - 148         i3 = i2 + 149         i4 = id - 150         i6 = id + 151         i7 = i8 - 152         i9 = i8 + 153         c = (data[i1] > 0) << 0 | (data[i2] > 0) << 1 \54             | (data[i3] > 0) << 2 | (data[i4] > 0) << 3 \55             | (data[i6] > 0) << 4 | (data[i7] > 0) << 5 \56             | (data[i8] > 0) << 6 | (data[i9] > 0) << 757         if (lup[c // 8] >> c % 8) & 1: data[id] = 058     return 059 60 61 def mid_axis(img):62     dis = ndimg.distance_transform_edt(img)63     idx = np.argsort(dis.flat).astype(np.int32)     64     skel2dp(dis, idx, lut)65     return dis66 67 68 from time import time69 img = ~horse()*25570 #img = cv2.imread('123.jpg')71 #img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)72 #ret2, img = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)73 dis = ndimg.distance_transform_edt(img)74 plt.imshow(dis)75 idx = np.argsort(dis.flat).astype(np.int32)76 a = skel2dp(dis, idx, lut)77 #mid_axis(img.copy())78 t1 = time()79 a = mid_axis(img)80 t2 = time()81 print(t2 - t1)82 plt.imshow(a)83 plt.show()

 

 

 

C++代码:

  

1 void center_axis(InputArray _src, Mat&  dst) 2 { 3     typedef struct MyStruct 4     { 5         Point position; 6         float num; 7     }MyStruct; 8     int wjy_array[] = { 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 9         1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1,10         0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1,11         1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1,12         1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,13         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,14         1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1,15         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,16         0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1,17         1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1,18         0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1,19         1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,20         1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,21         1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,22         1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0,23         1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0 };24     uchar lut[] = { 200, 206, 220, 204, 0, 207, 0, 204, 0, 207, 221, 51, 1, 207, 221, 51,25         0, 0, 221, 204, 0, 0, 0, 204, 1, 207, 221, 51, 1, 207, 221, 51 };26     Mat src = _src.getMat();27     //Mat dst = _dst.getMat();28     distanceTransform(src, src, DIST_L2, DIST_MASK_3, 5);29     normalize(src, src, 0, 255, NORM_MINMAX);30     Mat img_row = src.reshape(0, 1);31     vector
my_vector;32 for (size_t j = 0; j < img_row.cols; j++)33 {34 if (img_row.at
(0, j) == 0) continue;35 MyStruct my_struct;36 my_struct.num = saturate_cast
(img_row.at
(0, j));37 my_struct.position = Point(saturate_cast
(j % src.cols), saturate_cast
(j / src.cols));38 my_vector.push_back(my_struct);39 }40 for (size_t i = 0; i < my_vector.size(); i++)41 {42 if (my_vector[i].num == 0) continue;43 for (size_t j = i; j < my_vector.size(); j++)44 {45 MyStruct temp;46 if (my_vector[i].num >= my_vector[j].num)47 {48 if (my_vector[j].num == 0) continue;49 temp = my_vector[j];50 my_vector[j] = my_vector[i];51 my_vector[i] = temp;52 }53 }54 }55 for (size_t i = 0; i < my_vector.size(); i++)56 {57 if (my_vector[i].position.y == 158 || my_vector[i].position.x == 159 || my_vector[i].position.y == src.rows - 160 || my_vector[i].position.x == src.cols - 161 || src.at
(my_vector[i].position.y, my_vector[i].position.x) == 0) continue;62 else63 {64 char num[] = { 1,1,1,1,1,1,1,1 };65 num[0] = src.at
(my_vector[i].position.y - 1, my_vector[i].position.x - 1)66 > 0 ? 1 : 0;67 num[1] = src.at
(my_vector[i].position.y - 1, my_vector[i].position.x)68 > 0 ? 1 : 0;69 num[2] = src.at
(my_vector[i].position.y - 1, my_vector[i].position.x + 1)70 > 0 ? 1 : 0;71 num[3] = src.at
(my_vector[i].position.y, my_vector[i].position.x - 1)72 > 0 ? 1 : 0;73 num[4] = src.at
(my_vector[i].position.y, my_vector[i].position.x + 1)74 > 0 ? 1 : 0;75 num[5] = src.at
(my_vector[i].position.y + 1, my_vector[i].position.x - 1)76 > 0 ? 1 : 0;77 num[6] = src.at
(my_vector[i].position.y + 1, my_vector[i].position.x)78 > 0 ? 1 : 0;79 num[7] = src.at
(my_vector[i].position.y + 1, my_vector[i].position.x + 1)80 > 0 ? 1 : 0;81 int sum = num[0] + num[1] * 2 + num[2] * 4 + num[3] * 882 + num[4] * 16 + num[5] * 32 + num[6] * 64 + num[7] * 128;83 src.at
(my_vector[i].position.y, my_vector[i].position.x) = ((lut[uchar(sum / 8)] >> sum % 8) & 1) != 1 ? 255 : 0;84 }85 }86 dst = src.clone();87 dst.convertTo(dst, CV_8UC1);88 }

 

转载于:https://www.cnblogs.com/wjy-lulu/p/7402286.html

你可能感兴趣的文章
点击edittext并显示其内容
查看>>
[Effective Java]第十一章 序列化
查看>>
[算法导论]红黑树实现(插入和删除) @ Python
查看>>
iPhone开发 数据持久化总结(终结篇)—5种数据持久化方法对比
查看>>
使用ReaderWriterLock类实现多用户读/单用户写同步
查看>>
中国式危机公关9加1策略(第十四章 国外危机应对案例參考)
查看>>
CKEditor上传插件
查看>>
Java 缩放图片工具类,创建缩略图、伸缩图片比例
查看>>
Rebuild Instance 操作详解 - 每天5分钟玩转 OpenStack(37)
查看>>
利用scp传输文件小结
查看>>
面向对象设计模式纵横谈:Factory Method 工厂方法模式(笔记记录)
查看>>
C++使用hiredis连接带密码的redis服务
查看>>
SQL SERVER 批量生成编号
查看>>
thinkjs——一个字段一种数字代表两种状态
查看>>
C++的那些事:类的拷贝控制
查看>>
numpy得到数组的index
查看>>
JSP页面重定向
查看>>
RecyclerView具体解释
查看>>
vue2.0 vue-loader
查看>>
美国埃博拉患者是怎样治愈的?
查看>>