java使用opencv库二值化图片

2023-11-04

应用场景:
截取监控视频图片保存到本地后用作后期监控视频角度调整参考。
使用二值化后的图片并进行透明度降低进行监控矫正。

package img;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.IOException;

public class Canny {

	static int edge[][];
	static int find[][];
	static double vmax=0;
	static BufferedImage cannyImg;

	public Canny() {
		// TODO Auto-generated constructor stub
	}
	public static BufferedImage getCannyImg(BufferedImage image,double a,double b,double g) throws IOException {
		// TODO Auto-generated method stub
		// 灰度化
		BufferedImage grayImg=getGray(image);
		// 高斯滤波
		grayImg=filtering_Gaussian(grayImg, g);
		// 计算梯度幅度值和梯度方向
		double grad[][][]=getGradient(grayImg);
		// double nms[][]=NMS(grad);
		// 非极大值抑制处理(插值法)
		double nms[][]=NMS_2(grad);
		// 双阈值处理
		double thresh=vmax*a;
		double_threshold(nms, b*thresh, thresh);
		// 边界跟踪处理
		boundary_tracking();
		BufferedImage cannyImg=showCannyImg();
		return cannyImg;
	}
	private static BufferedImage getGray(BufferedImage image) {
		// TODO Auto-generated method stub
		int w = image.getWidth();
		int h = image.getHeight();

		BufferedImage grayImg= new BufferedImage(w,h,image.getType());

		for(int x=0;x<w;x++)
			for(int y=0;y<h;y++) {
				int pixel=image.getRGB(x, y);
				int r=(pixel & 0xff0000) >> 16;
				int g=(pixel & 0xff00) >> 8;
				int b=(pixel & 0xff);
				int gray = (int) (0.299 * r + 0.587 * g + 0.114 * b);
				grayImg.setRGB(x, y, new Color(gray,gray,gray).getRGB());
			}

		return grayImg;
	}
	private static int RGBTogray(int pixel) {
		// TODO Auto-generated method stub
		return pixel & 0xff;
	}
	private static BufferedImage filtering_Gaussian(BufferedImage image, double g) {
		// TODO Auto-generated method stub
		int w = image.getWidth();
		int h = image.getHeight();

		int length=5;
		int k=length/2;
		double sigma=Math.sqrt(g);

		double[][] gaussian=new double[length][length];
		double sum=0;
		for(int i=0;i<length;i++) {
			for(int j=0;j<length;j++) {
				gaussian[i][j]=Math.exp(-((i-k)*(i-k)+(j-k)*(j-k))/(2*sigma*sigma));
				gaussian[i][j]/=2*Math.PI*sigma*sigma;
				sum+=gaussian[i][j];
			}
		}
		for(int i=0;i<length;i++) {
			for(int j=0;j<length;j++) {
				gaussian[i][j]/=sum;
			}
		}

		BufferedImage GaussianImg= new BufferedImage(w,h,image.getType());

		for(int x=k;x<w-k;x++) {
			for(int y=k;y<h-k;y++) {
				int newpixel=0;
				for(int gx=0;gx<length;gx++) {
					for(int gy=0;gy<length;gy++) {
						int ix=x+gx-k;
						int iy=y+gy-k;
						if(ix<0||iy<0||ix>=w||iy>=h)
							continue;
						else {
							newpixel+=RGBTogray(image.getRGB(ix, iy))*gaussian[gx][gy];
						}
					}
				}
				newpixel=(int) Math.round(1.0*newpixel);
				GaussianImg.setRGB(x, y, new Color(newpixel,newpixel,newpixel).getRGB());
			}
		}
		return GaussianImg;
	}
	private static double[][][] getGradient(BufferedImage image){
		// TODO Auto-generated method stub
		int w = image.getWidth();
		int h = image.getHeight();
		int step=1;
		double[][][] grad = new double[w][h][2];
		for(int x=step;x<w-step;x++) {
			for(int y=step;y<h-step;y++) {
				int gx=-RGBTogray(image.getRGB(x-step, y-step))
						-RGBTogray(image.getRGB(x-step, y))*2
						-RGBTogray(image.getRGB(x-step, y+step))
						+RGBTogray(image.getRGB(x+step, y-step))
						+RGBTogray(image.getRGB(x+step, y))*2
						+RGBTogray(image.getRGB(x+step, y+step));
				int gy=RGBTogray(image.getRGB(x-step, y+step))
						+RGBTogray(image.getRGB(x, y+step))*2
						+RGBTogray(image.getRGB(x+step, y+step))
						-RGBTogray(image.getRGB(x-step, y-step))
						-RGBTogray(image.getRGB(x, y-step))*2
						-RGBTogray(image.getRGB(x+step, y-step));
				grad[x][y][0]=Math.sqrt(gx*gx+gy*gy);
				if(gx==0)
					grad[x][y][1]=90;
				else
					grad[x][y][1]=Math.toDegrees(Math.atan(1.0*gy/gx));
			}
		}

		return grad;
	}
	private static double[][] NMS(double[][][] grad){
		// TODO Auto-generated method stub
		int w=grad.length;
		int h=grad[0].length;
		double[][] nms=new double[w][h];
		for(int x=1;x<w-1;x++) {
			for(int y=1;y<h-1;y++) {
				nms[x][y]=grad[x][y][0];
				if(grad[x][y][0]==0)
					continue;
				int a=(int) Math.round(grad[x][y][1]/45);
				if(a==-2||a==2) {
					if(grad[x][y][0]<grad[x][y-1][0]||grad[x][y][0]<grad[x][y+1][0])
						nms[x][y]=0;
				}
				else if(a==-1) {
					if(grad[x][y][0]<grad[x-1][y-1][0]||grad[x][y][0]<grad[x+1][y+1][0])
						nms[x][y]=0;
				}
				else if(a==0) {
					if(grad[x][y][0]<grad[x-1][y][0]||grad[x][y][0]<grad[x+1][y][0])
						nms[x][y]=0;
				}
				else if(a==1) {
					if(grad[x][y][0]<grad[x+1][y-1][0]||grad[x][y][0]<grad[x-1][y+1][0])
						nms[x][y]=0;
				}
				if(nms[x][y]>vmax)vmax=nms[x][y];
			}
		}

		return nms;
	}
	private static double[][] NMS_2(double[][][] grad) {
		// TODO Auto-generated method stub
		int w=grad.length;
		int h=grad[0].length;
		double[][] nms=new double[w][h];
		for(int x=1;x<w-1;x++) {
			for(int y=1;y<h-1;y++) {
				nms[x][y]=grad[x][y][0];
				if(grad[x][y][0]==0)
					continue;
				int x1,y1,x2,y2;
				double weight=Math.tan(Math.toRadians(grad[x][y][1]));
				if(grad[x][y][1]>45) {
					x1=0;y1=1;x2=1;y2=1;
					weight=1.0/weight;
				}else if(grad[x][y][1]>0) {
					x1=1;y1=0;x2=1;y2=1;
					weight*=1;
				}else if(grad[x][y][1]>-45) {
					x1=1;y1=0;x2=1;y2=-1;
					weight*=-1;
				}else {
					x1=0;y1=-1;x2=1;y2=-1;
					weight=-1.0/weight;
				}
				double g1=grad[x+x1][y+y1][0];
				double g2=grad[x+x2][y+y2][0];
				double g3=grad[x-x1][y-y1][0];
				double g4=grad[x-x2][y-y2][0];
				double grad_count_1=g1*weight+g2*(1-weight);
				double grad_count_2=g3*weight+g4*(1-weight);
				if(grad[x][y][0]<grad_count_1||grad[x][y][0]<grad_count_2)
					nms[x][y]=0;
				if(nms[x][y]>vmax)vmax=nms[x][y];
			}
		}
		return nms;
	}
	private static void double_threshold(double[][] nms,double low_th,double high_th){
		// TODO Auto-generated method stub
		int w=nms.length;
		int h=nms[0].length;
		edge=new int[w][h];
		for(int x=0;x<w;x++) {
			for(int y=0;y<h;y++) {
				if(nms[x][y]>=high_th) {
					edge[x][y]=2;
				}else if(nms[x][y]>=low_th) {
					edge[x][y]=1;
				}
			}
		}
	}
	private static void dfs(int x,int y,int w,int h) {
		// TODO Auto-generated method stub
		if(x<0||x>=w||y<0||y>=h||find[x][y]==1)return ;
		find[x][y]=1;
		if(edge[x][y]>=1) {
			edge[x][y]=2;
			for(int i=-1;i<=1;i++) {
				for(int j=-1;j<=1;j++) {
					dfs(x+i,y+j,w,h);
				}
			}
		}
	}
	private static int[][] boundary_tracking(){
		// TODO Auto-generated method stub
		int w=edge.length;
		int h=edge[0].length;

		find=new int[w][h];

		for(int x=0;x<w;x++) {
			for(int y=0;y<h;y++) {
				if(find[x][y]==1)continue;
				if(edge[x][y]==2) {
					dfs(x,y,w,h);
				}else if(edge[x][y]==0) {
					find[x][y]=1;
				}
			}
		}
		return edge;
	}
	private static BufferedImage showCannyImg() throws IOException {
		// TODO Auto-generated method stub
		int w=edge.length;
		int h=edge[0].length;

		BufferedImage cannyImg= new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
		for(int x=0;x<w;x++) {
			for(int y=0;y<h;y++) {
				if(edge[x][y]==2) {
					cannyImg.setRGB(x, y, new Color(255,0,0).getRGB());
				}else {
					cannyImg.setRGB(x, y, new Color(0,0,0).getRGB());
				}
			}
		}
		return cannyImg;
	}
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java使用opencv库二值化图片 的相关文章

随机推荐

