基于积分图的二值图像膨胀算法实现
时间:2022-05-07
本文章向大家介绍基于积分图的二值图像膨胀算法实现,主要内容包括积分图来源与发展、积分图概念、膨胀介绍、基于积分图的形态学膨胀算法步骤、积分图方式与传统方式运行时间比对、基于积分图膨胀代码Java版本实现、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
积分图来源与发展
积分图是Crow在1984年首次提出,是为了在多尺度透视投影中提高渲染速度。随后这种技术被应用到基于NCC的快速匹配、对象检测和SURF变换中、基于统计学的快速滤波器等方面。积分图是一种在图像中快速计算矩形区域和的方法,这种算法主要优点是一旦积分图首先被计算出来我们可以计算图像中任意大小矩形区域的和而且是在常量时间内。这样在图像模糊、边缘提取、对象检测的时候极大降低计算量、提高计算速度。第一个应用积分图像技术的应用是在Viola-Jones的对象检测框架中出现。
积分图概念
在积分图(Integral Image - ii)上任意位置(x, y)处的ii(x, y)表示该点左上角所有像素之和,表示如下:
膨胀介绍
膨胀操作是图像形态学两个最基本的操作之一,另外一个是腐蚀。主要应用在二值图像和灰度图像分析上,膨胀操作可以适当的根据结构元素的大小来扩张图像前景对象。对二值图像来说,看上去像似边缘增长一样。数学定义如下:
其中W表示窗口大小,OpenCV中定义为结构元素,常见的结构元素包括
- 矩形
- 十字交叉
假设有3x3结构元素
二值图像如下
使用3x3结构元素膨胀之后结果如下:
上述图像说明如下:
1-表示白色(255),
0-表示黑色。
蓝色1-表示膨胀之后扩张区域,
红色1-表示二值图像原区域大小。
基于积分图的形态学膨胀算法步骤
- 根据输入二值图像建立积分图
- 使用积分图索引查找结构元素重叠区块的像素总和,如果不为0 而且总和不等于窗口大小X255,则中心像素设为255 ,即膨胀
- 重复第二步实现对每个像素点做相同计算。
- 输出结果,显示
积分图方式与传统方式运行时间比对
- 图像为600x400大小, 基于Java语言JDK8实现代码与运行测试结果如下:
从上面可以看出,基于积分图的方式,随着结构元素的变大,计算时间趋于一个常量时间值-C,而基于传统方式随着结构元素变大,时间消耗成几何级数增加。充分证明了基于积分图方式二值膨胀操作是一种高效时间线性化的算法实现。
基于积分图膨胀代码Java版本实现
public class FastDilateOperator extends AbstractByteProcessor {
private byte[] data;
private int radius; // must be odd
public FastDilateOperator() {
this.radius = 21;
}
public void setRadius(int radius) {
this.radius = radius;
if(radius % 2 == 0) {
throw new RuntimeException("invalid parameters");
}
}
public void setData(byte[] data) {
this.data = data;
}
@Override
public void process(int width, int height) {
int size = width*height;
byte[] output = new byte[size];
IntIntegralImage grayii = new IntIntegralImage();
grayii.setImage(data);
grayii.process(width, height);
int yr = radius/2;
int xr = radius/2;
System.arraycopy(data, 0, output, 0, size);
int index = 0;
int sum = radius*radius*255;
int c = 0;
for(int row=0; row<height; row++) {
for(int col=0; col<width; col++) {
index = row * width + col;
c = data[index]&0xff;
if(c == 255) continue;
// 计算均值
int sr = grayii.getBlockSum(col, row, (yr * 2 + 1), (xr * 2 + 1));
// 二值化
if(sr > 0 && sr < sum) {
output[index] = (byte)255;
}
}
}
System.arraycopy(output, 0, data, 0, size);
}
}
其中IntIntegralImage类为Java版本的积分图算法实现。 传统二值图像膨胀算法Java版本实现如下:
public class NormalDilateOperator extends AbstractByteProcessor {
private byte[] data;
private int radius; // must be odd
public NormalDilateOperator() {
this.radius = 21;
}
public void setRadius(int radius) {
this.radius = radius;
if(radius % 2 == 0) {
throw new RuntimeException("invalid parameters");
}
}
public void setData(byte[] data) {
this.data = data;
}
@Override
public void process(int width, int height) {
int size = width*height;
byte[] output = new byte[size];
IntIntegralImage grayii = new IntIntegralImage();
grayii.setImage(data);
grayii.process(width, height);
int yr = radius/2;
int xr = radius/2;
System.arraycopy(data, 0, output, 0, size);
int c = 0;
int nx=0, ny=0;
for(int row=0; row<height; row++) {
for(int col=0; col<width; col++) {
c = data[row*width+col]&0xff;
if(c == 255)continue;
c=0;
for(int y=-yr; y<=yr; y++) {
ny = y + row;
if(ny < 0 || ny >= height){
ny = 0;
}
for(int x=-xr; x<=xr; x++) {
nx = x+col;
if(nx < 0 || nx >= width) {
nx = 0;
}
c += data[ny*width+nx]&0xff;
}
}
if(c > 0) {
output[row*width+col] = (byte)255;
}
}
}
System.arraycopy(output, 0, data, 0, size);
}
}
运行截屏如下:
- Django 1.10中文文档-第一个应用Part6-静态文件
- Django 1.10中文文档-第一个应用Part5-测试
- 设计模式(5)-己所不欲,施之于人(代理模式)
- Python标准库笔记(4) — collections模块
- 使用captcha模块生成图形验证码
- 设计模式(6)-装饰器(认识程序中的装饰器)
- Selenium Webdriver常用方法
- 设计模式(7)-模板(从事务处理应用的模板)
- Python NLP入门教程
- 设计模式(8)-状态模式(关注状态之间的变化)
- Python标准库笔记(6) — struct模块
- Golang中image/jpeg包和image/png包用法
- Python Webdriver 重新使用已经打开的浏览器实例
- Golang-实现图片缩放
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- leetcode560题解【前缀和+哈希】
- 5秒解决:VMware Workstation 与 Hyper-V 不兼容
- Java的访问控制符详解(结合代码演示)
- Python贪吃蛇小游戏_完整源码免费分享
- GitHub修改昵称和用户名(图解详细教程)
- Python飞机大战小游戏_完整源码免费分享
- Linux求助命令
- Linux关机命令及步骤
- Java实现二叉树层次遍历:从上往下打印出二叉树的每个节点,同层节点从左至右打印。
- Django 用户认证系统使用总结
- 前端综合面试题(9道)
- 用SQL查询Oracle数据库名和实例名
- Hadoop历史服务器配置详细步骤
- MySQL常见关键字优先级
- Linux进程管理命令及状态详解