按照索引的细化提取骨架算法的java实现

近期研究验证码识别,也就看了一些图像识别的资料,其中一种字体细化提取骨架的算法网上没有java版的实现,所以就选取了一个python实现版本进行java代码的改写..

python版实现的地址:

http://www.cnblogs.com/xianglan/archive/2011/01/01/1923779.html

由于我不是很懂python语法,也是直接去的w3c看的教程,为此还掉进了一个坑..详见:

http://www.cnblogs.com/chyu/p/4335950.html

由于我对图像处理这里不是很在行,python也是临时看的,故这种细化提取骨架的算法也就是直接移植原代码,并没做什么优化之类..代码很粗糙..

package com.ocr.imgocr;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class Thin {
    //索引数组
    private static Integer[] array = {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};

    public static boolean isWhite(int colorInt) {
        Color color = new Color(colorInt);
        if (color.getRed() + color.getGreen() + color.getBlue() > 400) {
            return true;
        }
        return false;
    } 

    public static BufferedImage VThin(BufferedImage image,Integer[] array){
        int h = image.getHeight();
        int w = image.getWidth();
        int NEXT = 1;
        for(int i=0;i<h;i++){
            for(int j=0;j<w;j++){
                if (NEXT == 0){
                    NEXT = 1;
                }else{
                    int M ;
                    if( 0<j&&j<w-1){
                        if(isBlack(image.getRGB(j-1,i))&&isBlack(image.getRGB(j,i))&&isBlack(image.getRGB(j+1,i))){
                            M=0;
                        }else{
                            M=1;
                        }
                    }else {
                        M = 1;
                    }
                    if(isBlack(image.getRGB(j,i))&&M!=0){
                        int[] a = {0,0,0,0,0,0,0,0,0};
                        for(int k=0;k<3;k++){
                            for(int l=0;l<3;l++){
                                if ((-1<(i-1+k)&&(i-1+k)<h) && (-1<(j-1+l)&&(j-1+l)<w) && isWhite(image.getRGB(j-1+l,i-1+k))){
                                    a[k*3+l] = 1;
                                }
                            }
                        }
                        int sum = a[0]*1+a[1]*2+a[2]*4+a[3]*8+a[5]*16+a[6]*32+a[7]*64+a[8]*128;
                        if(array[sum]==0){
                            image.setRGB(j, i, Color.black.getRGB());
                        }else{
                            image.setRGB(j, i, Color.white.getRGB());
                        }
                        if (array[sum] == 1){
                            NEXT = 0;
                        }
                    }
                }
            }
        }
        return image;
    }

    public static BufferedImage HThin(BufferedImage image,Integer[] array){
        int h = image.getHeight();
        int w = image.getWidth();
        int NEXT = 1;
        for(int j=0;j<w;j++){
            for(int i=0;i<h;i++){
                if (NEXT == 0){
                    NEXT = 1;
                }else{
                    int M;
                    if(0<i&&i<h-1){
                        if(isBlack(image.getRGB(j,i-1))&&isBlack(image.getRGB(j,i))&&isBlack(image.getRGB(j,i+1))){
                            M=0;
                        }else{
                            M=1;
                        }
                    }else{
                        M = 1;
                    }
                    if (isBlack(image.getRGB(j,i)) && M != 0){
                        int[] a = {0,0,0,0,0,0,0,0,0};
                        for(int k=0;k<3;k++){
                            for(int l=0;l<3;l++){
                                if ((-1<(i-1+k)&&(i-1+k)<h) && (-1<(j-1+l)&&(j-1+l)<w )&& isWhite(image.getRGB(j-1+l,i-1+k))){
                                    a[k*3+l] = 1;
                                }
                            }
                        }
                        int sum = a[0]*1+a[1]*2+a[2]*4+a[3]*8+a[5]*16+a[6]*32+a[7]*64+a[8]*128;
                        if(array[sum]==0){
                            image.setRGB(j, i, Color.black.getRGB());
                        }else{
                            image.setRGB(j, i, Color.white.getRGB());
                        }
                        if (array[sum] == 1){
                            NEXT = 0;
                        }
                    }
                }
            }
        }
        return image;
    }

    public static BufferedImage Xihua(BufferedImage image,Integer[] array){
        int num=10;
        BufferedImage iXihua = image;
        for(int i=0;i<num;i++){
            VThin(iXihua,array);
            HThin(iXihua,array);
        }
        return iXihua;
    }

    public static BufferedImage Two(BufferedImage image){
        int w = image.getWidth();
        int h = image.getHeight();
        BufferedImage iTwo = image;
        for(int i=0;i<h;i++){
            for(int j=0;j<w;j++){
                if(isBlack(image.getRGB(j,i))){
                    iTwo.setRGB(j, i, Color.BLACK.getRGB());
                }else{
                    iTwo.setRGB(j, i, Color.WHITE.getRGB());
                }
            }
        }
        return iTwo;
    }

    public static boolean isBlack(int colorInt) {
        Color color = new Color(colorInt);
        if (color.getRed() + color.getGreen() + color.getBlue() <= 400) {
            return true;
        }
        return false;
    }

    public static void main(String[] args) {
        try {
            //原始图片路径
            BufferedImage image = ImageIO.read(new File("image"+File.separator+"0.jpg"));
            //二值化
            BufferedImage iTwo = Two(image);
            ImageIO.write(iTwo, "jpg", new File("image"+File.separator+"two.jpg"));
            //细化
            BufferedImage iThin = Xihua(image,array);
            ImageIO.write(iThin, "jpg", new File("image"+File.separator+"thin.jpg"));

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}
时间: 2024-10-24 09:19:22

按照索引的细化提取骨架算法的java实现的相关文章

MySQL索引背后的数据结构及算法原理

摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎 对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等.为了避免混乱,本文将只关注于BTree索 引,因为这是平常使用MySQL时主要打交道的索引,至于哈希索引和全文索引本文暂不讨论. 数据结构及算法基础 索引的本质 MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构.提取句子主干

浅谈MySQL索引背后的数据结构及算法

摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持 也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等.为了避免混乱,本文将只关注于BTree索引,因为这是 平常使用MySQL时主要打交道的索引,至于哈希索引和全文索引本文暂不讨论. 文章主要内容分为四个部分. 第一部分主要从数据结构及算法理论层面讨论MySQL数据库索引的数理基础. 第二部分结合MySQL数据库中

[纯干货] MySQL索引背后的数据结构及算法原理

摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等.为了避免混乱,本文将只关注于BTree索引,因为这是平常使用MySQL时主要打交道的索引,至于哈希索引和全文索引本文暂不讨论. 文章主要内容分为三个部分. 第一部分主要从数据结构及算法理论层面讨论MySQL数据库索引的数理基础. 第二部分结合MySQL数据库中My

浅谈MySQL索引背后的数据结构及算法(转载)

转自:http://blogread.cn/it/article/4088?f=wb1 摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等.为了避免混乱,本文将只关注于BTree索引,因为这是平常使用MySQL时主要打交道的索引,至于哈希索引和全文索引本文暂不讨论. 文章主要内容分为三个部分. 第一部分主要从数据结

MySQL索引背后的数据结构及算法原理(转)

原文:http://blog.codinglabs.org/articles/theory-of-mysql-index.html 目录 摘要 数据结构及算法基础 索引的本质 B-Tree和B+Tree 为什么实用B-Tree(B+Tree) MySQL索引实现 MyISAM索引实现 InnoDB索引实现 索引使用策略及优化 示例数据库 最左前缀原理与相关优化 索引选择性与前缀索引 InnoDB的主键选择与插入优化 后记 参考文献 摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一

MySQL索引背后的数据结构及算法原理 --转

写在前面的话 在编程领域有一句人尽皆知的法则“程序 = 数据结构 + 算法”,我个人是不太赞同这句话(因为我觉得程序不仅仅是数据结构加算法),但是在日常的学习和工作中我确认深深感受到数据结构和算法的重要性,很多东西,如果你愿意稍稍往深处挖一点,那么扑面而来的一定是各种数据结构和算法知识.例如几乎每个程序员都要打交道的数据库,如果仅仅是用来存个数据.建建表.建建索引.做做增删改查,那么也许觉得数据结构和这东西没什么关系.不过要是哪天心血来潮,想知道的多一点,想研究一下如何优化数据库,那么一定避免不

【转】MySQL索引背后的数据结构及算法原理

转自 :http://blog.jobbole.com/24006/ 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等.为了避免混乱,本文将只关注于BTree索引,因为这是平常使用MySQL时主要打交道的索引,至于哈希索引和全文索引本文暂不讨论. 文章主要内容分为三个部分. 第一部分主要从数据结构及算法理论层面讨论My

MySQL索引背后的数据结构及算法原理(上)

本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等.为了避免混乱,本文将只关注于BTree索引,因为这是平常使用MySQL时主要打交道的索引,至于哈希索引和全文索引本文暂不讨论. 文章主要内容分为三个部分. 第一部分主要从数据结构及算法理论层面讨论MySQL数据库索引的数理基础. 第二部分结合`MySQL数据库中MyIS

MySQL索引背后的数据结构及算法原理 【转】

摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等.为了避免混乱,本文将只关注于BTree索引,因为这是平常使用MySQL时主要打交道的索引,至于哈希索引和全文索引本文暂不讨论. 文章主要内容分为三个部分. 第一部分主要从数据结构及算法理论层面讨论MySQL数据库索引的数理基础. 第二部分结合MySQL数据库中My