  • 常用决策树模型ID3、C4.5、CART算法

    决策树概述 决策树 decision tree 是一种基本的分类与回归方法 下面提到的ID3 C4 5 CART主要讨论分类的决策树 在分类问题中 表示基于特征对实例进行分类的过程 可以认为是if then的集合 也可以认为是定义在特征空间
  • 计算机图形学期刊和会议

    目录 中国计算机学会推荐国际学术期刊 计算机图形学与多媒体 一 A类 二 B类 三 C类 中国计算机学会推荐国际学术会议 计算机图形学与多媒体 一 A类 二 B类 三 C类 中国计算机学会推荐国际学术期刊 计算机图形学与多媒体 一 A类 序
  • 光纤收发器怎么连?光纤收发器连接图解!

    光纤收发器可以实现光信号和电信号的转换 通过光纤进行信号的转换 最后和一些设备连接 让你的传输通信畅通无阻 当我们远距离传输时 通常会使用光纤来传输 因为光纤的传输距离很远 一般来说单模光纤的传输距离在10千米以上 而多模光纤的传输距离最高
  • C++报错提示某类名不是类或命名空间名称

    在学习C 的友元时 遇到一个问题 两个类互相调用时报错 如图 include
  • 三菱数控CNC系统G代码M代码大全

    G00 快速定位 G01 直线补间切削 G02 圆弧补间切削CW 顺时针 G03 圆弧补间切削CCW 逆时针 G02 3 指数函数补间 正转 G03 3 指数函数补间 逆转 G04 暂停 G05 高速高精度制御 1 G05 1 高速高精度制
  • C++ //STL 简介

