图像处理之积分图应用一(半径无关的快速模糊算法)

简介: 图像处理之积分图像应用一(半径无关的快速模糊算法)一:基本原理概述传统的图像空间域卷积模糊算法,当窗口大小改变时卷积模糊时间也会变化,而且随着窗口尺寸越大计算量也越大,算法运行时间约越长。在很多时候无法满足实时性要求。

图像处理之积分图像应用一(半径无关的快速模糊算法)

一:基本原理概述

传统的图像空间域卷积模糊算法,当窗口大小改变时卷积模糊时间也会变化,而且随着窗口尺寸越大计算量也越大,算法运行时间约越长。在很多时候无法满足实时性要求。而基于积分图像可以实现对窗口区域和大小的快速计算,把传统卷积模糊计算受窗口大小影响消除,把卷积模糊变成一个与窗口大小半径无关的常量时间完成的操作。关于如何从图像本身得到积分图像的算法请看上一篇文章《图像处理之积分图像算法》

二:详细解释

以5x5的窗口大小为例,假设图像I、积分图像II、处理之后模糊图像BI、则传统空间域卷积实现的图像均值模糊对每个像素点公式表示如下:



基于积分图像计算每个像素点模糊公式表示如下:

上述基于传统的均值模糊计算得到模糊之后的结果要计算24次加法和一次除法共计25次计算,而基于积分图像则只需要一次加法两次减法和一次除法共计四次计算,而且基于传统卷积均值模糊计算当窗口大小越大计算次数也越多,而基于积分图像则计算次数保持常量不变,是一个半径无关的均值模糊算法。

三:代码实现

积分图像算法实现参见:http://blog.csdn.net/jia20003/article/details/52710751

传统模式的卷积模糊代码如下:

package com.gloomyfish.ii.demo;

import java.awt.image.BufferedImage;

public class Convolution2DFilter extends AbstractImageOptionFilter {
	// 窗口半径大小
	private int xr;
	private int yr;

	public Convolution2DFilter() {
		xr = 1;
		yr = 1;
	}

	public int getXr() {
		return xr;
	}

	public void setXr(int xr) {
		this.xr = xr;
	}

	public int getYr() {
		return yr;
	}

	public void setYr(int yr) {
		this.yr = yr;
	}

	@Override
	public BufferedImage process(BufferedImage image) {
		long time = System.currentTimeMillis();
		int width = image.getWidth();
		int height = image.getHeight();

		int[] pixels = new int[width * height];
		int[] outPixels = new int[width * height];
		getRGB(image, 0, 0, width, height, pixels);
		int size = (xr * 2 + 1) * (yr * 2 + 1);
		int r = 0, g = 0, b = 0;

		for (int row = yr; row < height - yr; row++) {
			for (int col = xr; col < width - xr; col++) {
				int sr = 0, sg = 0, sb = 0;
				// 鍗风Н鎿嶄綔/妯℃澘璁$畻
				for (int i = -yr; i <= yr; i++) {
					int roffset = row + i;
					for (int j = -xr; j <= xr; j++) {
						int coffset = col + j;
						sr += ((pixels[roffset * width + coffset] >> 16) & 0xff);
						sg += (pixels[roffset * width + coffset] >> 8) & 0xff;
						sb += (pixels[roffset * width + coffset] & 0xff);
					}
				}

				r = sr / size;
				g = sg / size;
				b = sb / size;
				outPixels[row * width + col] = (0xff << 24) | (r << 16) | (g << 8) | b;
			}
		}
		System.out.println("Convolution2DFilter ->> time duration : " + (System.currentTimeMillis() - time));
		BufferedImage dest = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
		setRGB(dest, 0, 0, width, height, outPixels);
		return dest;
	}

}
基于积分图像的快速模糊代码如下:

package com.gloomyfish.ii.demo;

import java.awt.image.BufferedImage;

public class FastBlurFilter extends AbstractImageOptionFilter {
	// 窗口半径大小
	private int xr;
	private int yr;

	public FastBlurFilter() {
		xr = 1;
		yr = 1;
	}

	public int getXr() {
		return xr;
	}

	public void setXr(int xr) {
		this.xr = xr;
	}

	public int getYr() {
		return yr;
	}

	public void setYr(int yr) {
		this.yr = yr;
	}

