Java+opencv3.2.0之删除最小连通区域
来源:互联网 发布:java selenium教程 编辑:程序博客网 时间:2024/06/10 17:17
吐槽一下,在网上查了半天opencv3关于删除最小连通区域的方法,结果还是没找到,就自己写了一个,效果还可以,就发出来和大家分享一下。
思路:
1、遍历所有像素点
2、每遍历到一个黑点就去判断是否为连通区域起始点,若是则添加到待检测像素点集合中
3、遍历待检测像素点集合,检测待检测像素点周围(上下左右)的像素点,若是黑点,则添加到待检测像素点集合中,并把当前待检测像素点添加到已检测点集合。若待检测点集合中像素点数小于某个阈值时,就认为这些待检测点区域为最小连通区域。
4、查找到最小连通区域后把已检测点集合中的像素点设置成白点。
代码:
/** * 判断是否为连通区域起始点(有点问题,有待优化) * @param i 待检验点的横坐标 * @param j 待检验点的纵坐标 * @param srcImage 源图像 * @return true表示是连通区域起始点,false则反之 */ public boolean isStart(int i, int j, Mat srcImage){ int before = j - 1; int top = i - 1; if((before<0||srcImage.get(i, before)[0] == 255.0) && (top<0 || srcImage.get(top, j)[0] == 255.0)){ return true; } return false; }public Mat deleteMinConnectedArea(Mat srcImage,double minarea){ int iw = srcImage.width(); //横向 int ih = srcImage.height(); //纵向 System.out.println("宽和高:"+ iw +" "+ ih); for (int i = 0; i < ih; i++) { for (int j = 0; j < iw; j++) { double[] colors = srcImage.get(i, j); if(colors[0] < 255.0 && isStart(i, j, srcImage)){ List<Point> checkPoint = new ArrayList<Point>(); List<Point> checkedPoint = new ArrayList<Point>(); checkPoint.add(new Point(i, j)); ergodic(srcImage, checkPoint, checkedPoint, (int) minarea); } } } return srcImage; }/** * 连通像素计数 * @param i 第一个检测到的像素为0的横坐标 * @param j 第一个检测到的像素为0的纵坐标 * @param iw 源图像像素列数 * @param ih 源图像像素行数 * @param srcImage 源图像 * @param sp 待检测像素点 * @param lp 已检测像素点 */ public void ergodic(Mat srcImage, List<Point> sp, List<Point> lp, int minArea ){ for (int k = 0; k < sp.size(); k++) { check((int) sp.get(k).x, (int) sp.get(k).y, sp, lp, srcImage); if(sp.size() >= minArea){ lp.removeAll(lp); break; } } if(lp.size() < minArea){ for (Point point : lp) { srcImage.put((int) point.x, (int) point.y, 255.0); } } }/** * 像素点判断是否已检测过 * @param i 待检验是否已检测像素点横坐标 * @param j 待检验是否已检测像素点纵坐标 * @param lp 已检测点集合 * @return 检测结果 false表示未检测,true表示已检测 */ public boolean isExist(int i, int j, List<Point> lp){ if(lp.size() == 0){ return false; } for (Point point : lp) { if(point.x == i && point.y == j ){ return true; } } return false; }/** * 像素点判断是否已被发现(存储在待检测集合) * @param i 待检验是否已检测像素点横坐标 * @param j 待检验是否已检测像素点纵坐标 * @param sp 已检测点集合 * @return 检测结果 false表示未检测,true表示已检测 */ public boolean isFind(int i, int j, List<Point> sp){ if(sp.size() == 0){ return false; } for (Point point : sp) { if(point.x == i && point.y == j){ return true; } } return false; }/** * 检测当前像素点上下左右的像素,并把当前像素点添加到已检测集合 * @param i 检测当前像素点横坐标 * @param j 检测当前像素点纵坐标 * @param sp 待检测点集合 * @param lp 已检测点集合 * @param srcImage 源图像 */ public void check(int i, int j, List<Point> sp, List<Point> lp, Mat srcImage){ int before = j - 1; int after = j + 1; int top = i - 1; int bottom = i + 1; if(before >= 0 && srcImage.get(i, before)[0] == 0.0){ if(!isExist(i, before, lp) && !isFind(i, before, sp)){ sp.add(new Point(i, before)); } } if(after < srcImage.width() && srcImage.get(i, after)[0] == 0.0){ if(!isExist(i, after, lp) && !isFind(i, after, sp)){ sp.add(new Point(i, after)); } } if(top >= 0 && srcImage.get(top, j)[0] == 0.0){ if(!isExist(top, j, lp) && !isFind(top, j, sp)){ sp.add(new Point(top, j)); } } if(bottom < srcImage.height() && srcImage.get(bottom, j)[0] == 0.0){ if(!isExist(bottom, j, lp) && !isFind(bottom, j, sp)){ sp.add(new Point(bottom, j)); } } lp.add(new Point(i,j)); }public static void main(String[] args) { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); Mat mat = Imgcodecs.imread("F:\\20170801161034.png"); Imgproc.cvtColor(mat, mat, Imgproc.COLOR_BGR2GRAY); Imgproc.adaptiveThreshold(mat, mat, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY, 9, 0); Mat dst = new DeleteMinArea().deleteMinConnectedArea(mat,50); Imgcodecs.imwrite("F:\\31.jpg", dst); }
源图片:
结果图片:
阅读全文
0 0
- Java+opencv3.2.0之删除最小连通区域
- opencv 连通区域的最小外接矩形
- Java+opencv3.2.0之二值化
- 连通区域
- java图像处理--连通区域计数bwlable
- Java+opencv3.2.0之环境配置
- Java+opencv3.2.0之灰度化
- Java+opencv3.2.0之均值滤波
- Java+opencv3.2.0之高斯滤波
- Java+opencv3.2.0之中值滤波
- Java+opencv3.2.0之膨胀与腐蚀
- Java+opencv3.2.0之图像尺寸调整
- Java+opencv3.2.0之hough直线检测
- Java+opencv3.2.0之仿射变换
- Java+opencv3.2.0之直方图均衡
- Java+opencv3.2.0之canny算子
- Java+opencv3.2.0之sobel算子
- Java+opencv3.2.0之Laplacian算子
- 获取安卓系统版本等各个参数
- Servlet应用程序(2)----基于Filter Dispatcher的MVC
- VBScript 中常见的几种循环
- 使用 Router 实现的模块化,如何优雅的回到主页面
- 静态代理
- Java+opencv3.2.0之删除最小连通区域
- 简单说 !![]==true 与 []==true 引发的思考
- 关于c语言中字符常量,变量的两道经典例题
- C库中的strcpy,strncpy,memcpy,memmove,memset函数
- 个推推送项目实用(二)
- Android 原生 Intent 分享支持的那些事
- HDU6085Rikka with Candies
- React项目开发中的数据管理
- 海信 M30T 最新官方冰川白(8+1)S21版本 极致流畅