Java Opencv 实现细化 二值化

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

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

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

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

用OpenCV验证腐蚀和膨胀

1public class threshold { 2 3 private final static String path = System.getProperty("user.dir") + "\\catton.jpg"; 4 5 static { 6 platformUtils.loadLibraries(); 7 } 8 9 10 public static void main(String[] args) { 11 12 Mat src= Imgcodecs.imread(path); 13 14 Mat dest=new Mat(); 15 16 Imgproc.threshold(src,dest,100,500,Imgproc.THRESH_BINARY); 17 18 //获取数据 19 byte [] data=new byte[dest.rows()*dest.cols()*(int)dest.elemSize()]; 20 dest.get(0,0,data); 21 22 //转为二值化image buffer作为存储对象 可以存储二进制 也可以存储灰度化图像 23 BufferedImage bufferedImage=new BufferedImage(dest.cols(),dest.rows(),BufferedImage.TYPE_BYTE_GRAY); 24 25 bufferedImage.getRaster().setDataElements(0,0,dest.cols(),dest.rows(),data); 26 27 JFrame frame=new JFrame(); 28 frame.getContentPane().add(new JLabel(new ImageIcon(bufferedImage))); 29 frame.pack(); 30 frame.setVisible(true); 31 32 33 HighGui.imshow(" threshold image",dest); 34 HighGui.waitKey(0); 35 } 36}

二值化

用OpenCV验证细化

1//提取图像的骨架 2void ImgThin(cv::Mat src,int maxIterations=-1) 3{ 4 if (src.empty()) return;//图像为空,直接返回 5 cv::threshold(src, src, m_dThreshold, 1, CV_THRESH_BINARY);//转为0或1的图像 6 7 int ImgHeight = src.rows; 8 int ImgWidth = src.cols; 9 10 int count = 0; //记录迭代次数 11 while (true) 12 { 13 count++; 14 if (maxIterations != -1 && count > maxIterations) //限制次数并且迭代次数到达 15 break; 16 17 vector<pair<int, int> > mFlag; //用于标记需要删除的点 18 //对点标记 19 for (int i = 0; i < ImgHeight; ++i) 20 { 21 for (int j = 0; j < ImgWidth; ++j) 22 { 23 //如果满足四个条件,进行标记 24 // p9 p2 p3 25 // p8 p1 p4 26 // p7 p6 p5 27 int p1 = src.at<uchar>(i, j); 28 int p2 = (i == 0) ? 0 : src.at<uchar>(i - 1, j); 29 int p3 = (i == 0 || j == ImgWidth - 1) ? 0 : src.at<uchar>(i - 1, j + 1); 30 int p4 = (j == ImgWidth - 1) ? 0 : src.at<uchar>(i, j + 1); 31 int p5 = (i == ImgHeight - 1 || j == ImgWidth - 1) ? 0 : src.at<uchar>(i + 1, j + 1); 32 int p6 = (i == ImgHeight - 1) ? 0 : src.at<uchar>(i + 1, j); 33 int p7 = (i == ImgHeight - 1 || j == 0) ? 0 : src.at<uchar>(i + 1, j - 1); 34 int p8 = (j == 0) ? 0 : src.at<uchar>(i, j - 1); 35 int p9 = (i == 0 || j == 0) ? 0 : src.at<uchar>(i - 1, j - 1); 36 37 if ((p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) >= 2 && (p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) <= 6) 38 { 39 int ap = 0; 40 if (p2 == 0 && p3 == 1) ++ap; 41 if (p3 == 0 && p4 == 1) ++ap; 42 if (p4 == 0 && p5 == 1) ++ap; 43 if (p5 == 0 && p6 == 1) ++ap; 44 if (p6 == 0 && p7 == 1) ++ap; 45 if (p7 == 0 && p8 == 1) ++ap; 46 if (p8 == 0 && p9 == 1) ++ap; 47 if (p9 == 0 && p2 == 1) ++ap; 48 49 if (ap == 1) 50 { 51 if (p2*p4*p6 == 0) 52 { 53 if (p4*p6*p8 == 0) 54 { 55 //标记 56 mFlag.push_back(make_pair(i, j)); 57 } 58 } 59 } 60 } 61 } 62 } 63 64 //将标记的点删除 65 for (vector<pair<int, int> >::iterator i = mFlag.begin(); i != mFlag.end(); ++i) 66 { 67 src.at<uchar>(i->first, i->second) = 0; 68 } 69 70 //直到没有点满足,算法结束 71 if (mFlag.size() == 0) break; 72 else mFlag.clear();//将mFlag清空 73 74 //对点标记 75 for (int i = 0; i < ImgHeight; ++i) 76 { 77 for (int j = 0; j < ImgWidth; ++j) 78 { 79 //如果满足四个条件,进行标记 80 // p9 p2 p3 81 // p8 p1 p4 82 // p7 p6 p5 83 int p1 = src.at<uchar>(i, j); 84 if (p1 != 1) continue; 85 int p2 = (i == 0) ? 0 : src.at<uchar>(i - 1, j); 86 int p3 = (i == 0 || j == ImgWidth - 1) ? 0 : src.at<uchar>(i - 1, j + 1); 87 int p4 = (j == ImgWidth - 1) ? 0 : src.at<uchar>(i, j + 1); 88 int p5 = (i == ImgHeight - 1 || j == ImgWidth - 1) ? 0 : src.at<uchar>(i + 1, j + 1); 89 int p6 = (i == ImgHeight - 1) ? 0 : src.at<uchar>(i + 1, j); 90 int p7 = (i == ImgHeight - 1 || j == 0) ? 0 : src.at<uchar>(i + 1, j - 1); 91 int p8 = (j == 0) ? 0 : src.at<uchar>(i, j - 1); 92 int p9 = (i == 0 || j == 0) ? 0 : src.at<uchar>(i - 1, j - 1); 93 94 if ((p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) >= 2 && (p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) <= 6) 95 { 96 int ap = 0; 97 if (p2 == 0 && p3 == 1) ++ap; 98 if (p3 == 0 && p4 == 1) ++ap; 99 if (p4 == 0 && p5 == 1) ++ap; 100 if (p5 == 0 && p6 == 1) ++ap; 101 if (p6 == 0 && p7 == 1) ++ap; 102 if (p7 == 0 && p8 == 1) ++ap; 103 if (p8 == 0 && p9 == 1) ++ap; 104 if (p9 == 0 && p2 == 1) ++ap; 105 106 if (ap == 1) 107 { 108 if (p2*p4*p8 == 0) 109 { 110 if (p2*p6*p8 == 0) 111 { 112 //标记 113 mFlag.push_back(make_pair(i, j)); 114 } 115 } 116 } 117 } 118 } 119 } 120 //删除 121 for (vector<pair<int, int> >::iterator i = mFlag.begin(); i != mFlag.end(); ++i) 122 { 123 src.at<uchar>(i->first, i->second) = 0; 124 } 125 126 //直到没有点满足,算法结束 127 if (mFlag.size() == 0) break; 128 else mFlag.clear();//将mFlag清空 129 } 130 131 cv::threshold(src, src, 0, 255, CV_THRESH_BINARY);//二值化图像 132}
点赞
收藏

评论区

加载中...

相关推荐

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

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

Java日期时间API系列31

  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前

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