	@Override
	public BufferedImage process(BufferedImage image) {
		long time = System.currentTimeMillis();
		int width = image.getWidth();
		int height = image.getHeight();
		// get image data
		int[] pixels = new int[width * height];
		int[] outPixels = new int[width * height];
		getRGB(image, 0, 0, width, height, pixels);
		int size = (xr * 2 + 1) * (yr * 2 + 1);
		int r = 0, g = 0, b = 0;
		
		// per-calculate integral image
		byte[] R = new byte[width*height];
		byte[] G = new byte[width*height];
		byte[] B = new byte[width*height];
		getRGB(width, height, pixels, R, G, B);
		IntIntegralImage rii = new IntIntegralImage();
		rii.setImage(R);
		rii.process(width, height);
		IntIntegralImage gii = new IntIntegralImage();
		gii.setImage(G);
		gii.process(width, height);
		IntIntegralImage bii = new IntIntegralImage();
		bii.setImage(B);
		bii.process(width, height);

		for (int row = yr; row < height - yr; row++) {
			for (int col = xr; col < width - xr; col++) {
				int sr = rii.getBlockSum(col, row, (yr * 2 + 1), (xr * 2 + 1));
				int sg = gii.getBlockSum(col, row, (yr * 2 + 1), (xr * 2 + 1));
				int sb = bii.getBlockSum(col, row, (yr * 2 + 1), (xr * 2 + 1));
				r = sr / size;
				g = sg / size;
				b = sb / size;
				outPixels[row * width + col] = (0xff << 24) | (r << 16) | (g << 8) | b;
			}
		}
		System.out.println("FastBlurFilter ->> time duration : " + (System.currentTimeMillis() - time));
		BufferedImage dest = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
		setRGB(dest, 0, 0, width, height, outPixels);
		return dest;
	}
	
	/** Returns the red, green and blue planes as 3 byte arrays. */
	public void getRGB(int width, int height, int[] pixels, byte[] R, byte[] G, byte[] B) {
		int c, r, g, b;
		for (int i=0; i < width*height; i++) {
			c = pixels[i];
			r = (c&0xff0000)>>16;
			g = (c&0xff00)>>8;
			b = c&0xff;
			R[i] = (byte)r;
			G[i] = (byte)g;
			B[i] = (byte)b;
		}
	}

}

四:效率之比

分别把窗口半径调整到1、3、10、20的情况下,对同一张图像做模糊处理,CPU耗时直方图如下:


可见在其它条件不改变的情况下,窗口半径越大,两者之间执行时间差距越大。各位国庆节快乐!

目录
相关文章
|
27天前
|
机器学习/深度学习 存储 算法
sklearn应用线性回归算法
sklearn应用线性回归算法
24 0
|
1月前
|
算法 计算机视觉
图像处理常用算法—6个算子 !!
图像处理常用算法—6个算子 !!
30 2
|
1月前
|
存储 算法 测试技术
ArrayList集合的两个实例应用,有趣的洗牌算法与杨辉三角
ArrayList集合的两个实例应用,有趣的洗牌算法与杨辉三角
23 1
|
1月前
|
机器学习/深度学习 算法 数据库
KNN和SVM实现对LFW人像图像数据集的分类应用
KNN和SVM实现对LFW人像图像数据集的分类应用
34 0
|
9天前
|
数据采集 算法 数据可视化
R语言聚类算法的应用实例
R语言聚类算法的应用实例
86 18
R语言聚类算法的应用实例
|
9天前
|
算法 数据可视化 数据挖掘
R语言社区主题检测算法应用案例
R语言社区主题检测算法应用案例
12 0
|
1月前
|
算法 数据可视化 计算机视觉
使用Python实现图像处理中的边缘检测算法
图像处理中的边缘检测是计算机视觉和图像识别领域的重要技术之一。本文将介绍如何利用Python语言实现常见的边缘检测算法,包括Sobel、Canny等,并结合实例演示其在图像处理中的应用。
|
1月前
|
存储 算法 安全
数据安全之道:加密算法在现代网络通信中的应用
本文将深入探讨加密算法在现代网络通信中的重要性和应用。通过介绍对称加密、非对称加密和哈希算法等加密技术,帮助读者了解数据安全保障的关键技术,并探讨其在保护数据完整性和隐私方面的作用。
|
1月前
|
传感器 算法 计算机视觉
基于肤色模型和中值滤波的手部检测算法FPGA实现,包括tb测试文件和MATLAB辅助验证
该内容是关于一个基于肤色模型和中值滤波的手部检测算法的描述,包括算法的运行效果图和所使用的软件版本(matlab2022a, vivado2019.2)。算法分为肤色分割和中值滤波两步,其中肤色模型在YCbCr色彩空间定义,中值滤波用于去除噪声。提供了一段核心程序代码,用于处理图像数据并在FPGA上实现。最终,检测结果输出到&quot;hand.txt&quot;文件。
|
1月前
|
机器学习/深度学习 算法 计算机视觉
基于yolov2深度学习网络的视频手部检测算法matlab仿真
基于yolov2深度学习网络的视频手部检测算法matlab仿真