Java Opencv 实现细化 二值化

Wesley13
• 阅读 1166

1. 用OpenCV验证腐蚀和膨胀,只需截图回复。具体做法可参考何东健课件和源代码的第6章或其他资源。

2. 用OpenCV验证细化,只需截图回复。具体做法可参考何东健课件和源代码的第6章或其他资源。

3. 其他方法,可先了解基本原理,数学推导知道即可。

算法理论文章: https://blog.csdn.net/baidu_21578557/article/details/51871134 

用OpenCV验证腐蚀和膨胀

public class threshold {

    private final static String path = System.getProperty("user.dir") + "\\catton.jpg";

    static {
        platformUtils.loadLibraries();
    }


    public static void main(String[] args) {

        Mat src= Imgcodecs.imread(path);

        Mat dest=new Mat();

        Imgproc.threshold(src,dest,100,500,Imgproc.THRESH_BINARY);

        //获取数据
        byte [] data=new byte[dest.rows()*dest.cols()*(int)dest.elemSize()];
        dest.get(0,0,data);

        //转为二值化image buffer作为存储对象 可以存储二进制 也可以存储灰度化图像
        BufferedImage bufferedImage=new BufferedImage(dest.cols(),dest.rows(),BufferedImage.TYPE_BYTE_GRAY);

        bufferedImage.getRaster().setDataElements(0,0,dest.cols(),dest.rows(),data);

        JFrame frame=new JFrame();
        frame.getContentPane().add(new JLabel(new ImageIcon(bufferedImage)));
        frame.pack();
        frame.setVisible(true);


        HighGui.imshow(" threshold image",dest);
        HighGui.waitKey(0);
    }
}

Java Opencv 实现细化 二值化

用OpenCV验证细化

