按照索引的细化提取骨架算法的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();
} } }
按照索引的细化提取骨架算法的java实现的更多相关文章
- 【转】MySQL索引背后的数据结构及算法原理
摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...
- [转]MySQL索引背后的数据结构及算法原理
摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...
- MySQL索引背后的数据结构及算法原理【转】
本文来自:张洋的MySQL索引背后的数据结构及算法原理 摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持 ...
- MySQL索引背后的数据结构及算法原理
摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...
- [纯干货] MySQL索引背后的数据结构及算法原理
摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...
- MySQL 索引背后的数据结构及算法原理
本文转载自http://blog.jobbole.com/24006/ 摘要本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引 ...
- 浅谈MySQL索引背后的数据结构及算法
摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...
- 浅谈MySQL索引背后的数据结构及算法(转载)
转自:http://blogread.cn/it/article/4088?f=wb1 摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储 ...
- MySQL索引背后的数据结构及算法原理 --转
写在前面的话 在编程领域有一句人尽皆知的法则“程序 = 数据结构 + 算法”,我个人是不太赞同这句话(因为我觉得程序不仅仅是数据结构加算法),但是在日常的学习和工作中我确认深深感受到数据结构和算法的重 ...
随机推荐
- css中visiblity和display异同
visiblity 是设置元素的可见性,即可见 / 隐藏:隐藏后元素所占有位置保留: display 是设置元素按什么样的方式来显示,是按块显示,显示成一条线的形式,显示为“消失”等等,当displa ...
- cppcheck
http://sourceforge.net/projects/cppcheck/files/?source=navbar https://github.com/danmar/cppcheck htt ...
- PHP使用SnowFlake算法生成唯一ID
前言:最近需要做一套CMS系统,由于功能比较单一,而且要求灵活,所以放弃了WP这样的成熟系统,自己做一套相对简单一点的.文章的详情页URL想要做成url伪静态的格式即xxx.html 其中xxx考虑过 ...
- [PHP] 读取大文件并显示
使用PHP读取日志文件,当文件比较大的时候,会报内存不足,因此应该部分读取,读取指定的行数的数据 PHP代码: <?php class Test{ //日志路径 const LOG_PATH=& ...
- 205 Isomorphic Strings
Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the chara ...
- Maven多模块项目使用MyBatis Generator
开发环境: JDK:8u102 Maven:3.3.9 MySQL:5.7.10 MySQL Connector:5.1.40 IDE:IntelliJ IDEA 2016 MyBatis:3.4.1 ...
- js注入,黑客之路必备!
最近刚出了新闻,阿里四名网络安全部门员工利用网页漏洞写js脚本抢月饼,于是兴致来了,想了解一下这个js脚本到底怎么写,各种刷单各种抢枪抢又是怎么实现的. 什么是javascript注入攻击? 1.每当 ...
- Orchard MySql 修正版 下载
Orchard是支持多种数据库的如果是个人站长推荐使用MySql作为运行数据库,虽然SqlServer更为强大,但总觉得SqlServer好重啊,一装就是几个G. 最近的版本在使用MySql建库时却会 ...
- 六个创建模式之单例模式(Singleton Pattern)
定义: 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.三个特点:一个类只有一个实例:必需自己创建这个实例:必需自行向整个系统提供这个实例. 结构图: Singleton:单例类,提 ...
- RGui的http代理设置
办公电脑环境需要http代理访问大网,使用R语言安装包时老是无法连接网络,后来从网上发现解决方法很简单,只需在启动RGui.exe的命令行上加上启动参数就可以了. "C:\Program F ...