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

简介: 图像处理之图像内插值与外插值 两张图像混合时通过内插与外插值方法可以实现图像亮度、对比度、饱和度、填色、锐化等常见的图像处理操作。在两张图像混合时最常见是线性插值方法,使用的混合权重公式如下:这个就是两张图像最常见的混合公式,其实我们很少考虑到值大于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篇图像处理文章,分享有用知识,各位支持是我坚持下来的最大动力

目录
相关文章
|
1月前
halcon算子模板匹配(一)基于形状的模板匹配
halcon算子模板匹配(一)基于形状的模板匹配
|
算法 数据可视化
Halcon边缘检测和线条检测(1),文章含自适应/动态二值化等算子
Halcon边缘检测和线条检测(1),文章含自适应/动态二值化等算子
1152 0
|
3月前
|
文字识别 Python
Halcon 学习笔记五:几何定位+仿射变换+测量
Halcon 学习笔记五:几何定位+仿射变换+测量
102 0
|
4月前
[Halcon&图像] 图像、区域和轮廓相互转化
[Halcon&图像] 图像、区域和轮廓相互转化
72 1
|
11月前
|
计算机视觉 Python
OpenCV_03 图像的算数操作:图像的加法+图像的混合
你可以使用OpenCV的cv.add()函数把两幅图像相加,或者可以简单地通过numpy操作添加两个图像,如res = img1 + img2。两个图像应该具有相同的大小和类型,或者第二个图像可以是标量值。
58 0
|
机器学习/深度学习 传感器 算法
【图像处理】基于形状提取和模式匹配组合的面部特征点提取方法附Matlab代码
【图像处理】基于形状提取和模式匹配组合的面部特征点提取方法附Matlab代码
|
机器学习/深度学习 资源调度 算法
【图像插值】基于稀疏拉普拉斯滤波器处理红绿蓝三种像素实现插值效果附matlab代码
【图像插值】基于稀疏拉普拉斯滤波器处理红绿蓝三种像素实现插值效果附matlab代码
|
算法 计算机视觉 Python
图像插值算法和OpenCV框架
图像插值算法和OpenCV框架
295 0
图像插值算法和OpenCV框架
|
算法 Java 计算机视觉
常用的像素操作算法:图像加法、像素混合、提取图像中的ROI
常用的像素操作算法:图像加法、像素混合、提取图像中的ROI
309 0
常用的像素操作算法:图像加法、像素混合、提取图像中的ROI
|
算法 计算机视觉 Python
Python对图像进行二维Gabor滤波加速
Python对图像进行二维Gabor滤波加速
176 0
Python对图像进行二维Gabor滤波加速

热门文章

最新文章