//提取图像的骨架
void ImgThin(cv::Mat src,int maxIterations=-1)
{
    if (src.empty()) return;//图像为空,直接返回
    cv::threshold(src, src, m_dThreshold, 1, CV_THRESH_BINARY);//转为0或1的图像

    int ImgHeight = src.rows;
    int ImgWidth = src.cols;

    int count = 0;  //记录迭代次数
    while (true)
    {
        count++;
        if (maxIterations != -1 && count > maxIterations) //限制次数并且迭代次数到达
            break;

        vector<pair<int, int> > mFlag; //用于标记需要删除的点
        //对点标记
        for (int i = 0; i < ImgHeight; ++i)
        {
            for (int j = 0; j < ImgWidth; ++j)
            {
                //如果满足四个条件,进行标记
                //  p9 p2 p3
                //  p8 p1 p4
                //  p7 p6 p5
                int p1 = src.at<uchar>(i, j);
                int p2 = (i == 0) ? 0 : src.at<uchar>(i - 1, j);
                int p3 = (i == 0 || j == ImgWidth - 1) ? 0 : src.at<uchar>(i - 1, j + 1);
                int p4 = (j == ImgWidth - 1) ? 0 : src.at<uchar>(i, j + 1);
                int p5 = (i == ImgHeight - 1 || j == ImgWidth - 1) ? 0 : src.at<uchar>(i + 1, j + 1);
                int p6 = (i == ImgHeight - 1) ? 0 : src.at<uchar>(i + 1, j);
                int p7 = (i == ImgHeight - 1 || j == 0) ? 0 : src.at<uchar>(i + 1, j - 1);
                int p8 = (j == 0) ? 0 : src.at<uchar>(i, j - 1);
                int p9 = (i == 0 || j == 0) ? 0 : src.at<uchar>(i - 1, j - 1);

                if ((p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) >= 2 && (p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) <= 6)
                {
                    int ap = 0;
                    if (p2 == 0 && p3 == 1) ++ap;
                    if (p3 == 0 && p4 == 1) ++ap;
                    if (p4 == 0 && p5 == 1) ++ap;
                    if (p5 == 0 && p6 == 1) ++ap;
                    if (p6 == 0 && p7 == 1) ++ap;
                    if (p7 == 0 && p8 == 1) ++ap;
                    if (p8 == 0 && p9 == 1) ++ap;
                    if (p9 == 0 && p2 == 1) ++ap;

                    if (ap == 1)
                    {
                        if (p2*p4*p6 == 0)
                        {
                            if (p4*p6*p8 == 0)
                            {
                                //标记
                                mFlag.push_back(make_pair(i, j));
                            }
                        }
                    }
                }
            }
        }

        //将标记的点删除
        for (vector<pair<int, int> >::iterator i = mFlag.begin(); i != mFlag.end(); ++i)
        {
            src.at<uchar>(i->first, i->second) = 0;
        }

        //直到没有点满足,算法结束
        if (mFlag.size() == 0) break;
        else mFlag.clear();//将mFlag清空

        //对点标记
        for (int i = 0; i < ImgHeight; ++i)
        {
            for (int j = 0; j < ImgWidth; ++j)
            {
                //如果满足四个条件,进行标记
                //  p9 p2 p3
                //  p8 p1 p4
                //  p7 p6 p5
                int p1 = src.at<uchar>(i, j);
                if (p1 != 1) continue;
                int p2 = (i == 0) ? 0 : src.at<uchar>(i - 1, j);
                int p3 = (i == 0 || j == ImgWidth - 1) ? 0 : src.at<uchar>(i - 1, j + 1);
                int p4 = (j == ImgWidth - 1) ? 0 : src.at<uchar>(i, j + 1);
                int p5 = (i == ImgHeight - 1 || j == ImgWidth - 1) ? 0 : src.at<uchar>(i + 1, j + 1);
                int p6 = (i == ImgHeight - 1) ? 0 : src.at<uchar>(i + 1, j);
                int p7 = (i == ImgHeight - 1 || j == 0) ? 0 : src.at<uchar>(i + 1, j - 1);
                int p8 = (j == 0) ? 0 : src.at<uchar>(i, j - 1);
                int p9 = (i == 0 || j == 0) ? 0 : src.at<uchar>(i - 1, j - 1);

                if ((p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) >= 2 && (p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) <= 6)
                {
                    int ap = 0;
                    if (p2 == 0 && p3 == 1) ++ap;
                    if (p3 == 0 && p4 == 1) ++ap;
                    if (p4 == 0 && p5 == 1) ++ap;
                    if (p5 == 0 && p6 == 1) ++ap;
                    if (p6 == 0 && p7 == 1) ++ap;
                    if (p7 == 0 && p8 == 1) ++ap;
                    if (p8 == 0 && p9 == 1) ++ap;
                    if (p9 == 0 && p2 == 1) ++ap;

                    if (ap == 1)
                    {
                        if (p2*p4*p8 == 0)
                        {
                            if (p2*p6*p8 == 0)
                            {
                                //标记
                                mFlag.push_back(make_pair(i, j));
                            }
                        }
                    }
                }
            }
        }
        //删除
        for (vector<pair<int, int> >::iterator i = mFlag.begin(); i != mFlag.end(); ++i)
        {
            src.at<uchar>(i->first, i->second) = 0;
        }

        //直到没有点满足,算法结束
        if (mFlag.size() == 0) break;
        else mFlag.clear();//将mFlag清空
    }

    cv::threshold(src, src, 0, 255, CV_THRESH_BINARY);//二值化图像
}
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Stella981 Stella981
3年前
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解2016年09月02日00:00:36 \牧野(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fme.csdn.net%2Fdcrmg) 阅读数:59593
Stella981 Stella981
3年前
Python图片验证码降噪 — 8邻域降噪
!(http://qiniu.spiderpy.cn/19130/captchat.jpg)简介图片验证码识别的可以分为几个步骤,一般用Pillow库或OpenCV来实现,这几个过程是:1.灰度处理&二值化2.降噪3.字符分割4.标准化5.识别所谓降噪就是把不需
Wesley13 Wesley13
3年前
Java日期时间API系列31
  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
Java日期时间API系列30
  实际使用中,经常需要使用不同精确度的Date,比如保留到天2020042300:00:00,保留到小时,保留到分钟,保留到秒等,常见的方法是通过格式化到指定精确度(比如:yyyyMMdd),然后再解析为Date。Java8中可以用更多的方法来实现这个需求,下面使用三种方法:使用Format方法、 使用Of方法和使用With方法,性能对比,使用
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这