    STL简介 STL Standard Template Library 即标准模板库 是一个具有工业强度的 高效的C 程序库 STL的一个重要特点是数据结构和算法的分离 STL另一个重要特性是它不是面向对象的 STL六大组件 容器 Cont
  • 非线性解方程组c语言_08 -- 非线性有限元分析方法

    到目前为止 讨论的都是线性问题 这里采用了两个基本假设 1 材料的应力 应变关系是线性的 D 2 结构的应变 位移关系是线性的 B 非线性有限元分析方法大同小异 以材料非线性为例 1 当材料的应力 应变关系是非线性时 刚度矩阵不是常数 与位
  • 代码管理工具SVN

    svn 什么是svn SVN是Subversion的简称 是一个开放源代码的版本控制系统 相较于RCS CVS 它采用了分支管理系统 它的设计目标就是取代CVS 互联网上很多版本控制服务已从CVS迁移到Subversion 说得简单一点SV
  • 力扣-->#剑指Offer 563 . 二叉树倾斜

    这道题要理解有一定的困难 首先看到这样的题目肯定想到的就是遍历 其次 需要有一个值来记录倾斜度 即 left right 再者 需要一个函数来帮忙辅助计算倾斜度 即findSum class Solution int findSum Tre
  • RIP、OSPF等路由协议严格意义上讲属哪一层?

