图像处理之图像内插值与外插值

简介: 图像处理之图像内插值与外插值 两张图像混合时通过内插与外插值方法可以实现图像亮度、对比度、饱和度、填色、锐化等常见的图像处理操作。在两张图像混合时最常见是线性插值方法,使用的混合权重公式如下:这个就是两张图像最常见的混合公式,其实我们很少考虑到值大于1的情况,当这个时候得到的效果跟在值属于[0,1]之间相反,我们称之为两张图像混合的外插值方法,而常见的值属于[0,1]之间称之为内插值方法。

图像处理之图像内插值与外插值

 

两张图像混合时通过内插与外插值方法可以实现图像亮度、对比度、饱和度、填色、锐化等常见的图像处理操作。在两张图像混合时最常见是线性插值方法,使用的混合权重公式如下:


这个就是两张图像最常见的混合公式,其实我们很少考虑到值大于1的情况,当这个时候得到的效果跟在值属于[0,1]之间相反,我们称之为两张图像混合的外插值方法,而常见的值属于[0,1]之间称之为内插值方法。外插值可以用来生成跟内插值效果相反的图像,比如内插值模糊图像,通过外插值可以去模糊,外插值可以调节饱和度,可以实现图像一些列的处理比如亮度、饱和度、对比度、锐化调整。

一:改变亮度

创建一张跟输入图像大小一致的黑色图像,对图像混合时使用内插值方法,我们可以得到一个比较暗的版本图像,通过混合时候使用外插值方法,得到一个亮度更高的版本图像。效果如下:


代码如下:

package com.gloomyfish.ii.demo;

import java.awt.image.BufferedImage;
import java.util.Arrays;

public class AdjustBrightness extends AbstractImageOptionFilter {

	private float alpha;
	public AdjustBrightness() {
		alpha = 0.5f;
	}

	public float getAlpha() {
		return alpha;
	}

	public void setAlpha(float alpha) {
		this.alpha = alpha;
	}

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

		// create black image
		BufferedImage bimage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
		int r = 0, g = 0, b = 0;
		int pixel = (0xff << 24) | (r << 16) | (g << 8) | b;
		int[] values = new int[width * height];
		Arrays.fill(values, pixel);
		setRGB(bimage, 0, 0, width, height, values);

		// adjust contrast
		int[] pixels = new int[width * height];
		int[] outPixels = new int[width * height];
		getRGB(image, 0, 0, width, height, pixels);
		int index = 0;
		for (int row = 0; row < height; row++) {
			for (int col = 0; col < width; col++) {
				index = row*width + col;
				// black image
				int r1 = (values[index]&0xff0000)>>16;
				int g1 = (values[index]&0xff00)>>8;
				int b1 = values[index]&0xff;
				
				// target image
				int r2 = (pixels[index]&0xff0000)>>16;
				int g2 = (pixels[index]&0xff00)>>8;
				int b2 = pixels[index]&0xff;
				
				r = clamp((int)(r1*(1.0 - alpha) + r2*alpha));
				g = clamp((int)(g1*(1.0 - alpha) + g2*alpha));
				b = clamp((int)(b1*(1.0 - alpha) + b2*alpha));
				
				outPixels[index] = (0xff << 24) | (r << 16) | (g << 8) | b;
			}
		}
		
		BufferedImage dest = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
		setRGB(dest, 0, 0, width, height, outPixels);
		return dest;
	}

}

二:调整对比度

计算当前输入图像的平均亮度得到一张常量亮度的图像,用该图像跟原图像进行权重混合当alpha值在0到1之间是内插值得到对比度降低的图片,当值大于1时候是外插值得到对比度提高图片。效果如下:

代码如下:

package com.gloomyfish.ii.demo;

import java.awt.image.BufferedImage;
import java.util.Arrays;

public class AdjustContrast extends AbstractImageOptionFilter {

	private float alpha;
	
	public AdjustContrast() {
		alpha = 0.5f;
	}

	public float getAlpha() {
		return alpha;
	}

	public void setAlpha(float alpha) {
		this.alpha = alpha;
	}

	@Override
	public BufferedImage process(BufferedImage image) {
		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);

		// the average luminance image 
		int[] values = createLuminanceImage(width, height, pixels);
		int r=0, g=0, b=0;
		
		// adjust contrast
		int index = 0;
		for (int row = 0; row < height; row++) {
			for (int col = 0; col < width; col++) {
				index = row*width + col;
				// constant means image
				int r1 = (values[index]&0xff0000)>>16;
				int g1 = (values[index]&0xff00)>>8;
				int b1 = values[index]&0xff;
				
				// target image
				int r2 = (pixels[index]&0xff0000)>>16;
				int g2 = (pixels[index]&0xff00)>>8;
				int b2 = pixels[index]&0xff;
				
				r = clamp((int)(r1*(1.0 - alpha) + r2*alpha));
				g = clamp((int)(g1*(1.0 - alpha) + g2*alpha));
				b = clamp((int)(b1*(1.0 - alpha) + b2*alpha));
				
				outPixels[index] = (0xff << 24) | (r << 16) | (g << 8) | b;
			}
		}
		
