Java基于opencv实现图像数字识别(五)—投影法分割字符

Java基于opencv实现图像数字识别(五)—投影法分割字符

水平投影法

1、水平投影法就是先用一个数组统计出图像每行黑色像素点的个数(二值化的图像);

2、选出一个最优的阀值,根据比这个阀值大或小,用一个数组记录相应Y轴的坐标;

3、因为是水平切割我们只需要Y轴的切割点即可,宽度默认图像的宽,高度可以用相邻的切割点相减得到;

4、优化切割点,把切割点靠近的都清除掉

5、设置感应区的区域,切割图片

垂直投影法和水平投影法类似,对比思考一下

因为我做的是表格的切割,你如果想实现验证码的切割,或者其他的类比这个,我想也是很容易实现的

我们先看一下,效果,还是很不错的


投影法分割字符

水平切割代码

// 图像切割,水平投影法切割
public List<Mat> cutImgX() {
    int i, j;
    int nWidth = getWidth(), nHeight = getHeight();
    int[] xNum = new int[nHeight], cNum;
    int average = 0;// 记录像素的平均值
    // 统计出每行黑色像素点的个数
    for (i = 0; i < nHeight; i++) {
        for (j = 0; j < nWidth; j++) {
            if (getPixel(i, j) == BLACK) {
                xNum[i]++;
            }

        }
    }

    // 经过测试这样得到的平均值最优
    cNum = Arrays.copyOf(xNum, xNum.length);
    Arrays.sort(cNum);
    for (i = 31 * nHeight / 32; i < nHeight; i++) {
        average += cNum[i];
    }
    average /= (nHeight / 32);

    // 把需要切割的y点都存到cutY中
    List<Integer> cutY = new ArrayList<Integer>();
    for (i = 0; i < nHeight; i++) {
        if (xNum[i] > average) {
            cutY.add(i);
        }
    }

    // 优化cutY把
    if (cutY.size() != 0) {

        int temp = cutY.get(cutY.size() - 1);
        // 因为线条有粗细,优化cutY
        for (i = cutY.size() - 2; i >= 0; i--) {
            int k = temp - cutY.get(i);
            if (k <= 8) {
                cutY.remove(i);
            } else {
                temp = cutY.get(i);

            }

        }
    }

    // 把切割的图片都保存到YMat中
    List<Mat> YMat = new ArrayList<Mat>();
    for (i = 1; i < cutY.size(); i++) {
        // 设置感兴趣的区域
        int startY = cutY.get(i - 1);
        int height = cutY.get(i) - startY;
        Mat temp = new Mat(mat, new Rect(0, startY, nWidth, height));
        Mat t = new Mat();
        temp.copyTo(t);
        YMat.add(t);
    }

    return YMat;
}

垂直投影法

// 图像切割,垂直投影法切割
public List<Mat> cutImgY() {

    int i, j;
    int nWidth = getWidth(), nHeight = getHeight();
    int[] xNum = new int[nWidth], cNum;
    int average = 0;// 记录像素的平均值
    // 统计出每列黑色像素点的个数
    for (i = 0; i < nWidth; i++) {
        for (j = 0; j < nHeight; j++) {
            if (getPixel(j, i) == BLACK) {
                xNum[i]++;
            }

        }
    }

    // 经过测试这样得到的平均值最优 , 平均值的选取很重要
    cNum = Arrays.copyOf(xNum, xNum.length);
    Arrays.sort(cNum);
    for (i = 31 * nWidth / 32; i < nWidth; i++) {
        average += cNum[i];
    }
    average /= (nWidth / 28);

    // 把需要切割的x点都存到cutY中,
    List<Integer> cutX = new ArrayList<Integer>();
    for (i = 0; i < nWidth; i += 2) {
        if (xNum[i] >= average) {
            cutX.add(i);
        }
    }

    if (cutX.size() != 0) {

        int temp = cutX.get(cutX.size() - 1);
        // 因为线条有粗细,优化cutY
        for (i = cutX.size() - 2; i >= 0; i--) {
            int k = temp - cutX.get(i);
            if (k <= 10) {
                cutX.remove(i);
            } else {
                temp = cutX.get(i);

            }

        }
    }

    // 把切割的图片都保存到YMat中
    List<Mat> XMat = new ArrayList<Mat>();
    for (i = 1; i < cutX.size(); i++) {
        // 设置感兴趣的区域
        int startX = cutX.get(i - 1);
        int width = cutX.get(i) - startX;
        Mat temp = new Mat(mat, new Rect(startX, 0, width, nHeight));
        Mat t = new Mat();
        temp.copyTo(t);
        XMat.add(t);
    }

    return XMat;
}

注:本文章参考了很多博客,感谢;主要是跟着一个博客来实现的https://blog.csdn.net/ysc6688/article/category/2913009(也是基于opencv来做的)感谢

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容