zoukankan      html  css  js  c++  java
  • 基于Mat变换的骨架提取Java

    针对一副二值图像,区域内的点只有背景点(白点,0值)和前景点(黑点,1值)。对于给定区域的像素点逐次应用两个基本步骤,以提取骨架:

    step1,如果一个像素点满足下列4个条件,那么将它标记为要删除的点:

    (1)2<=N(p1)<=6,其中N(p1)=p2+p3+p4+...+p8+p9;

    (2)T(p1)=1,其中T(p1)是以p2,p3,...,p8,p9,p2的次序旋转,从0到1的变换次数;

    (3)p2*p4*p6=0;

    (4)p4*p6*p8=0.

    step2,条件(1)(2)不变,但是条件(3)(4)变为:

    (3)p2*p4*p8=0;

    (4)p2*p6*p8=0.

    这里,每个像素点的八邻域结构为

    p9 p2 p3
    p8 p1 p4
    p7 p6 p5

    基于Mat变换的骨架提取的完整步骤:

    (1)执行step1,对需要删除的边界点进行标记;

    (2)删除标记点;

    (3)执行step2,对需要删除的边界点进行标记;

    (4)删除标记点;

    (1)到(4)属于一个循环过程,不断反复进行这一循环过程,检测是否存在符合条件的删除点,直到再也找不到可删除的点的时候,说明此时骨架已经生成,结束循环。

      1 package com.example.lenovo.linehough;
      2 
      3 import android.graphics.Color;
      4 
      5 public class Mat {
      6 
      7     public static int[] matswitch(int w, int h, int[] inputs) {
      8         int[] imgBuf = new int[w * h];
      9         int[] neighbor = new int[10];
     10         int[] mark = new int[w * h];
     11         int markNum1;
     12         int markNum2;
     13         boolean s = true;
     14         for(int index=0;index<w*h;index++)
     15             imgBuf[index] = inputs[index];
     16         while (s) {
     17             //第一步,统一黑点值为1,白点值为0
     18             markNum1 = 0;//步骤1中标记被删除的边界点的个数
     19             for (int x = 1; x < w - 1; x++) {
     20                 for (int y = 1; y < h - 1; y++) {
     21                     //条件1:p必须是边界点,值为1, 8邻域内至少有1个像素点值为0
     22                     if (imgBuf[y * w + x] == Color.WHITE) continue;
     23                     int[] detectBlack = new int[10];
     24                     neighbor[2] = ((imgBuf[(y - 1) * w + x] & 0x00ff0000) >> 16) / 255;//黑点neighbor为0,白点neighbor为1
     25                     neighbor[3] = ((imgBuf[(y - 1) * w + x + 1] & 0x00ff0000) >> 16) / 255;
     26                     neighbor[4] = ((imgBuf[y * w + x + 1] & 0x00ff0000) >> 16) / 255;
     27                     neighbor[5] = ((imgBuf[(y + 1) * w + x + 1] & 0x00ff0000) >> 16) / 255;
     28                     neighbor[6] = ((imgBuf[(y + 1) * w + x] & 0x00ff0000) >> 16) / 255;
     29                     neighbor[7] = ((imgBuf[(y + 1) * w + x - 1] & 0x00ff0000) >> 16) / 255;
     30                     neighbor[8] = ((imgBuf[(y) * w + x - 1] & 0x00ff0000) >> 16) / 255;
     31                     neighbor[9] = ((imgBuf[(y - 1) * w + x - 1] & 0x00ff0000) >> 16) / 255;
     32                     for (int i = 2; i <= 9; i++) {
     33                         if (neighbor[i] == 0)
     34                             detectBlack[i]++;//(黑点)neighbor为0,detectBlack就为1;(白点)neighbor为1,detectBlack就为0
     35                     }
     36                     //8领域的点都是黑点,证明该点不是边界点,退出该轮循环,检测下一个点
     37                     if (detectBlack[2] * detectBlack[3] * detectBlack[4] * detectBlack[5]
     38                             * detectBlack[6] * detectBlack[7] * detectBlack[8] * detectBlack[9] != 0)
     39                         continue;
     40 
     41                     //条件2:2<=N(p)<=6
     42                     int np = (detectBlack[2] + detectBlack[3] + detectBlack[4] + detectBlack[5]
     43                             + detectBlack[6] + detectBlack[7] + detectBlack[8] + detectBlack[9]);
     44                     if (np < 2 || np > 6) continue;
     45 
     46                     //条件3:T(p)=1
     47                     int tp = 0;
     48                     for (int i = 3; i <= 9; i++) {
     49                        /* if(neighbor[i]-neighbor[i-1]==Color.WHITE-Color.BLACK )*/
     50                         if (detectBlack[i] - detectBlack[i - 1] == 1)
     51                             tp++;
     52                     }
     53                     if (detectBlack[2] - detectBlack[9] == 1)
     54                         tp++;
     55                     if (tp != 1) continue;
     56 
     57                     //条件4:p2*p4*p6=0
     58                     if (detectBlack[2] * detectBlack[4] * detectBlack[6] != 0)
     59                         continue;
     60                     //条件5:p4*p6*p8=0
     61                     if (detectBlack[4] * detectBlack[6] * detectBlack[8] != 0)
     62                         continue;
     63 
     64                     //标记要被删除的点
     65                     mark[y * w + x] = 1;
     66                     markNum1++;
     67                 }
     68             }
     69 
     70             //将标记删除的点置为背景色
     71             if (markNum1 > 0) {
     72                 for (int x = 1; x < w - 1; x++) {
     73                     for (int y = 1; y < h - 1; y++) {
     74                         //删除被标记的点,即置为背景色黑色
     75                         if (mark[y * w + x] == 1) {
     76                             imgBuf[y * w + x] = Color.WHITE;
     77                         }
     78                     }
     79                 }
     80             }
     81 
     82 
     83             //第二步
     84             markNum2 = 0;//步骤2中标记被删除的点的个数
     85             for (int x = 1; x < w - 1; x++) {
     86                 for (int y = 1; y < h - 1; y++) {
     87                     //条件1:p必须是前景点BLACK
     88                     if (imgBuf[y * w + x] == Color.WHITE) continue;
     89                     int[] detectBlack = new int[10];
     90                     neighbor[2] = ((imgBuf[(y - 1) * w + x] & 0x00ff0000) >> 16) / 255;
     91                     neighbor[3] = ((imgBuf[(y - 1) * w + x + 1] & 0x00ff0000) >> 16) / 255;
     92                     neighbor[4] = ((imgBuf[y * w + x + 1] & 0x00ff0000) >> 16) / 255;
     93                     neighbor[5] = ((imgBuf[(y + 1) * w + x + 1] & 0x00ff0000) >> 16) / 255;
     94                     neighbor[6] = ((imgBuf[(y + 1) * w + x] & 0x00ff0000) >> 16) / 255;
     95                     neighbor[7] = ((imgBuf[(y + 1) * w + x - 1] & 0x00ff0000) >> 16) / 255;
     96                     neighbor[8] = ((imgBuf[(y) * w + x - 1] & 0x00ff0000) >> 16) / 255;
     97                     neighbor[9] = ((imgBuf[(y - 1) * w + x - 1] & 0x00ff0000) >> 16) / 255;
     98                     for (int i = 2; i < 10; i++) {
     99                         if (neighbor[i] == 0) detectBlack[i]++;
    100                     }
    101 
    102                     if (detectBlack[2] * detectBlack[3] * detectBlack[4] * detectBlack[5]
    103                             * detectBlack[6] * detectBlack[7] * detectBlack[8] * detectBlack[9] != 0)
    104                         continue;
    105 
    106                     //条件2:2<=N(p)<=6
    107                     int np = (detectBlack[2] + detectBlack[3] + detectBlack[4] + detectBlack[5]
    108                             + detectBlack[6] + detectBlack[7] + detectBlack[8] + detectBlack[9]);
    109                     if (np < 2 || np > 6) continue;
    110 
    111                     //条件3:T(p)=1
    112                     int tp = 0;
    113                     for (int i = 3; i <= 9; i++) {
    114                        /* if(neighbor[i]-neighbor[i-1]==Color.WHITE-Color.BLACK )*/
    115                         if (detectBlack[i] - detectBlack[i - 1] == 1)
    116                             tp++;
    117                     }
    118                     if (detectBlack[2] - detectBlack[9] == 1)
    119                         tp++;
    120                     if (tp != 1) continue;
    121 
    122                     //条件4:p2*p4*p8==0
    123                     if (detectBlack[2] * detectBlack[4] * detectBlack[8] != 0)
    124                         continue;
    125                     //条件5:p2*p6*p8==0
    126                     if (detectBlack[2] * detectBlack[6] * detectBlack[8] != 0)
    127                         continue;
    128 
    129                     //标记删除
    130                     mark[y * w + x] = 1;
    131                     markNum2++;
    132                 }
    133             }
    134 
    135             //将标记删除的点置为背景色WHITE
    136             if (markNum2 > 0) {
    137                 for (int x = 1; x < w - 1; x++) {
    138                     for (int y = 1; y < h - 1; y++) {
    139                         if (mark[y * w + x] == 1) {
    140                             imgBuf[y * w + x] = Color.WHITE;
    141                         }
    142                     }
    143                 }
    144             }
    145             //先步骤1再步骤2,一次周期循环后,不再出现标记删除的点时,说明已生成骨架了
    146             if (markNum1 == 0 && markNum2 == 0) s = false;
    147             else s = true;
    148         }
    149         return imgBuf;
    150     }
    151 
    152 
    153 }
  • 相关阅读:
    JS系列:三元运算符与循环
    浏览器解析js和type判断数据类型
    JS系列:数据类型详细讲解
    JS系列:编程语言
    京东校招面试汇总
    有关axios的request与response拦截
    正则表达式 判断内容是否为合法的url
    H5 小代码(实时更新)
    H5 回到顶部按钮
    图片压缩(js压缩,底部有vue压缩图片依赖使用的教程链接)
  • 原文地址:https://www.cnblogs.com/gxclmx/p/7498427.html
Copyright © 2011-2022 走看看