    1 RIP基于UDP BGP基于TCP OSPF和EIGRP基于IP 这些在TCP IP协议栈中定义的路由协议用于发现和维护前往目的地的最短路径 你可以认为它们不属于网络层协议 注意 是用 based on 而不是实现了 BGP用TCP 所
  • 微信公众号h5页面实现授权,前端部分

    授权步骤 微信开发工具上配置公众号的apiId 微信环境内调起微信的授权功能 代码实现 此段代码放在app vue的监听函数中 每当路由发生变化 都会判断此页面是否已授权 没授权的话则进行授权 watch route handler fun
  • 4. 消息中心的设计与实现

    消息中心的设计与实现 一 引言 运用场景 1 消息的主动提醒 客户端被动接收 2 客户模块 及时通讯 3 单一登录 一个账号只能在一个设备登录 消息中心的实现方案 1 客户端轮询 2 TCP长连接 常用 Java的长连接的方案 Java B
  • windows命令行下ftp连接超时的可能原因

    1 需要连接的主机没有启用ftp服务 iis没有建立ftp站点 ftp身份验证设置不当 详情参考博文 windows下使用ftp 以及 windows开启ftp服务 两篇博文有重复的部分 我将他们取并集操作了一遍 另外 我还处理了iis未授
  • 使用Visual Studio编译ffmpeg

    一 首先参照下面的链接配置和编译 FFmpeg在VS2017下的编译 vs2017 ffmpeg源码编译 鱼儿 1226的博客 CSDN博客 vs2019编译ffmpeg源码为静态库动态库 完整步骤 亲测可行 ffmpeg vs 令狐掌门的
  • 嵩天老师-Python语言程序设计-Python123配套练习测验题目汇总整理

    测验1 Python基本语法元素 知识点概要 普遍认为Python语言诞生于1991年 Python语言中的缩进在程序中长度统一且强制使用 只要统一即可 不一定是4个空格 尽管这是惯例 IPO模型指 Input Process Output
  • 求最长不含重复字符的子字符串——C++

    声明 本文原题主要来自力扣 记录此博客主要是为自己学习总结 不做任何商业等活动 一 原题描述 剑指 Offer 48 最长不含重复字符的子字符串 请从字符串中找出一个最长的不包含重复字符的子字符串 计算该最长子字符串的长度 示例 1 输入
  • Linux查看进程命令

    查看进程 1 ps 命令用于查看当前正在运行的进程 grep 搜索 例如 ps ef grep java 表示查看所有进程里 CMD 是 java 的进程信息 2 ps aux grep java aux 显示所有状态 ps 3 kill
  • Sublime Text4 配置 Python3 环境、代码提示、编译报错教程

    1 配置 Python3 环境 单击 工具 gt 编译系统 gt 新建编译系统 弹出 替换里面的内容为 cmd G CodeTools anaconda3 python exe u file file regex File line 0 9
  • 数据中台数据分析过程梳理

    在当今社会中 随着企业的快速发展 相关业务系统的建设也会越来越多 新的业务模式 新的IT架构 多云环境的出现等等 而一些问题就逐渐暴露了出来 企业之间的IT无法做到互通 新模式生产数据与旧数据无法互通 企业IT架构错综复杂 底层数据互通更加
  • java使用opencv库二值化图片

    应用场景 截取监控视频图片保存到本地后用作后期监控视频角度调整参考 使用二值化后的图片并进行透明度降低进行监控矫正 package img import java awt Color import java awt image Buffer