		BufferedImage dest = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
		setRGB(dest, 0, 0, width, height, outPixels);
		return dest;
	}
	
	private int[] createLuminanceImage(int width, int height, int[] pixels) {
		int r = 0, g = 0, b = 0;
		int index = 0;
		double sumr = 0, sumg = 0, sumb = 0;
		for(int row=0; row<height; row++) {
			for(int col=0; col<width; col++) {
				r = (pixels[index]&0xff0000)>>16;
				g = (pixels[index]&0xff00)>>8;
				b = pixels[index]&0xff;
				
				sumr += r;
				sumg += g;
				sumb += b;
				
				// double gray = (0.2126 * r + 0.7152 * g + 0.0722 * b);
			}
		}
		
		int tp = width * height;
		r= (int)(sumr / tp);
		g= (int)(sumg / tp);
		b= (int)(sumb / tp);
		int pixel = (0xff << 24) | (r << 16) | (g << 8) | b;
		int[] values = new int[width * height];
		Arrays.fill(values, pixel);
		return values;
	}

}

三:模糊与锐化

对输入图像进行模糊得到一张模糊版本的图像跟原图像进行混合当alpha值在0~1之间时内插值得到轻微模糊图像,当值大于1时候得到反模糊的锐化效果图像。效果显示如下:

代码显示如下:

package com.gloomyfish.ii.demo;

import java.awt.image.BufferedImage;

public class AdjustBlurAndSharpen extends AbstractImageOptionFilter {

	private float alpha;
	private BufferedImage blurImage;

	public AdjustBlurAndSharpen() {
		alpha = 0.5f;
	}

	public float getAlpha() {
		return alpha;
	}

	public void setAlpha(float alpha) {
		this.alpha = alpha;
	}

	public BufferedImage getBlurImage() {
		return blurImage;
	}

	public void setBlurImage(BufferedImage blurImage) {
		this.blurImage = blurImage;
	}

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

		// read blur image
		int r=0, g=0, b=0;
		int[] values = new int[width * height];
		getRGB(blurImage, 0, 0, width, height, values);

		// adjust contrast
		int[] pixels = new int[width * height];
		int[] outPixels = new int[width * height];
		getRGB(image, 0, 0, width, height, pixels);
		int index = 0;
		for (int row = 0; row < height; row++) {
			for (int col = 0; col < width; col++) {
				index = row * width + col;
				// blur image
				int r1 = (values[index] & 0xff0000) >> 16;
				int g1 = (values[index] & 0xff00) >> 8;
				int b1 = values[index] & 0xff;

				// original image
				int r2 = (pixels[index] & 0xff0000) >> 16;
				int g2 = (pixels[index] & 0xff00) >> 8;
				int b2 = pixels[index] & 0xff;
				
				// final result
				r = clamp((int) (r1 * (1.0 - alpha) + r2 * alpha));
				g = clamp((int) (g1 * (1.0 - alpha) + g2 * alpha));
				b = clamp((int) (b1 * (1.0 - alpha) + b2 * alpha));

				outPixels[index] = (0xff << 24) | (r << 16) | (g << 8) | b;
			}
		}

		BufferedImage dest = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
		setRGB(dest, 0, 0, width, height, outPixels);
		return dest;
	}

}

内插值与外插值通过两张图像的权重混合巧妙的实现了常见的图像亮度、对比度、模糊与锐化操作,这样的操作简单直观,避免了亮度调整时候色彩空间转换和锐化时候需要掩膜计算的问题。是一种新的调整图像对比度、亮度、模糊与锐化的手段。

本篇文章也是本人第100篇图像处理文章,分享有用知识,各位支持是我坚持下来的最大动力

目录
相关文章
|
6月前
|
算法 计算机视觉
图像处理之积分图应用四(基于局部均值的图像二值化算法)
图像处理之积分图应用四(基于局部均值的图像二值化算法)
542 0
|
6月前
|
算法 计算机视觉
图像处理之基于一维高斯快速模糊
图像处理之基于一维高斯快速模糊
31 8
|
6月前
|
算法 计算机视觉
图像处理之基于像素的图像混合
图像处理之基于像素的图像混合
37 1
|
6月前
|
算法 计算机视觉
图像处理之错切变换
图像处理之错切变换
101 1
|
6月前
|
计算机视觉
图像处理之图像内插值与外插值
图像处理之图像内插值与外插值
32 0
|
6月前
|
算法 C语言 计算机视觉
图像处理之图像快速插值放缩算法
图像处理之图像快速插值放缩算法
37 0
|
6月前
|
算法 BI 计算机视觉
图像处理之积分图应用一(半径无关的快速模糊算法)
图像处理之积分图应用一(半径无关的快速模糊算法)
46 0
|
6月前
|
算法 计算机视觉
图像处理之Lanczos采样放缩算法
图像处理之Lanczos采样放缩算法
61 0
|
6月前
|
算法 Java
图像放缩之双立方插值
图像放缩之双立方插值
44 0
|
7月前
|
文字识别 Python
Halcon 学习笔记五:几何定位+仿射变换+测量
Halcon 学习笔记五:几何定位+仿射变换+测量
672 0