python查表法提取骨骼线经历

       首先根据这篇博文https://www.cnblogs.com/xianglan/archive/2011/01/01/1923779.html,自己重新编写python代码,由于出现局部错误,导致出现了一些奇妙结果,因此写就过程如下:

结果一:

# -*- coding: utf-8 -*-
"""
Created on Mon Jun 10 14:35:27 2019

@author: 高行吟
"""
import numpy as np

def Get_skeleton_line(img):
    table = [0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,\
             1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,\
             0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,\
             1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,\
             1,1,0,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,\
             1,1,0,0,1,1,0,0,1,1,0,1,1,1,0,1,\
             0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
             0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,\
             1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,\
             0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,\
             1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,\
             1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,\
             1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,\
             1,1,0,0,1,1,0,0,1,1,0,1,1,1,0,0,\
             1,1,0,0,1,1,1,0,1,1,0,0,1,0,0,0]
    r , c = img.shape
    line_img = np.zeros((r , c))
    new_img = np.zeros((r + 2 , c + 2))##由于本程序以窗口遍历,因此原矩阵四个方向均增加一个全零边,方便计算
    new_img[1:-1 , 1:-1] = img
    new_img = np.where(new_img == 1 , 0 , 1)###由于目标区域值为1,而查表法规定,一旦像素为目标,则其权重为0,因此将矩阵所有值全部反向,即是0→1,1→0,方便与权重模板temp做乘法计算
    temp = np.array([[1 , 2 , 4] , [8 , 0 , 16] , [32 , 64 , 128]])###权重矩阵
    for i in range(1 , r+1):
        for j in range(1 , c+1):
            line_img[i-1 , j-1] = table[(new_img[i-1:i+2 , j-1:j+2]*temp).sum()]###窗口矩阵与模板相乘,其和即为表索引
    return line_img

上述代码处理一副图前后如下:

   

                         原图                                                                   二值图                                                  处理后

       可以看到,本来使用查表法是提取骨骼线的,结果却得到了边界线,结果似乎还很好?也可能本人孤陋寡闻,大方勿笑,反正感觉很奇妙,因此记录下来,以便以后提取边界线时查看。

       按照本人理解,应该是倒数第二行代码问题,该行代码将查表后计算的值赋予到一个新的矩阵,并没有对后续查表计算产生影影响,这是不合理的,当中心点完全处于二值图内部时(即是3×3矩阵完全在目标区域内),计算得到的表索引将为0,查表得到的值同样为0,最终在与二值图目标区域内部的相同位置上,新矩阵的值同样为0,因此导致上述情况。

结果二:

       按上述理解改正代码后如下:

# -*- coding: utf-8 -*-
"""
Created on Mon Jun 10 14:35:27 2019

@author: 高行吟
"""
import numpy as np

def Get_skeleton_line(img):
    table = [0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,\
             1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,\
             0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,\
             1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,\
             1,1,0,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,\
             1,1,0,0,1,1,0,0,1,1,0,1,1,1,0,1,\
             0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
             0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,\
             1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,\
             0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,\
             1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,\
             1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,\
             1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,\
             1,1,0,0,1,1,0,0,1,1,0,1,1,1,0,0,\
             1,1,0,0,1,1,1,0,1,1,0,0,1,0,0,0]
    r , c = img.shape
#    line_img = np.zeros((r , c))
    new_img = np.zeros((r + 2 , c + 2))##由于本程序以窗口遍历,因此原矩阵四个方向均增加一个全零边,方便计算
    new_img[1:-1 , 1:-1] = img
    new_img = np.where(new_img == 1 , 0 , 1)###由于目标区域值为1,而查表法规定,一旦像素为目标,则其权重为0,因此将矩阵所有值全部反向,即是0→1,1→0,方便与权重模板temp做乘法计算
    temp = np.array([[1 , 2 , 4] , [8 , 0 , 16] , [32 , 64 , 128]])###权重矩阵
    for i in range(1 , r+1):
        for j in range(1 , c+1):
#            line_img[i-1 , j-1] = table[(new_img[i-1:i+2 , j-1:j+2]*temp).sum()]######窗口矩阵与模板相乘,其和即为表索引
            new_img[i , j] = table[(new_img[i-1:i+2 , j-1:j+2]*temp).sum()]
    
    return new_img[1:-1 , 1:-1]#line_img

       但结果仍然未达到目的,提取的仍然不是骨骼线,但生成的图案却,,,怎么说呢,反正是很特殊,是自己平时想要获取类似的图案都无法着手的那种,而且总感觉这种图案会有些用处,但目前还想不到可以用在什么地方。。。

        结果图如下,还是上面那副素材:

 

   

                           原图                                                                   二值图                                                  处理后

         经过与原博客代码对照,发现问题应出现在处理范围上,原博客仅针对目标像素处理,而上述一改之后的代码确是从第一个像素即开始处理,当中心像素窗口完全不在目标区域,其计算的所索引值将达到最大,从table表中可以看出,最终结果为0,与上面处理后图像的结果相符。

结果三:

按照上述理解,进行第二次修改,相对于第一修改后代码,仅增加了倒数第三行代码:

# -*- coding: utf-8 -*-
"""
Created on Mon Jun 10 14:35:27 2019

@author: 高行吟
"""
import numpy as np

def Get_skeleton_line(img):
    table = [0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,\
             1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,\
             0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,\
             1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,\
             1,1,0,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,\
             1,1,0,0,1,1,0,0,1,1,0,1,1,1,0,1,\
             0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
             0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,\
             1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,\
             0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,\
             1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,\
             1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,\
             1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,\
             1,1,0,0,1,1,0,0,1,1,0,1,1,1,0,0,\
             1,1,0,0,1,1,1,0,1,1,0,0,1,0,0,0]
    r , c = img.shape
#    line_img = np.zeros((r , c))
    new_img = np.zeros((r + 2 , c + 2))##由于本程序以窗口遍历,因此原矩阵四个方向均增加一个全零边,方便计算
    new_img[1:-1 , 1:-1] = img
    new_img = np.where(new_img == 1 , 0 , 1)###由于目标区域值为1,而查表法规定,一旦像素为目标,则其权重为0,因此将矩阵所有值全部反向,即是0→1,1→0,方便与权重模板temp做乘法计算
    temp = np.array([[1 , 2 , 4] , [8 , 0 , 16] , [32 , 64 , 128]])###权重矩阵
    for i in range(1 , r+1):
        for j in range(1 , c+1):
            if new_img[i , j] == 0:####判断中心像素是否为目标像素,由于前面进行了像素值反转,因此,此处0值代表目标像素
#           line_img[i-1 , j-1] = table[(new_img[i-1:i+2 , j-1:j+2]*temp).sum()]######窗口矩阵与模板相乘,其和即为表索引
                new_img[i , j] = table[(new_img[i-1:i+2 , j-1:j+2]*temp).sum()]
    
    return new_img[1:-1 , 1:-1]#line_img

按上述二改后代码运行结果正确,结果为单像素组成的连通边,如下:

                               原图                                                         二值图                                                    处理后

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值